Как уменьшить коды номеров

Я новичок в проектах 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*/
}

счетчик Arduino Он работает довольно хорошо, но проблема в том, что код слишком длинный. Есть ли метод, который я могу использовать для уменьшения длины кодов?

, 👍0


2 ответа


Лучший ответ:

3

То, что вы здесь пишете, является своего рода двоичным счетчиком: BCD (двоично-десятичный) счетчик, если быть точным. Оказывается, процессор внутри Arduino уже работает в бинарном виде. это его родной язык, поэтому вам не нужно указывать ему, как делать двоичный код. У тебя просто есть чтобы узнать, какие операторы использовать для доступа к отдельным битам.

Мой подход состоял бы в том, чтобы написать функцию, которая может отображать любое число n между 0 и 99. Первым шагом является десятичное разложение: раздели на 10 и возьми частное (первая цифра) и остаток (вторая цифра). Эти цифры будут представлены в двоичном виде в машина. Следующим шагом является доступ к отдельным битам. это два пошаговый процесс:

  1. Сдвигайте биты числа вправо до тех пор, пока нужный бит не станет в крайнем правом. Это достигается с помощью оператора сдвига вправо.

  2. Вычислите побитовое И с числом 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:

  1. Разделите отображаемое число на 10: остальная часть деления самая правая цифра

  2. заменить исходное число на частное от деления

  3. делите еще раз на 10: оставшаяся часть деления — вторая крайняя справа цифра

  4. заменить исходное число на частное от деления

  5. и т. д.

Например, для трех десятичных цифр:

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);
    }
}
,

Спасибо большое, хоть я и мало в этом разбираюсь, @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


1

Я предлагаю вам посмотреть, как создавать циклы, в учебнике по программированию на 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