Число с ведущим нулем

Azot63
Offline
Зарегистрирован: 26.04.2017

Создаю проект на arduino с LCD 16x2 дисплеем. Так проблема в том что на него выводится время с часов реального времени и если число минут или часов является односимвольным например, от 1 до 9 происходит смещение и как следствие артефакты типа 7:599. Нашел, по моему мнению, костыль в виде

if(myRTC.hours<10 && myRTC.hours>0)
{
  lcd.print("0");
  lcd.print(myRTC.hours);
}
else
{
  lcd.print(myRTC.hours);
}

Есть ли какие то более качественные способы вывода информации в виде 01, 02, 03.... 08 и 09?

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

А чем Вас этот не устраивает? Ну, можете printf воспользоваться, если склонны к "шалунизму" :)

Кстати, прикололо условие "&& myRTC.hours>0". А что, если время 0 часов, то лидирующий ноль не нужен?

Azot63
Offline
Зарегистрирован: 26.04.2017

Было на быструю руку скопированно из строки отображения даты по этому и >= не сделал. Спасибо за уточнение.

Вроде должно получится что то подобное, но компилятор возмущается. Либо я косячник либо библиотека не поддерживает

lcd.printf("%02d", myRTC.hours);

 

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

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

Но, вообще-то я пошутил. Нафига тащить в программу такого монстра, как printf ради бедного нуля? Делайте как у Вас сейчас.

По поводу проверки, Ваше исправление на ">=" тоже выглядит странным. Не может Ваш hour быть отрицательным ни при каких условиях, так что эту проверку надо просто убрать.

Клапауций 112
Клапауций 112 аватар
Offline
Зарегистрирован: 01.03.2017

хватит тупить...

lcd.setCursor(0, 0);
if (myRTC.hours < 10) {lcd.print('0');}
lcd.print(myRTC.hours);

 

Azot63
Offline
Зарегистрирован: 26.04.2017

Видел что применяли в своих проектах printf и показалось, что использование if является весьма обширной функцией. Благодарю за ответ. 

Возможно я где то ошибаюсь, но если перевести в словесную форму условие то "часы больше, либо ровны 0" т.е. от 0 и до бесконечности.

afen
Offline
Зарегистрирован: 24.04.2017

Ну может быть так:

String s;

s=Srtring(myRTC.hours)+":"+String(myRTC.min)+"                                "; //затираем остальное пробелами
lcd.setCursor(0, 0);
lcd.print(s);

 

wdrakula
wdrakula аватар
Онлайн
Зарегистрирован: 15.03.2016

хватит тупить , уже все сделали до нас , ищем :    printNumI()

Oleg_Ru
Offline
Зарегистрирован: 17.09.2019
String c2d (byte i){ // convert2digit - добавляю ноль перед числом до 10 и преобразовываю в строку
  String str = (String)i;
  if (i < 10)  str = '0' + str; 
  return str;
}

 

 

b707
Offline
Зарегистрирован: 26.05.2017

Oleg_Ru - ради двух символов заводить (пусть временно) два экземпляра класса String ?

А потом удивляемся. почему ппростенькой игрушке даже Меги не хватает

Oleg_Ru
Offline
Зарегистрирован: 17.09.2019

Это же функция, вызвали, выполнилось и все очистилось. Предложите другое однострочное решение, сам бы использовал. Написал это так как 1.Понятно выглядит 2. Закрыл вопрос с частым форматированием внутри кода. 

пример из скетча:  

serialVFD.printf(c2d(now.day()) + '-' + c2d(now.month()) + '-' + (String)now.year());

 

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

Oleg_Ru пишет:

пример из скетча:  

serialVFD.printf(c2d(now.day()) + '-' + c2d(now.month()) + '-' + (String)now.year());

Не понял, в Вашей библиотеке есть целый printf и Вы ещё к ней какое-то преобразование для добавления нуля колхозите?

Когда будете подвешивать к самолёту атомную бомбу, не забудьте засунуть её в мешок с гвоздями, чтобы увеличить поражающую способность.

Oleg_Ru
Offline
Зарегистрирован: 17.09.2019

Нет там printf, к сожалению. Описка...

serialVFD.print(c2d(now.day()) + '-' + c2d(now.month()) + '-' + (String)now.year());

объект software serial 

Oleg_Ru
Offline
Зарегистрирован: 17.09.2019

про printf навеяли воспоминания про полноценную библиотеку stdio в "С" и тема с форума 

http://arduino.ru/forum/programmirovanie/formatirovannyi-vyvod-v-serial

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

Вот здесь небольшая библиотечка. Просто включаешь и имеешь уже готовый потоковый вывод и полный printf в сериале.

("полный", но без плавающей точки только)

b707
Offline
Зарегистрирован: 26.05.2017

Oleg_Ru пишет:

Это же функция, вызвали, выполнилось и все очистилось. Предложите другое однострочное решение,

А ваше решение "однострочное"? - что-то не заметил :)

void leading_zero(byte c, char* buf) {
   *(buf++)= '0' + c/10;
   *(buf++)='0' + c%10;
   *buf='\0';
}

// Использование:
byte i =3;
char bb[3];
Serial.println(leading_zero(i,bb));

 

Oleg_Ru
Offline
Зарегистрирован: 17.09.2019

Мое решение в 5 строк, ваше тоже. Про однострочное, это о том, что было бы действительно замечательно, если бы оно было. 

Ваше решение возможно менее требовательное к памяти, надо попробовать.

В примере только должно быть так, наверное: 

leading_zero(i,bb);
Serial.println(bb); 

 

 

b707
Offline
Зарегистрирован: 26.05.2017

Oleg_Ru пишет:

leading_zero(i,bb);
Serial.println(bb); 

да, вы правы

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

а чо, принтф использовать запрещено? 

String getTimeStr(RTC &Clock){
   char *buf[8] = alloca(8);
   sprintf(buf, "%02d:%02d", Clock.getHours(), Clock.getMinutes());
  
   return String(buf);
}



 

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

Мне вот всегда жалко полтора кило (или сколько там) ради какого-то сраного нуля. Я его как-нибудь и ручками туда запихаю

Logik
Offline
Зарегистрирован: 05.08.2014

//принтф использовать запрещено?

Запрещено конечно. Она тяжеленная. А уж алокейтить память и не освобождать где алокейтил - очень жестко. Память начнет утекать 99%. Один процент оставлю для суперпеданта-профессионала делающего регулярный кодревю, ему даже можно оставить право на такой стиль. Лучше кода, чем от b707 не родить. разве что упростить для новичка

void leading_zero(byte c, char* buf) {
   buf[0]= '0' +  c/10;
   buf[1]='0' + c%10;
   buf[2]='\0';
}

Можно еще от выделения дробной части избавится типа tmp=c/10;..buf[1]='0' + c-tmp*10; Типа заменяем деление (это подпрограмма у 328р) на умножение (это одна команда), быстрей типа, но то уже для маньяков;)

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

Logik пишет:

А уж алокейтить память и не освобождать где алокейтил - очень жестко. Память начнет утекать 99%. 

дак alloca сама освободится при выходе. 

А String освободица при выходе из области её видимости. Подробностей точных не знаю, но подозреваю, что на уровне выше будет вызван копирующий конструктор, который у String очень грамотно и аккуратно написан, и возвращённый экземпляр тут же почит в бозе. 

Хотя, да, смотря кто как это использует.  Я пока такими граблями в лоп не огребал еще.  

b707
Offline
Зарегистрирован: 26.05.2017

DetSimen пишет:

А String освободица при выходе из области её видимости. Подробностей точных не знаю, но подозреваю, что на уровне выше будет вызван копирующий конструктор, который у String очень грамотно и аккуратно написан, и возвращённый экземпляр тут же почит в бозе.

Ну да, после выхода все очистится. Но в сам момент выполнения функции  будет создано аж два экземпляра String - каждый. если правильно помню - более чем по сотне байт в RAM. И все это ради строчки в 3 символа. А если этих 200 байт нет?

Короче, если можно обойтись без String - лучше обойтись

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

Дак а ТС за память ничо не говорил, ему бы покороче бы. :) 

b707
Offline
Зарегистрирован: 26.05.2017

DetSimen пишет:

Дак а ТС за память ничо не говорил, ему бы покороче бы. :) 

 ТС потерял интерес к вопросу еще в 17м году :)

Нынешнее обсуждение началось с #8

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

аха, вот кто у нас некромант проклятый. :)  

Logik
Offline
Зарегистрирован: 05.08.2014

А чего некромант. Чел верно сделал, чем плодить кучу тем по одному вопросу намного лучше собирать все в одной.

Logik
Offline
Зарегистрирован: 05.08.2014

b707 пишет:

DetSimen пишет:

А String освободица при выходе из области её видимости. Подробностей точных не знаю, но подозреваю, что на уровне выше будет вызван копирующий конструктор, который у String очень грамотно и аккуратно написан, и возвращённый экземпляр тут же почит в бозе.

Ну да, после выхода все очистится. ..

Ох уж эти сказки, ох уж эти сказочники )))

void setup() {
  // put your setup code here, to run once:
 Serial.begin(115200);
}

String getTimeStr(int i){
   char *buf = malloc(8);
   sprintf(buf, "%02d", i);
   return String(buf);
}
void loop() {
  // put your main code here, to run repeatedly:
// Использование:
 Serial.println(getTimeStr(millis()));
 delay(10);
}

Собралось длиней в 2,5 раза и ОЗУ больше.

Скетч использует 4284 байт (13%) памяти устройства. Всего доступно 30720 байт.
Глобальные переменные используют 202 байт (9%) динамической памяти, оставляя 1846 байт для локальных переменных. Максимум: 2048 байт.
 

Вывод дало:

11:40:03.359 -> 09
11:40:03.393 -> 19
11:40:03.393 -> 29
11:40:03.393 -> 39
11:40:03.426 -> 50
11:40:03.426 -> 60
11:40:03.426 -> 70
11:40:03.426 -> 80
......
11:40:04.971 -> 1613
11:40:04.971 -> 1624
11:40:05.005 -> 1634
11:40:05.005 -> 1644
11:40:05.005 -> 1654
11:40:05.039 -> 1665
11:40:05.039 -> 1675
11:40:05.039 -> 1684
11:40:05.039 -> 1694
11:40:05.073 -> 
11:40:05.073 -> 
 
 
И усьооо..., висит. Проверяйте! Ну в смысле свои проекты проверяйте.
 
 

 

 

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

как бы тебе памягше намекнуть, что malloc() от alloca()  весьма существенно отличается? 

Logik
Offline
Зарегистрирован: 05.08.2014

Я заметил, с ним не собирается, потому и malloc(). Хотя конечно если не на куче выделять, а на стеке не все так плохо. Токо я его на ардуине чето не встречал.

 

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

дак #include <alloca.h> нада. 

молотит уже 5 минут, как заводной, не вешаясь

Logik
Offline
Зарегистрирован: 05.08.2014

Да, так молотит.

wdrakula
wdrakula аватар
Онлайн
Зарегистрирован: 15.03.2016

Запусти у себя: ;))))))))))))))))))

#include <alloca.h>

void setup() {
  // put your setup code here, to run once:
 Serial.begin(57600);
}

String getTimeStr(int i){
   char *buf = alloca(8);
   sprintf(buf, "%02d", i);
   return String(buf);
}
void loop() {
  uint16_t _SP = SP;
  char * tc = malloc(1);
  uint16_t _HP = (uint16_t) tc;
  free(tc);

 Serial.print(getTimeStr(millis()));
 Serial.print("   Memfree = ");
 Serial.println( _SP - _HP);
 delay(10);
}

 

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

век живи, век учися. :) 

wdrakula
wdrakula аватар
Онлайн
Зарегистрирован: 15.03.2016

Дед! Это VSCode у тебя или прям студия целиком?

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

Студия.  С темой BC 3.11

Я ж еще ГУИ на Шарпе изредка ваяю. 

sadman41
Offline
Зарегистрирован: 19.10.2016

Logik пишет:

Я заметил, с ним не собирается, потому и malloc(). 

Жесть какая. С alloca() не собирается, поэтому заменил на malloc() не глядя, память при этом не освободил на выходе и сделал вывод, что чужие проэкты с багами. Прямо мегахит от второго по крутости (после Архата) программизда на форуме.

У вас тут точно отупин не разливали по стаканам?

Ворота
Ворота аватар
Offline
Зарегистрирован: 10.01.2016

sadman41 пишет:
С alloca() не собирается, поэтому заменил на malloc() не глядя, память при этом не освободил на выходе и сделал вывод, что чужие проэкты с багами.

А это просто modus vivendi. Персонаж всегда так себя ведёт. Все уже привыкли.

Насчёт.

sadman41 пишет:
второго по крутости (после Архата)
не согласен. Думаю, всё-таки "первого". Архат - второй :) Раньше я думал, что Архат круче и был уверен, что его "дефайн" никто не перебьёт. Но тут человек скомпилировать не сумел! До такого уровня профессионализма Архат ещё не доходил. Хотя, вроде, пример правильного использования (и компиляции) alloca прибит гвоздями в одной из тем, которые архаложик презрительно называют "пересказом общеизвестных истин из школьных учебников". Видимо, всё же, не совсем общеизвестных, раз даже Великие испытывают трудности.

xDriver
xDriver аватар
Offline
Зарегистрирован: 14.08.2015

тока прочитал, ржу не могу, форум юмористов мля :)))))