Помогите разобрать с календарём в часах на 1302

ArturKu
ArturKu аватар
Offline
Зарегистрирован: 06.09.2020

Подскажите, что я делаю не так с днями недели!
Пока не прибыли часики на 3231, экспериментирую с 1302 (довольно точными).
Никак не могу понять как правильно выводить день недели на 2008рус.
С русским разобрался, а вот с выводом - нет.
Ниже привожу полный исходник с будущими задумками.

Так вот, сперва у меня был исходник с 7-ю днями недели. Исправно работал до воскресения. В воскресенье показал пустую строку. Вывел ниже названия дня недели его числовое значение (строки 69-70)..
Получается, что часы считают от 1 до 7, а "char dayofweek" от 0 до 6.

Пока сделал воскресение и нулевым и 7 днём недели, хотя нулевой можно заменить и пробелом.
Получается, что у меня неделя о восьми днях! Но это как то криво, хотя отображается правильно.
Почитал справочники по ардуино, но так и не понял, как массив сделать не от 0 до 6, а от 1 до 7.

 

#include <virtuabotixRTC.h>
virtuabotixRTC myRTC(5, 6, 7); //CLK, DAT, RST

#include <Wire.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27,20,4);
char dayofweek[8] [12] = {
  "Boc\272pece\275\270e",
  "\250o\275e\343e\273\304\275\270\272",
  "B\277op\275\270\272    ",
  "Cpe\343a       ",
  "\253e\277\263ep\264     ",
  "\250\307\277\275\270\345a     ",
  "Cy\262\262o\277a    ",
  "Boc\272pece\275\270e",
  };

void setup() {
  Wire.begin();
  lcd.begin(20,4);
  // myRTC.setDS1302Time(00, 11, 01, 01, 19, 10, 2020);  //сек, мин, час, д.нед, д, м, г (~ за 8-10 сек)
  lcd.init();   // Сброс экрана
  lcd.backlight();   // Включение подсветки
  lcd.clear();    // Очистка экрана
}

void loop() {
myRTC.updateTime();

lcd.setCursor(0, 0);
if (myRTC.hours < 10) lcd.print("0");
lcd.print(myRTC.hours);
lcd.print(":");
if (myRTC.minutes < 10) lcd.print("0");
lcd.print(myRTC.minutes);
lcd.print(":");
if (myRTC.seconds < 10) lcd.print("0");
lcd.print(myRTC.seconds);

lcd.setCursor(0, 1);
if (myRTC.dayofmonth < 10) lcd.print("0");
lcd.print(myRTC.dayofmonth);
lcd.print(".");
if (myRTC.month < 10) lcd.print("0");
lcd.print(myRTC.month);
lcd.print(".");
lcd.print(myRTC.year-2000);

lcd.setCursor(0, 2);
lcd.print(dayofweek[myRTC.dayofweek]);
// lcd.print("     ");

lcd.setCursor(13, 0);
lcd.print("23.3");
lcd.print(" ");
lcd.print('\337');
lcd.print("C");

lcd.setCursor(13, 1);
lcd.print("1400 CO");

lcd.setCursor(13, 2);
lcd.print(" 760 mm");

lcd.setCursor(13, 3);
lcd.print("  50 %");

 lcd.setCursor (0, 3);
 lcd.print(myRTC.dayofweek);
}

 

ArturKu
ArturKu аватар
Offline
Зарегистрирован: 06.09.2020

Подозреваю, что тут виновата сама библиотека.
Какую использовать с 3231?
Я их встречал уже несколько разных, влоть до какой то универсальной для 1302, 1307 и 3231...

Такое чувство, что их переделывают под себя чуть ли не в каждом проекте?

Хочу сократить код до минимума, что бы запихать всё в атмега8 (без кварца или с самым плохим часовым, что есть у меня), но, подозреваю, что это уже надо на что-то более низкоуровневое переходить?

ArturKu
ArturKu аватар
Offline
Зарегистрирован: 06.09.2020

Всё, понял! Я пропустил самое главное:
"при создании массива типа char, необходим дополнительный элемент массива для нулевого символа."

Пока всё подробно не расписал вам, но мог врубиться. 

Потом пришла идея.

Потом в 10-й раз полез в справочник, но не на Андроиде, а здесь... 
Видать на андроиде было мелковато и до мозга не дошло. ;-)

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

Причем здесь библитека? Посмотрите в даташит. Там дни недели от 1 до 7. Если надо с массивом использовать, то кто мешает сделать так lcd.print(dayofweek[myRTC.dayofweek-1]); ?

ArturKu
ArturKu аватар
Offline
Зарегистрирован: 06.09.2020

asam

Спасибо! Чего-то такое простое решение мне в голову и не пришло...

ArturKu
ArturKu аватар
Offline
Зарегистрирован: 06.09.2020

Сегодня пришел с работы и был "приятно" удивлён.

У дней недели поехала крыша!

Ещё вчера всё работало как надо, а сегодня пришел с работы и такая картинка (лишнее удалил).

Сброс, перепрошивка, замена батарейки не помогают...
Что, и 1302 отправилась в страну вечного покоя или это ардуинка окочурилась?

Почему грешу на ардуинку - часы то идут и с батарейкой и с питанием и 5 и 3.3В
Может загрузчик крякнулся?

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

Последнюю версию скетча целиком выкладывайте. Посмотрим

ArturKu
ArturKu аватар
Offline
Зарегистрирован: 06.09.2020

Вчера всё работало, сегодня пришел - этот глюк.

Сейчас попробовал закомментировать строку 51 и изменил 70-ю строку на:

   lcd.print(myRTC.dayofweek-1);

Всё выводится правильно...

Я в полной растерянности...

Вот полная версия:

 

// 4.776 байта
#include <virtuabotixRTC.h>
virtuabotixRTC myRTC(5, 6, 7); //CLK, DAT, RST

#include <Wire.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27,20,4);
char dayofweek[7] [12] = {
  "\250o\275e\343e\273\304\275\270\272",
  "B\277op\275\270\272    ",
  "Cpe\343a       ",
  "\253e\277\263ep\264     ",
  "\250\307\277\275\270\345a     ",
  "Cy\262\262o\277a    ",
  "Boc\272pece\275\270e",
  };

void setup() {
  Wire.begin();
  lcd.begin(20,4);
  // myRTC.setDS1302Time(00, 16, 21, 03, 28, 10, 2020);  //сек, мин, час, д.нед, д, м, г (~ за 8-10 сек)
  lcd.init();   // Сброс экрана
  lcd.backlight();   // Включение подсветки
  lcd.clear();    // Очистка экрана
}

void loop() {
myRTC.updateTime();

lcd.setCursor(0, 0);
if (myRTC.hours < 10) lcd.print("0");
lcd.print(myRTC.hours);
lcd.print(":");
if (myRTC.minutes < 10) lcd.print("0");
lcd.print(myRTC.minutes);
lcd.print(":");
if (myRTC.seconds < 10) lcd.print("0");
lcd.print(myRTC.seconds);

lcd.setCursor(0, 1);
if (myRTC.dayofmonth < 10) lcd.print("0");
lcd.print(myRTC.dayofmonth);
lcd.print(".");
if (myRTC.month < 10) lcd.print("0");
lcd.print(myRTC.month);
lcd.print(".");
lcd.print(myRTC.year-2000);

lcd.setCursor(0, 2);
// lcd.print(dayofweek[myRTC.dayofweek-1]);
// lcd.print("     ");

lcd.setCursor(13, 0);
lcd.print("23.3");
lcd.print(" ");
lcd.print('\337');
lcd.print("C");

lcd.setCursor(13, 1);
lcd.print("1400 CO");

lcd.setCursor(13, 2);
lcd.print(" 760 mm");

lcd.setCursor(13, 3);
lcd.print("  50 %");

 lcd.setCursor (0, 3);
 lcd.print(myRTC.dayofweek-1);
}

 

ArturKu
ArturKu аватар
Offline
Зарегистрирован: 06.09.2020

Раскомментирую 51-ю - глюк на месте.

Меняю 51-ю на
lcd.print(dayofweek[myRTC.dayofweek]);

Глюк тоже вылазит!

ArturKu
ArturKu аватар
Offline
Зарегистрирован: 06.09.2020

Блин! Это я - тормоз!!!

Оказалось, что в "Среде      " у меня один лишний пробел...
Получается, что символ конца строки затёрся...
 

Green
Offline
Зарегистрирован: 01.10.2015

Как вообще такими иероглифами можно писать! Неужто нельзя по нормальному, а затем преобразовать для LCD. Ну порнография же!

ArturKu
ArturKu аватар
Offline
Зарегистрирован: 06.09.2020

Green, согласен.
Однако мне принципиален размер готового кода - планирую атмегу8 приспособить для этого дела.
Скорее всего придётся часть просто переписывать на асм (надо вспоминать - давно это было, очень давно, ещё на 8086-м) или избавляться от библиотек каким-то другим способом...

maks321
Offline
Зарегистрирован: 28.10.2020

предпологаю что ардуинам блокировали компилятор,и теперь мы имеем кучу траблов с переходом от понятного и ошибкоприемлемого ггс++ к точтому и жесткому с-

наслаждайтесь и переползайте на более платные компиляторы

maks321
Offline
Зарегистрирован: 28.10.2020

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

char GetTime(){
RTC_now();
char s[5] = {"  :  "};
if (hours < 10) s[1] = ('0'+hours); else {
   s[0] = ('0'+(hours / 10)); s[1] = '0'+(hours % 10);}
if (minute<10) {s[3] = '0'; s[4] = '0'+minute; }else {
  s[3] = '0'+(minute /10); s[4] = '0'+(minute % 10);}
return s;
}
 
ArturKu
ArturKu аватар
Offline
Зарегистрирован: 06.09.2020

maks321, я только начинающий...

Подключил 18В20. Стал выводить температуру... Но мне надо до десятых, а сотые не интересны.

Например Т=24,19.

Если пишу так:
lcd.print((round(ds.getTempC()*10))/10); // выводится только 24

Если так:
lcd.print((round(ds.getTempC()*10))/10.0);  // Выводит 24,10

А как вывести 24,1?

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

ArturKu пишет:

А как вывести 24,1?

видимо, использовать dtostrf()

Green
Offline
Зарегистрирован: 01.10.2015

ArturKu пишет:

Подключил 18В20. Стал выводить температуру... Но мне надо до десятых, а сотые не интересны.

Например Т=24,19.


Ну если вам принципиален размер, зачем тогда плавучку используете. Конечно, никаких мег8 не хватит. У меня на 2313 всего и асм здесь не нужен.

ArturKu
ArturKu аватар
Offline
Зарегистрирован: 06.09.2020

Green, уже когда 18В20 подключил, понял, что мои хотелки в атмега8 точно не влезут...
Ну и ладно - оставлю их для вольт-амперметра БП. Я почему ардуинкой на старости лет и занялся, что "завалялись в хозяйстве" "цельнотянутые" пара штук... 

Всё равно по приколу заказал атмега128а и атмега328...

П.С. А что такое "плавучка"?

Green
Offline
Зарегистрирован: 01.10.2015

float - тип данных.

ArturKu
ArturKu аватар
Offline
Зарегистрирован: 06.09.2020

А такой вопросик:

Если не округлять, а просто вывести первые 4 символа от температуры?

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

maks321 пишет:

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

char GetTime(){
RTC_now();
char s[5] = {"  :  "};
if (hours < 10) s[1] = ('0'+hours); else {
   s[0] = ('0'+(hours / 10)); s[1] = '0'+(hours % 10);}
if (minute<10) {s[3] = '0'; s[4] = '0'+minute; }else {
  s[3] = '0'+(minute /10); s[4] = '0'+(minute % 10);}
return s;
}

 

Макс, во-первых привыкайте вставлять код как положено.

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

apg_777
Offline
Зарегистрирован: 22.09.2020

maks321 пишет:

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

char GetTime(){
RTC_now();
char s[5] = {"  :  "};
if (hours < 10) s[1] = ('0'+hours); else {
   s[0] = ('0'+(hours / 10)); s[1] = '0'+(hours % 10);}
if (minute<10) {s[3] = '0'; s[4] = '0'+minute; }else {
  s[3] = '0'+(minute /10); s[4] = '0'+(minute % 10);}
return s;
}
 
А почему не 
sprintf(s, "%2d:%02d", hours, minute);

?

 

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

apg_777 - да много как можно написать. Из того же кода maks321 можно все условия выкинуть - он станет втрое короче...

Но товарищ, похоже, не сам учиться пришел, а других поучать :)

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

ArturKu пишет:

 уже когда 18В20 подключил, понял, что мои хотелки в атмега8 точно не влезут...
 

Что за хотелки? При правильном подходе в Атмегу8 можно много чего запихнуть.

ArturKu
ArturKu аватар
Offline
Зарегистрирован: 06.09.2020

apg_777 пишет:

А почему не
sprintf(s, "%2d:%02d", hours, minute);
?

А что сие означает?

На сколько мне не изменяет память, то даже в паскале 5.0 было что-то с округлением (функция) и форматированным выводом?

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

ArturKu пишет:

apg_777 пишет:

sprintf(s, "%2d:%02d", hours, minute);

А что сие означает?

а вы не пробовали поискать эту функцию в гугле?

Green
Offline
Зарегистрирован: 01.10.2015

Нет, гугль это последнее дело.)

apg_777
Offline
Зарегистрирован: 22.09.2020

ArturKu пишет:

А что сие означает?

На сколько мне не изменяет память, то даже в паскале 5.0 было что-то с округлением (функция) и форматированным выводом?

Сдаётся мне что часы и минуты округлять не надо.
А сия конструкция просто запишет в строковую переменную s пять символов — два первых символа переменная hours без лидирующего нуля, два последних minute с лидирующим нулём и эти пары разделены двоеточием. При объявлении переменной s надо зарезервировать место под байт окончания строки char s[6]; иначе можно заполучить непредсказуемые глюки.