Нули в разрядах для семисегментного индикатора

sharik_28.05
Offline
Зарегистрирован: 05.02.2020

Здравствуйте.

Нужно на 4 - х разрядный индикатор выводить числа, только если число 123, то должно быть 0123, число 25 - значит 0025, то есть нули должны быть.

 

  byte digit[4] = {0, 0, 0, 0};
  uint16_t num = 1;

  digit[3] = num % 10 % 10;
  digit[2] = num / 10 % 10;
  digit[1] = num / 100 % 10;
  digit[0] = num / 1000 % 10;

  Serial.println(digit[0]);
  Serial.println(digit[1]);
  Serial.println(digit[2]);
  Serial.println(digit[3]);

Так будет правильно? 

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

Правильно будет sprintf() c форматом "%04d"

Дим-мычъ
Offline
Зарегистрирован: 20.03.2021

sharik_28.05 пишет:

  digit[3] = num % 10 % 10;

Так будет правильно? 

 А зачем два раза ?

BOOM
BOOM аватар
Offline
Зарегистрирован: 14.11.2018

Дим-мычъ пишет:

sharik_28.05 пишет:

  digit[3] = num % 10 % 10;

Так будет правильно? 

 А зачем два раза ?

Для непонятливых видимо )))

BOOM
BOOM аватар
Offline
Зарегистрирован: 14.11.2018

DetSimen пишет:

Правильно будет sprintf() c форматом "%04d"

Деда, залогинься. Внуки балутся. Как sprintf для семисегментников?))

BOOM
BOOM аватар
Offline
Зарегистрирован: 14.11.2018
for (h = 0; h < 4; h++) {
  digit[h] = num % 10;
  num = num / 10;
}

 

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

BOOM пишет:

DetSimen пишет:

Правильно будет sprintf() c форматом "%04d"

Деда, залогинься. Внуки балутся. Как sprintf для семисегментников?))

а шо не так?  сначала спринтом в буфер - оттуда в семисегментник.  Я, правда, через itoa() делал, так тоже можно. 

BOOM
BOOM аватар
Offline
Зарегистрирован: 14.11.2018

Я тоже через itoa()

v258
v258 аватар
Offline
Зарегистрирован: 25.05.2020

Вроде любая библиотека для семисегментника позволяет выводить как с нулями, так и без них

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

v258 пишет:

Вроде любая библиотека для семисегментника позволяет выводить как с нулями, так и без них

у Деда своя, сейчас он нам скажет

sharik_28.05
Offline
Зарегистрирован: 05.02.2020

А зачем два раза ?

Опечатка. Спасибо.

  byte digit[4] = {0, 0, 0, 0};
  uint16_t num = 1234;

  ltoa (num, digit, DEC);
  Serial.println(digit[0]);
  Serial.println(digit[1]);
  Serial.println(digit[2]);
  Serial.println(digit[3]);

Почему получаю 49 50 51 52?

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Ну sprintf может оказаться очень тяжело для МК. У AVR sprintf не работает с числами с плавающей точкой и, возможно, именно поэтому не слишком объемный. А для stm32, например, он добавляет к коду 12 кбайт.

В общем, предложенный в исходном сообщении вариант не так уж плох, разумеется, если убрать из него лишние операции взятия по модулю. Недостаток - несколько обращений к функции печати.

Мне кажется, лучше сделать массив на 5 char, заполнить его символами, т.е: digit[3] = (num %  10) + '0'; и распечатать как строку одним вызовом функции печати.

sharik_28.05
Offline
Зарегистрирован: 05.02.2020

Правильно будет sprintf() c форматом "%04d"

Что значит "%04d" ?

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

sharik_28.05 пишет:

А зачем два раза ?

Опечатка. Спасибо.

  byte digit[4] = {0, 0, 0, 0};
  uint16_t num = 1234;

  ltoa (num, digit, DEC);
  Serial.println(digit[0]);
  Serial.println(digit[1]);
  Serial.println(digit[2]);
  Serial.println(digit[3]);

Почему получаю 49 50 51 52?

Потому что преобразуете в символы, а печатаете как числа. (почитайте про разницу между символами и числами)

sharik_28.05
Offline
Зарегистрирован: 05.02.2020

andriano пишет:

Ну sprintf может оказаться очень тяжело для МК. У AVR sprintf не работает с числами с плавающей точкой и, возможно, именно поэтому не слишком объемный. А для stm32, например, он добавляет к коду 12 кбайт.

В общем, предложенный в исходном сообщении вариант не так уж плох, разумеется, если убрать из него лишние операции взятия по модулю. Недостаток - несколько обращений к функции печати.

Мне кажется, лучше сделать массив на 5 char, заполнить его символами, т.е: digit[3] = (num %  10) + '0'; и распечатать как строку одним вызовом функции печати.

Я не буду печатать, буду выводить на семисегментный индикатор

  for (uint8_t h = 0; h < 4; h++) {
    digit[h] = num % 10;
    num = num / 10;
  }

Спасибо.

 

sharik_28.05
Offline
Зарегистрирован: 05.02.2020

Потому что преобразуете в символы, а печатаете как числа. (почитайте про разницу между символами и числами)

Что - то не тот у меня...

 ltoa (num, digit, DEC);

  Serial.println(atoi(digit[0]));
  Serial.println(atoi(digit[1]));
  Serial.println(atoi(digit[2]));
  Serial.println(atoi(digit[3]));

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

DetSimen пишет:

а шо не так?  сначала спринтом в буфер - оттуда в семисегментник. 

А я так тупо обычный printf к семисегментнику напрямую привязывал. Очень удобно, если ресурсов хватает на prinf.