Как уменьшить коды номеров
Я новичок в проектах Arduino, я сделал цифровой счетчик, который считает от 00 до 99. Вот мой код ниже
void setup()
{
pinMode(0,OUTPUT);
pinMode(1,OUTPUT);
pinMode(2,OUTPUT);
pinMode(3,OUTPUT);
pinMode(4,OUTPUT);
pinMode(5,OUTPUT);
pinMode(6,OUTPUT);
pinMode(7,OUTPUT);
pinMode(8,OUTPUT);
pinMode(9,OUTPUT);
}
void loop()
{
/* segment starts from 00*/
digitalWrite(0,LOW);
digitalWrite(1,LOW);
digitalWrite(3,LOW);
delay(500);
digitalWrite(0,HIGH);
delay(500);
digitalWrite(0,LOW);
digitalWrite(1,HIGH);
delay(500);
digitalWrite(0,HIGH);
delay(500);
digitalWrite(2,HIGH);
digitalWrite(0,LOW);
digitalWrite(1,LOW);
delay(500);
digitalWrite(0,HIGH);
delay(500);
digitalWrite(1,HIGH);
digitalWrite(0,LOW);
delay(500);
digitalWrite(0,HIGH);
delay(500);
digitalWrite(3,HIGH);
digitalWrite(0,LOW);
digitalWrite(1,LOW);
digitalWrite(2,LOW);
delay(500);
digitalWrite(0,HIGH);
delay(500);
digitalWrite(4,HIGH);
digitalWrite(0,LOW);
digitalWrite(3,LOW);
/* segment will now be 10, the 0 will continue counting up to 1*/
digitalWrite(0,LOW);
digitalWrite(1,LOW);
digitalWrite(3,LOW);
delay(500);
digitalWrite(0,HIGH);
delay(500);
digitalWrite(0,LOW);
digitalWrite(1,HIGH);
delay(500);
digitalWrite(0,HIGH);
delay(500);
digitalWrite(2,HIGH);
digitalWrite(0,LOW);
digitalWrite(1,LOW);
delay(500);
digitalWrite(0,HIGH);
delay(500);
digitalWrite(1,HIGH);
digitalWrite(0,LOW);
delay(500);
digitalWrite(0,HIGH);
delay(500);
digitalWrite(3,HIGH);
digitalWrite(0,LOW);
digitalWrite(1,LOW);
digitalWrite(2,LOW);
delay(500);
digitalWrite(0,HIGH);
delay(500);
digitalWrite(5,HIGH);
digitalWrite(4,LOW);
/* the segment will now be 20 */
digitalWrite(0,LOW);
digitalWrite(1,LOW);
digitalWrite(3,LOW);
delay(500);
digitalWrite(0,HIGH);
delay(500);
digitalWrite(0,LOW);
digitalWrite(1,HIGH);
delay(500);
digitalWrite(0,HIGH);
delay(500);
digitalWrite(2,HIGH);
digitalWrite(0,LOW);
digitalWrite(1,LOW);
delay(500);
digitalWrite(0,HIGH);
delay(500);
digitalWrite(1,HIGH);
digitalWrite(0,LOW);
delay(500);
digitalWrite(0,HIGH);
delay(500);
digitalWrite(3,HIGH);
digitalWrite(0,LOW);
digitalWrite(1,LOW);
digitalWrite(2,LOW);
delay(500);
digitalWrite(0,HIGH);
delay(500);
digitalWrite(4,HIGH);
digitalWrite(5,HIGH);
digitalWrite(0,LOW);
digitalWrite(1,LOW);
digitalWrite(3,LOW);
delay(500);
digitalWrite(0,HIGH);
delay(500);
digitalWrite(0,LOW);
digitalWrite(1,HIGH);
delay(500);
digitalWrite(0,HIGH);
delay(500);
digitalWrite(2,HIGH);
digitalWrite(0,LOW);
digitalWrite(1,LOW);
delay(500);
digitalWrite(0,HIGH);
delay(500);
digitalWrite(1,HIGH);
digitalWrite(0,LOW);
delay(500);
digitalWrite(0,HIGH);
delay(500);
digitalWrite(3,HIGH);
digitalWrite(0,LOW);
digitalWrite(1,LOW);
digitalWrite(2,LOW);
delay(500);
digitalWrite(0,HIGH);
delay(500);
digitalWrite(4,LOW);
digitalWrite(6,HIGH);
digitalWrite(5,LOW);
digitalWrite(0,LOW);
digitalWrite(1,LOW);
digitalWrite(3,LOW);
delay(500);
digitalWrite(0,HIGH);
delay(500);
digitalWrite(0,LOW);
digitalWrite(1,HIGH);
delay(500);
digitalWrite(0,HIGH);
delay(500);
digitalWrite(2,HIGH);
digitalWrite(0,LOW);
digitalWrite(1,LOW);
delay(500);
digitalWrite(0,HIGH);
delay(500);
digitalWrite(1,HIGH);
digitalWrite(0,LOW);
delay(500);
digitalWrite(0,HIGH);
delay(500);
digitalWrite(3,HIGH);
digitalWrite(0,LOW);
digitalWrite(1,LOW);
digitalWrite(2,LOW);
delay(500);
digitalWrite(0,HIGH);
delay(500);
digitalWrite(4,HIGH);
digitalWrite(6,HIGH);
digitalWrite(0,LOW);
digitalWrite(1,LOW);
digitalWrite(3,LOW);
delay(500);
digitalWrite(0,HIGH);
delay(500);
digitalWrite(0,LOW);
digitalWrite(1,HIGH);
delay(500);
digitalWrite(0,HIGH);
delay(500);
digitalWrite(2,HIGH);
digitalWrite(0,LOW);
digitalWrite(1,LOW);
delay(500);
digitalWrite(0,HIGH);
delay(500);
digitalWrite(1,HIGH);
digitalWrite(0,LOW);
delay(500);
digitalWrite(0,HIGH);
delay(500);
digitalWrite(3,HIGH);
digitalWrite(0,LOW);
digitalWrite(1,LOW);
digitalWrite(2,LOW);
delay(500);
digitalWrite(0,HIGH);
delay(500);
digitalWrite(5,HIGH);
digitalWrite(4,LOW);
digitalWrite(0,LOW);
digitalWrite(1,LOW);
digitalWrite(3,LOW);
delay(500);
digitalWrite(0,HIGH);
delay(500);
digitalWrite(0,LOW);
digitalWrite(1,HIGH);
delay(500);
digitalWrite(0,HIGH);
delay(500);
digitalWrite(2,HIGH);
digitalWrite(0,LOW);
digitalWrite(1,LOW);
delay(500);
digitalWrite(0,HIGH);
delay(500);
digitalWrite(1,HIGH);
digitalWrite(0,LOW);
delay(500);
digitalWrite(0,HIGH);
delay(500);
digitalWrite(3,HIGH);
digitalWrite(0,LOW);
digitalWrite(1,LOW);
digitalWrite(2,LOW);
delay(500);
digitalWrite(0,HIGH);
delay(500);
digitalWrite(4,HIGH);
digitalWrite(0,LOW);
digitalWrite(1,LOW);
digitalWrite(3,LOW);
delay(500);
digitalWrite(0,HIGH);
delay(500);
digitalWrite(0,LOW);
digitalWrite(1,HIGH);
delay(500);
digitalWrite(0,HIGH);
delay(500);
digitalWrite(2,HIGH);
digitalWrite(0,LOW);
digitalWrite(1,LOW);
delay(500);
digitalWrite(0,HIGH);
delay(500);
digitalWrite(1,HIGH);
digitalWrite(0,LOW);
delay(500);
digitalWrite(0,HIGH);
delay(500);
digitalWrite(3,HIGH);
digitalWrite(0,LOW);
digitalWrite(1,LOW);
digitalWrite(2,LOW);
delay(500);
digitalWrite(0,HIGH);
delay(500);
digitalWrite(4,LOW);
digitalWrite(7,HIGH);
digitalWrite(6,LOW);
digitalWrite(5,LOW);
digitalWrite(0,LOW);
digitalWrite(1,LOW);
digitalWrite(3,LOW);
delay(500);
digitalWrite(0,HIGH);
delay(500);
digitalWrite(0,LOW);
digitalWrite(1,HIGH);
delay(500);
digitalWrite(0,HIGH);
delay(500);
digitalWrite(2,HIGH);
digitalWrite(0,LOW);
digitalWrite(1,LOW);
delay(500);
digitalWrite(0,HIGH);
delay(500);
digitalWrite(1,HIGH);
digitalWrite(0,LOW);
delay(500);
digitalWrite(0,HIGH);
delay(500);
digitalWrite(3,HIGH);
digitalWrite(0,LOW);
digitalWrite(1,LOW);
digitalWrite(2,LOW);
delay(500);
digitalWrite(0,HIGH);
delay(500);
digitalWrite(4,HIGH);
/* the segment will now be 9 0 */
digitalWrite(0,LOW);
digitalWrite(1,LOW);
digitalWrite(3,LOW);
delay(500);
digitalWrite(0,HIGH);
delay(500);
digitalWrite(0,LOW);
digitalWrite(1,HIGH);
delay(500);
digitalWrite(0,HIGH);
delay(500);
digitalWrite(2,HIGH);
digitalWrite(0,LOW);
digitalWrite(1,LOW);
delay(500);
digitalWrite(0,HIGH);
delay(500);
digitalWrite(1,HIGH);
digitalWrite(0,LOW);
delay(500);
digitalWrite(0,HIGH);
delay(500);
digitalWrite(3,HIGH);
digitalWrite(0,LOW);
digitalWrite(1,LOW);
digitalWrite(2,LOW);
delay(500);
digitalWrite(0,HIGH);
delay(500);
digitalWrite(4,LOW);
digitalWrite(7,LOW);
/* when it gets here the segment resets to 00*/
}
Он работает довольно хорошо, но проблема в том, что код слишком длинный. Есть ли метод, который я могу использовать для уменьшения длины кодов?
@Joseph Afodu, 👍0
2 ответа
Лучший ответ:
То, что вы здесь пишете, является своего рода двоичным счетчиком: BCD (двоично-десятичный) счетчик, если быть точным. Оказывается, процессор внутри Arduino уже работает в бинарном виде. это его родной язык, поэтому вам не нужно указывать ему, как делать двоичный код. У тебя просто есть чтобы узнать, какие операторы использовать для доступа к отдельным битам.
Мой подход состоял бы в том, чтобы написать функцию, которая может отображать любое число n
между 0 и 99. Первым шагом является десятичное разложение:
раздели на 10 и возьми частное (первая цифра) и остаток
(вторая цифра). Эти цифры будут представлены в двоичном виде в
машина. Следующим шагом является доступ к отдельным битам. это два
пошаговый процесс:
Сдвигайте биты числа вправо до тех пор, пока нужный бит не станет в крайнем правом. Это достигается с помощью оператора сдвига вправо.
Вычислите побитовое И с числом 1 (0000000000000001 в двоичный). Это очистит все биты, кроме того, который вы хотите, и результат либо 0 (то же, что и
LOW
), либо 1 (т.е.HIGH
).
Например, если вы хотите получить бит 1 числа 7, вы делаете
0000000000000111 = 7 initial number
0000000000000011 = 3 shifted one potion to the right
0000000000000001 = 1 bitwise AND-ed with 1
В коде:
void display(int n)
{
int digit0 = n % 10;
int digit1 = n / 10;
digitalWrite(0, (digit0 >> 0) & 1);
digitalWrite(1, (digit0 >> 1) & 1);
digitalWrite(2, (digit0 >> 2) & 1);
digitalWrite(3, (digit0 >> 3) & 1);
digitalWrite(4, (digit1 >> 0) & 1);
digitalWrite(5, (digit1 >> 1) & 1);
digitalWrite(6, (digit1 >> 2) & 1);
digitalWrite(7, (digit1 >> 3) & 1);
}
ОБНОВЛЕНИЕ: если вам нужно больше двух цифр, вы должны последовательно разделить на 10:
Разделите отображаемое число на 10: остальная часть деления самая правая цифра
заменить исходное число на частное от деления
делите еще раз на 10: оставшаяся часть деления — вторая крайняя справа цифра
заменить исходное число на частное от деления
и т. д.
Например, для трех десятичных цифр:
void display(int n)
{
int digits[3]; // digits[0] — самая правая цифра
digits[0] = n % 10;
n /= 10;
digits[1] = n % 10;
n /= 10;
digits[2] = n % 10;
// Теперь убедитесь, что n < 10 (иначе мы пропускаем цифры),
// затем отображаем цифры[0], цифры[1] и цифры[2].
}
Теперь основная программа должна перебирать только числа от 0 до 99, а отображать каждый по очереди:
void loop()
{
for (int n = 0; n < 100; n++) {
display(n);
delay(500);
}
}
Я предлагаю вам посмотреть, как создавать циклы, в учебнике по программированию на C или C++. Например, вы можете заменить:
void setup()
{
pinMode(0,OUTPUT);
pinMode(1,OUTPUT);
pinMode(2,OUTPUT);
pinMode(3,OUTPUT);
pinMode(4,OUTPUT);
pinMode(5,OUTPUT);
pinMode(6,OUTPUT);
pinMode(7,OUTPUT);
pinMode(8,OUTPUT);
pinMode(9,OUTPUT);
}
с:
void setup()
{
for (int i = 0; i <= 9; i++)
pinMode(i,OUTPUT);
}
Кроме того, что сказал Эдгар Боне. :), @Nick Gammon
- avrdude ser_open() can't set com-state
- Float печатается только 2 десятичных знака после запятой
- ошибка: espcomm_upload_mem failed при загрузке скетча
- Печать массива байтов на экране последовательного монитора Arduino IDE
- Разные и самые быстрые способы вычисления синусов и косинусов в Arduino
- Arduino IDE Отказано В Разрешении На Загрузку, Ubuntu
- Нет заголовочных файлов (.h) в Documents\Arduino\libraries\arduino_144469 с демонстрационным кодом
- Связь Arduino master/slave с использованием RS485
Спасибо большое, хоть я и мало в этом разбираюсь, @Joseph Afodu
Большое спасибо за помощь. Но как вы получили digit0=n%10 digit1=n/10, и если я хочу добавить к нему еще один bcd, какие вычисления мне нужно сделать, чтобы получить его, я пытался digit2=n /100, но это не сработало., @Joseph Afodu
@JosephAfodu: Re «_как вы получили digit0=n%10 [...]_»: я изучил десятичный счет в начальной школе, а затем я узнал значение операторов
/
и%
в C++. По поводу «_и если я хочу добавить еще один bcd_»: см. ответ с поправками., @Edgar Bonet@JosephAfodu, большая часть вашего замешательства может заключаться в том, что вы не распознаете
%
как нечто, с чем вы [вероятно, уже знакомы] (https://www.arduino.cc/reference/en/language/structure/arithmetic-operators). /remainder/), что не является общепринятым в математике, но достаточно обычным в программировании. Вы также должны быть знакомы с побитовыми [операторами] (https://www.arduino.cc/reference/en/)., @timemageЕсть ли способ сделать это с 3 bcd без отображения букв в среднем, я пытался, но когда последний считает 1, средний будет отображать буквы., @Joseph Afodu
@JosephAfodu: У вас, должно быть, ошибка в коде. Если вы вычисляете
digits[1]
какn % 10
, он не должен отображать буквы, если только проводка неверна., @Edgar BonetЕсли я сделаю это таким образом, цифра [0] и цифра [1] будут показывать одно и то же число за раз, @Joseph Afodu
Если мне нужно число 999, я использую: digit0=n%10; цифра1=n/10; цифра2=n/100; . Также я изменил: for (int n=0; n<100; n++) на for (int n=0; n<1000; n++), потому что мне нужны числа до 999. Когда он доходит до 99, а третий bcd показывает 1 , вместо второго, чтобы показать 0, он будет показывать A до тех пор, пока он не досчитает до f, прежде чем он перезапустится с 1, и, возможно, к тому времени 3-й bcd уже покажет 2. Что не позволит числам добраться до 999, когда он дойдет до 930 это перезапустится с 000. Мне просто нужно избавиться от букв, отображаемых на втором bcd., @Joseph Afodu
@JosephAfodu: посмотрите мое редактирование, сделанное два дня назад: код сразу после «Например, для трех десятичных цифр»., @Edgar Bonet