оптимизация кода
- Войдите на сайт для отправки комментариев
Сб, 10/08/2019 - 09:28
Всем привет, я недавно начал осваивать програмирование, имею арудино нано на ат158, и делаю часы/альтиметр/барометр/температуру в авто, столкунлся с тем что мне не хватает памяти для всего, либо я могу вывести на экран позанания датчика bme280, а время останется не задействованным, либо время без показания датчика, при этом у меня остается не реализованным управление настройкой времени через 2 кнопки.
вопрос такой, ткните меня в ошибки и подскажите как можно уменьшить вес библиотек не испортив ничего
#include <Wire.h>
#include <SPI.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 20, 4);
#include <iarduino_RTC.h> //библиотека часов
iarduino_RTC time (RTC_DS3231); // объявляем переменную time для работы с библиотекой, указывая название модуля RTC_DS3231
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
#define SEALEVELPRESSURE_HPA (1013.25)
Adafruit_BME280 bme;
int last_time; //потому что значение инт от -32к до +32к
void setup() {
lcd.init();
lcd.backlight();
lcd.clear();
bool status;
status = bme.begin();
}
void loop() {
lcd.setCursor(0, 0);
lcd.print("JEEP GRAND CHEROKEE");
lcd.setCursor(0, 1);
//if (millis() % 1000 == 0) { // Если прошла 1 секунда
//lcd.print(time.gettime("d-m-Y, H:i:s, D")); // Выводим время.
//delay(1); // Приостанавливаем скетч на 1 мс, чтоб не выводить время несколько раз за 1мс.
//}
if (millis() - last_time > 1000) {
last_time = millis();
printValues();
}
}
void printValues() {
lcd.setCursor(0, 2);
lcd.print("Tempe=");
lcd.print(round(bme.readTemperature()));
lcd.println("C ");
lcd.setCursor(10, 2);
lcd.print("Davl=");
lcd.print(round(bme.readPressure() / 100.0F * 0.750062F));
lcd.println("mm");
lcd.setCursor(0, 3);
lcd.print("Viso=");
lcd.print(round(bme.readAltitude(SEALEVELPRESSURE_HPA)));
lcd.print("m");
lcd.setCursor(10, 3);
lcd.print("Vlazh=");
lcd.print(round(bme.readHumidity()));
lcd.println("% ");
}
Для начала уточните, что у Вас за контроллер, т.к. указанного Вами
ат158,
я не знаю, и микрочип тоже не знает.
ткните меня в ошибки
В ошибки Вы сами должны нас ткнуть, т.е. описать что Вам не нравится и задать конкретный вопрос. Пока я вижу одну глобальную ошибку - использование напрочь кривой библиотеки iarduino_RTC. Бросьте каку и не хватайте руками всё, что на улице валяется.
как можно уменьшить вес библиотек не испортив ничего
Задача неясна. До какого предела уменьшить? Сейчас скетч занимает 12к, а сколько надо? Вы уж определитесь и задавайте вопрос поконкретнее.
Можно взять нану на ат318, там памяти больше
Это точно. А на 381 - ещё шибчее :)
Для начала уточните, что у Вас за контроллер, т.к. указанного Вами
ат158,
я не знаю, и микрочип тоже не знает.
ткните меня в ошибки
В ошибки Вы сами должны нас ткнуть, т.е. описать что Вам не нравится и задать конкретный вопрос. Пока я вижу одну глобальную ошибку - использование напрочь кривой библиотеки iarduino_RTC. Бросьте каку и не хватайте руками всё, что на улице валяется.
как можно уменьшить вес библиотек не испортив ничего
Задача неясна. До какого предела уменьшить? Сейчас скетч занимает 12к, а сколько надо? Вы уж определитесь и задавайте вопрос поконкретнее.
Сорян, ошибся, ATMega168, основной вопрос в весе, у меня есть всего 14к, при инициализации часов вес кода переваливает за 15к, соотвественно ниего не выходит сделать. Так вот вопрос это как уменьшить вес кода?
Библиотеку часов заменю. Спасибо
Это точно. А на 381 - ещё шибчее :)
Да это моя первая ошибка, не правльный выбор платы
В общем удалось мне установить все что я хотел, даже осталось место для реализации кнопок, только теперь столкнулся с такой проблемой, на фото видно, экран обновляется многократно и выводит полосы в 2 ячейки, не могу понять как мне это убрать, через миллис не могу остановить обновление экрана, так же еще вопрос, какой командой вывести формат времени "09:05" а не "9:5"
#include <Wire.h> #include <SPI.h> #include <LiquidCrystal_I2C.h> LiquidCrystal_I2C lcd(0x27, 20, 4); #include "RTClib.h" RTC_DS3231 rtc; char daysOfTheWeek[7][12] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; #include <Adafruit_Sensor.h> #include <Adafruit_BME280.h> #define SEALEVELPRESSURE_HPA (1013.25) Adafruit_BME280 bme; int last_time, zad ; //потому что значение инт от -32к до +32к void setup() { lcd.init(); lcd.backlight(); lcd.clear(); bool status; status = bme.begin(); rtc.begin(); rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); } void loop() { DateTime now = rtc.now(); lcd.setCursor(0,0); lcd.print("JEEP GRAND CHEROKEE"); if (millis() - zad > 1000) { //попробовал таким образом затормозить обновление экрана, нифига zad = millis(); lcd.setCursor(0,1); lcd.print(now.hour(), DEC); //вопрос уже стоит как выводит время в формате 09:05 а не 9:5 как это происходит сейчас lcd.print (":"); lcd.print( now.minute(), DEC); // lcd.print(":"); // не вижу смысла в секндах // lcd.print(now.second()); lcd.setCursor(6,1); lcd.print(daysOfTheWeek[now.dayOfTheWeek()]); lcd.setCursor(10,1); lcd.print(now.day(), DEC); lcd.print ("/"); lcd.print( now.month(), DEC); lcd.print("/"); lcd.print(now.year()); } // vremya(); //тут я пробовал сделать функцию на время чтобы просто вызывать часы командой, как с датчиком bme280 if (millis() - last_time > 500) { last_time = millis(); printValues(); //таким образом } } void printValues() { lcd.setCursor(0, 2); lcd.print("Tempe="); lcd.print(round(bme.readTemperature())); lcd.println("C "); lcd.setCursor(10, 2); lcd.print("Davl="); lcd.print(round(bme.readPressure() / 100.0F * 0.750062F)); lcd.println("mm"); lcd.setCursor(0, 3); lcd.print("Viso="); lcd.print(round(bme.readAltitude(SEALEVELPRESSURE_HPA))); lcd.print("m"); lcd.setCursor(10, 3); lcd.print("Vlazh="); lcd.print(round(bme.readHumidity())); lcd.println("% "); } /* int vremya() { //функция которая не получилась , есть совет по ней? lcd.setCursor(0,0); lcd.print("JEEP GRAND CHEROKEE"); lcd.setCursor(0,1); lcd.print(now.hour(), DEC); lcd.print (":"); lcd.print( now.minute(), DEC); // lcd.print(":"); // lcd.print(now.second()); lcd.setCursor(6,1); lcd.print(daysOfTheWeek[now.dayOfTheWeek()]); lcd.setCursor(10,1); lcd.print(now.day(), DEC); lcd.print ("/"); lcd.print( now.month(), DEC); lcd.print("/"); lcd.print(now.year()); } */через миллис не могу остановить обновление экрана,
В строке №16 написано в чём проблема, нужно просто прочитать и исправить.
какой командой вывести формат времени "09:05" а не "9:5"
Есть 100500 вариантов. Например, можно воспользоваться sprintf или даже printf настроить.
Но если с памятью проблемы, то можно if'ом разбирать нужет там 0 или нет.
через миллис не могу остановить обновление экрана,
В строке №16 написано в чём проблема, нужно просто прочитать и исправить.
какой командой вывести формат времени "09:05" а не "9:5"
Есть 100500 вариантов. Например, можно воспользоваться sprintf или даже printf настроить.
Но если с памятью проблемы, то можно if'ом разбирать нужет там 0 или нет.
После замены библиотеки, по вашему совету, у меня повилось место на плате, сейчас используется 88%. буду пробовать, спасибо
После замены библиотеки, по вашему совету, у меня повилось место на плате
Это очень сильное колдунство :)
через миллис не могу остановить обновление экрана,
В строке №16 написано в чём проблема, нужно просто прочитать и исправить.
Заменил int на unsigned lond
если я через миллис торможу обновление экрана, тогда у меня полоски весят все время до обновления, потом показывается время и все проворяется, то есть они присутствуют всегда, я пробовл ставить обноление раз в минуту и тогда отчетливо все видно. если убираю милллис из кода на время, то тогда цифра висит и моргает еле видными полосками. я не могу понять почему полосы воообще не уходят, как-будто они в скетче прописаны
какой командой вывести формат времени "09:05" а не "9:5"
Есть 100500 вариантов. Например, можно воспользоваться sprintf или даже printf настроить.
Но если с памятью проблемы, то можно if'ом разбирать нужет там 0 или нет.
Сделал через IF, вроде получилось, другие команды мне показались массивными по коду
После замены библиотеки, по вашему совету, у меня повилось место на плате
Это очень сильное колдунство :)
на уровне с хогвартсем )))
я не могу потому никогда раньше програмированием не занимался.
вот код. надеюсь на помощь
#include <Wire.h> #include <SPI.h> #include <LiquidCrystal_I2C.h> LiquidCrystal_I2C lcd(0x27, 20, 4); #include "RTClib.h" RTC_DS3231 rtc; char daysOfTheWeek[7][12] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; #include <Adafruit_Sensor.h> #include <Adafruit_BME280.h> #define SEALEVELPRESSURE_HPA (1013.25) Adafruit_BME280 bme; #include <GyverButton.h> //будут еще 2 кнопки GButton butt1(10); GButton butt2(5); #define mode_see //хочу реализовать 2 эрана и переключать их кнопками, один показ даты\времени #define mode_set // второй показ настроек времени/даты unsigned long last_time; //потому что значение инт от -4000к до +4000К unsigned long zad; void setup() { lcd.init(); lcd.backlight(); lcd.clear(); bool status; status = bme.begin(); rtc.begin(); rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); } void loop() { DateTime now = rtc.now(); butt1.tick(); //обязательная команда опрос кнопки butt2.tick(); //опрос 2й кнопки lcd.setCursor(0,0); lcd.print("JEEP GRAND CHEROKEE"); /* if (millis() - zad >60000) { //думал обновлять раз в минуту, но так выходит что все время полоски и только во время обновления показыватеся время zad = millis();*/ lcd.setCursor(0,1); if (now.hour() < 10) { //организовал 0 перед выводом времени таким образом, как советовали lcd.print("0"); lcd.print(now.hour()); } else if (now.hour() >=10) { lcd.print(now.hour()); } lcd.print(":"); if (now.minute() < 10) { lcd.print("0"); lcd.print(now.minute()); //теперь хоть время занимает стабильно 5 символов и нормально отображается, относительно, не считая полос } else if (now.minute() >=10) { lcd.print(now.minute()); } //} lcd.setCursor(6,1); lcd.print(daysOfTheWeek[now.dayOfTheWeek()]); lcd.setCursor(10,1); if (now.day() < 10) { lcd.print("0"); lcd.print( now.day(), DEC); } else if (now.day() >=10) { lcd.print( now.day(), DEC); } lcd.print ("/"); if (now.month() < 10) { lcd.print("0"); lcd.print( now.month(), DEC); } else if (now.month() >=10) { lcd.print( now.month(), DEC); } lcd.print("/"); lcd.print(now.year()); if(millis() - zad >60000){ zad = millis(); // chas(); } if (millis() - last_time >1000) { last_time = millis(); printValues(); } } void printValues() { lcd.setCursor(0, 2); lcd.print("T="); lcd.print(round(bme.readTemperature())); lcd.print("C|"); lcd.print(round(rtc.getTemperature())); lcd.println("C "); lcd.setCursor(10, 2); lcd.print("Davl="); lcd.print(round(bme.readPressure() / 100.0F * 0.750062F)); lcd.println("mm"); lcd.setCursor(0, 3); lcd.print("Viso="); lcd.print(round(bme.readAltitude(SEALEVELPRESSURE_HPA))); lcd.print("m"); lcd.setCursor(10, 3); lcd.print("Vlazh="); lcd.print(round(bme.readHumidity())); lcd.println("% "); }вот код.
А полоски где?
вот код.
А полоски где?
Вот это фото уже было, с того момента скетч чуть изменился, но полосы на часах так же держатся, причем при уменьшении колличества обновлений экрана они становятся только четче, и обратно, если оставить обновление как есть, каждую секунду то их не так честко видно, больше выглядят как моргание цыфрой
--Доктор! Что со мной такое - куда ни ткну пальцем - больно?! И в ногу ткну - больно, и в руку, и в голову!
--Мил человек, да у вас палец сломан.
--------
Это я к тому, что стоит попробовать экран поменять. ;)))))
--Доктор! Что со мной такое - куда ни ткну пальцем - больно?! И в ногу ткну - больно, и в руку, и в голову!
--Мил человек, да у вас палец сломан.
--------
Это я к тому, что стоит попробовать экран поменять. ;)))))
тут скорее всего ручки из жопки ))
Ну правильная была мысль обновлять время с интервалом и
lcd.setCursor(0,0);
lcd.print("JEEP GRAND CHEROKEE");Ну правильная была мысль обновлять время с интервалом и
lcd.setCursor(0,0);
lcd.print("JEEP GRAND CHEROKEE");если ставлю надпись в setup то происходит следующее
int button_func(){ //управление настройкой с кнопок if(butt1.isHolded() && butt2.isHolded()){ if(mode_see==1 && mode_set>7){mode_set==1;} mode_set++; //тут не понимает что хочу } time.blinktime(mode_set); if(mode_set){ //если в режиме управления if(butt2.isClick()|| butt2.isStep()){ //если нажата или ужержана клавиша 2 увеличивать показания switch (mode_set){ // инкремент (увеличение) устанавливаемого значения /* сек */ case 1: time.settime(0, -1, -1, -1, -1, -1, -1); break; /* мин */ case 2: time.settime(-1, (now.minute==59?0:now.minute+1), -1, -1, -1, -1, -1); break; /* час */ case 3: time.settime(-1, -1, (now.hour==23?0:now.hour+1), -1, -1, -1, -1); break; /* дни */ case 4: time.settime(-1, -1, -1, (now.day==31?1:now.day+1), -1, -1, -1); break; /* мес */ case 5: time.settime(-1, -1, -1, -1, (now.month==12?1:now.month+1), -1, -1); break; /* год */ case 6: time.settime(-1, -1, -1, -1, -1, (now.year==99?0:now.year+1), -1); break; /* д.н.*/ case 7: time.settime(-1, -1, -1, -1, -1, -1, (now.dayOfTheWeek==6?0:now.dayOfTheWeek+1) ); break; } } } if(butt1.isClick() || butt1.isStep()){ //если нажата или ужержана клавиша 1 уменьшать показания switch (mode_set){ // декремент (уменьшение) устанавливаемого значения /* сек */ case 1: time.settime(0, -1, -1, -1, -1, -1, -1); break; /* мин */ case 2: time.settime(-1, (now.minute==59?0:now.minute-1), -1, -1, -1, -1, -1); break; /* час */ case 3: time.settime(-1, -1, (now.hour==23?0:now.hour-1), -1, -1, -1, -1); break; /* дни */ case 4: time.settime(-1, -1, -1, (now.day==31?1:now.day-1), -1, -1, -1); break; /* мес */ case 5: time.settime(-1, -1, -1, -1, (now.month==12?1:now.month-1), -1, -1); break; /* год */ case 6: time.settime(-1, -1, -1, -1, -1, (now.year==99?0:now.year-1), -1); break; /* д.н.*/ case 7: time.settime(-1, -1, -1, -1, -1, -1, (now.dayOfTheWeek==6?0:now.dayOfTheWeek-1) ); break; } } }Еще вопросик, я хотел вот этим кодом управлять настройкой времени чтобы не тащить комп к авто, код взят с https://lesson.iarduino.ru/page/urok-17-podklyuchenie-rtc-chasy-realnogo-vremeni-s-knopkami/ и "адаптирован" под мои команды, вопрос в том что я ничего не понимаю в настройке кнопок и логике работы, и в принцепе в логике работы этого кода, если у вас есть рабочик код настройки времени с 2 кнопок поделитесь плиз либо помогите мне написать его
http://arduino.ru/forum/obshchii/attiny85-i-posledovatelnyi-port#comment...
Вот здесь я привел программу часов с настройкой времени с помощью одной кнопки. И будильника с помощью другой.
Очень похоже что датчик bme280 дает артефакты на экран, потому что при работе только с экраном и временем ничего не моргало. и никаких полос в пустых строках не было. получатеся на датчик bme кривая библиотека? и какой командой можно заставить время мигать при настройке? now.blinktime пробовал выдает ошибку что не определен оператор. код для понимания процесса, пробую отдельно написать упраление кнопками, чтобы потом встроих их в основной скеч, до конца он еще не написан, но даже это заставить работать пока не получается.
#include <Wire.h> #include <SPI.h> #include <LiquidCrystal_I2C.h> LiquidCrystal_I2C lcd(0x27, 20, 4); #include <RTClib.h> RTC_DS3231 rtc; char daysOfTheWeek[7][12] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; #include <GyverButton.h> GButton butt2(10); //определить кнопку и задать пин GButton butt1(5); #define mode_see 1 //мод просмотра времени #define mode_set 1 //мод настройки времени void setup() { lcd.init(); lcd.backlight(); lcd.clear(); rtc.begin(); //rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); //команда для прошивки времени, не забыть отключить ее на финальной прошивке } void loop() { butt1.tick(); //инициализация кнопок butt2.tick(); DateTime now = rtc.now(); lcd.setCursor(0,1); if (now.hour() < 10) { lcd.print("0"); lcd.print(now.hour()); } else if (now.hour() >=10) { lcd.print(now.hour()); } lcd.print(":"); if (now.minute() < 10) { lcd.print("0"); lcd.print(now.minute()); } else if (now.minute() >=10) { lcd.print(now.minute()); } lcd.setCursor(6,1); lcd.print(daysOfTheWeek[now.dayOfTheWeek()]); lcd.setCursor(10,1); if (now.day() < 10) { lcd.print("0"); lcd.print( now.day(), DEC); } else if (now.day() >=10) { lcd.print( now.day(), DEC); } lcd.print ("/"); if (now.month() < 10) { lcd.print("0"); lcd.print( now.month(), DEC); } else if (now.month() >=10) { lcd.print( now.month(), DEC); } lcd.print("/"); lcd.print(now.year()); button_func (); //инициализация управления копками } int button_func(){ //управление с кнопок if(butt1.isHolded() && butt2.isHolded()){ //если ужержана клавиша 1 И ужержана клавиша 2 переходить в устанвку времени mode_set; if (butt1.isHolded()){mode_set+1;} //почему когда здесть стоило mode_set++ прога не понимала что я хочу, а с +1 понимает? if(mode_set>7){mode_set==1;} } now.blinktime(mode_set); //выдает ошибку, не определен оператор now хочу чтобы параметр при установке времени моргал if(mode_set){ //если в режиме управления if(butt2.isClick()|| butt2.isStep()){ //если нажата или ужержана клавиша 2 увеличивать показания switch (mode_set){ // инкремент (увеличение) устанавливаемого значения case 1: now.settime(0, -1, -1, -1, -1, -1, -1); break; //СЕК case 2: now.settime(-1, (now.minute==59?0:now.minute+1), -1, -1, -1, -1, -1); break; //МИН // case 3: now.settime(-1, -1, (now.hour==23?0:now.hour+1), -1, -1, -1, -1); break; //ЧАС // case 4: now.settime(-1, -1, -1, (now.day==31?1:now.day+1), -1, -1, -1); break; //ДНИ // case 5: now.settime(-1, -1, -1, -1, (now.month==12?1:now.month+1), -1, -1); break; //МЕС // case 6: now.settime(-1, -1, -1, -1, -1, (now.year==99?0:now.year+1), -1); break; //ГОД // case 7: now.settime(-1, -1, -1, -1, -1, -1, (now.dayOfTheWeek==6?0:now.dayOfTheWeek+1) ); break; //Д.Н. } } } } if(butt1.isClick() || butt1.isStep()){ //если нажата или ужержана клавиша 1 уменьшать показания switch (mode_set){ // декремент (уменьшение) устанавливаемого значения case 1: now.settime(0, -1, -1, -1, -1, -1, -1); break; //сек case 2: now.settime(-1, (now.minute==59?0:now.minute-1), -1, -1, -1, -1, -1); break; //мин // case 3: now.settime(-1, -1, (now.hour==23?0:now.hour-1), -1, -1, -1, -1); break; //час // case 4: now.settime(-1, -1, -1, (now.day==31?1:now.day-1), -1, -1, -1); break; //дни // case 5: now.settime(-1, -1, -1, -1, (now.month==12?1:now.month-1), -1, -1); break; //мес // case 6: now.settime(-1, -1, -1, -1, -1, (now.year==99?0:now.year-1), -1); break; //год // case 7: now.settime(-1, -1, -1, -1, -1, -1, (now.dayOfTheWeek==6?0:now.dayOfTheWeek-1) ); break; //д.н. } } }и какой командой можно заставить время мигать при настройке?
Там вроде только курсор может мигать, а если хотите текст - мигайте им сами (очищайте и выводите по интервалам millis()).
http://www.dinceraydin.com/lcd/commands.htm
Да ему не погасить экран надо (без очистки) а Turn on visible blinking-block cursor
Сорри. Что-то у меня аллергия на бессмысленные вопросы в последнее время наблюдается - понять их не получается.
Мне кажется автор хочет сделать как часто в других девайсах со временем - чтобы при установке изменяемое число мигало, не курсор.
Если курсор полноразмерный (5х7), во всё знакоместо, то им можно мигать в изменяемой позиции, и просто и наглядно. (Я всегда так делаю)
Мне кажется автор хочет сделать как часто в других девайсах со временем - чтобы при установке изменяемое число мигало, не курсор.
Именно так я и хочу сделать
Сорри. Что-то у меня аллергия на бессмысленные вопросы в последнее время наблюдается - понять их не получается.
Вроде по максимуму конкретизировал вопрос, и в скетче сделал кучу пометок что и как хочу чтобы полнятно было
Если курсор полноразмерный (5х7), во всё знакоместо, то им можно мигать в изменяемой позиции, и просто и наглядно. (Я всегда так делаю)
У вас уже есть реализованная настройка часов на кнопках? можете код показать?
У вас уже есть реализованная настройка часов на кнопках?
Есть.
можете код показать?
Нет.
Валерич-тех. Что Вам мешает поискать на форуме решения для меню.
Ну ладно бы хоть какие то телодвижения Валерич делал - тогда и не жалко... А так, дай да дай... Стыдоба то какая.(
А вам пряма жалка чилавеку памочь!
А вот есть такая гнильца характера, чего уж тут...( Да и много тут всяких хитрожопых поразвелось, любителей лохов, понимаешь ли.)
А вот есть такая гнильца характера, чего уж тут...( Да и много тут всяких хитрожопых поразвелось, любителей лохов, понимаешь ли.)
я же не прошу за меня написать код. или что-то сделать за меня, тем более какие-то из своих новых открытий выкладываю сюда и вот стоило спросить про управление кнопками как сразу хитрожопый. и ничего что я б. до этого дойти своей головой пока еще не могу
Я понял что рано мне еще меню осваивать, так как уже несколько дней не могу напряму с кнопок время менять, какой командой в библиотеке rtclib просходит управление настройкой времени, не при компиляции скетча.. Еще прикол в том что команды типи now.isrunning| now.timestamp| now.toString (пытался пробовать все, чтобы хоть что-то куда-то двигалось) компилятор выдает что не объявлено значение now, хотя в loop все объявлено. Толи я дурак, то ли лыжи не едут. Какой командой меняется время на модуле ?
ПС смотри коментарии в скетче
#include <Wire.h> #include <SPI.h> #include <LiquidCrystal_I2C.h> LiquidCrystal_I2C lcd(0x27, 20, 4); #include <RTClib.h> RTC_DS3231 rtc; char daysOfTheWeek[7][12] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; #include <GyverButton.h> GButton butt2(10); GButton butt1(5); //#define mode_see 1 //#define mode_set 0 //int val; void setup() { lcd.init(); lcd.backlight(); lcd.clear(); rtc.begin(); rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); //команда для прошивки времени, не забыть отключить ее на финальной прошивке } void loop() { butt1.tick(); butt2.tick(); DateTime now = rtc.now(); //значение объявлено lcd.setCursor(0,1); if (now.hour() < 10) { lcd.print("0"); lcd.print(now.hour()); } else if (now.hour() >=10) { lcd.print(now.hour()); } lcd.print(":"); if (now.minute() < 10) { lcd.print("0"); lcd.print(now.minute()); } else if (now.minute() >=10) { lcd.print(now.minute()); } lcd.setCursor(6,1); lcd.print(daysOfTheWeek[now.dayOfTheWeek()]); lcd.setCursor(10,1); if (now.day() < 10) { lcd.print("0"); lcd.print( now.day(), DEC); } else if (now.day() >=10) { lcd.print( now.day(), DEC); } lcd.print ("/"); if (now.month() < 10) { lcd.print("0"); lcd.print( now.month(), DEC); } else if (now.month() >=10) { lcd.print( now.month(), DEC); } lcd.print("/"); lcd.print(now.year()); if (butt1.isClick()){ rtc.adjust(DateTime(now.hour()+1)); //пробовал этой командой. думал что если установит при загрузке то и просто тоже будет работать, но нет, только сбивает время на 6,28 и 2106 год } if(butt2.isClick()){ now.DateTime(now.hour()-1); //данный вариант так же не подходит } //now.isrunning не работает. я уже все команды из библиотеки попробовал /* if(butt1.isClick()){ //пробовал таким образом, взято с gitHub с <a data-cke-saved-href="https://github.com/adafruit/RTClib/blob/master/RTClib.cpp" href="https://github.com/adafruit/RTClib/blob/master/RTClib.cpp" rel="nofollow">https://github.com/adafruit/RTClib/blob/master/RTClib.cpp</a> rtc.adjust(const DateTime& dt); Wire._I2C_WRITE(bin2bcd(dt.hour()+1)); //естественно тоже не пошло } if(butt2.isClick()){ now.timestamp(now.hour()-1); //так тоже не идет }*/ /* void RTC_DS3231::adjust(const DateTime& dt) { Wire.beginTransmission(DS3231_ADDRESS); Wire._I2C_WRITE((byte)0); // start at location 0 Wire._I2C_WRITE(bin2bcd(dt.second())); Wire._I2C_WRITE(bin2bcd(dt.minute())); Wire._I2C_WRITE(bin2bcd(dt.hour())); Wire._I2C_WRITE(bin2bcd(0)); Wire._I2C_WRITE(bin2bcd(dt.day())); Wire._I2C_WRITE(bin2bcd(dt.month())); Wire._I2C_WRITE(bin2bcd(dt.year() - 2000)); Wire.endTransmission(); uint8_t statreg = read_i2c_register(DS3231_ADDRESS, DS3231_STATUSREG); statreg &= ~0x80; // flip OSF bit write_i2c_register(DS3231_ADDRESS, DS3231_STATUSREG, statreg); }*/Вот посмотрите, простенький примерчик работы с RTC без библиотек. Установка и вывод времени идет через монитор.
#include <Wire.h> #define DS3231_I2C_ADDRESS 0x68 byte seconds, minutes, hours, day, date, month, year; char weekDay[4]; byte tMSB, tLSB; float temp3231; void setup() { Wire.begin(); Serial.begin(9600); //set control register to output square wave on pin 3 at 1Hz Wire.beginTransmission(DS3231_I2C_ADDRESS); // 104 is DS3231 device address Wire.write(0x0E); //выставляемся в 14й байт Wire.write(B00000000); //сбрасываем контрольные регистры Wire.write(B10001000); //выставляем 1 на статус OSF и En32kHz Wire.endTransmission(); } void loop() { watchConsole(); //читаем консоль. Если нажата "T" читаем из консоли следующий 7 байт и устанавливаем время. get3231Date(); //получаем данные //и потом их выводим через Serial.print() Serial.print(weekDay); Serial.print(", "); Serial.print(month, DEC); Serial.print("/"); Serial.print(date, DEC); Serial.print("/"); Serial.print(year, DEC); Serial.print(" - "); Serial.print(hours, DEC); Serial.print(":"); Serial.print(minutes, DEC); Serial.print(":"); Serial.print(seconds, DEC); Serial.print(" Temperature: "); Serial.print(get3231Temp());Serial.print("; "); Serial.println(get3231Register(0x0F)); //получаем и выводим статусовый регистр delay(1000); } // Convert normal decimal numbers to binary coded decimal byte decToBcd(byte val) { return ( (val/10*16) + (val%10) ); } void watchConsole() { if (Serial.available()) { // Look for char in serial queue and process if found if (Serial.read() == 84) { //If command = "T" Set Date set3231Date(); get3231Date(); Serial.println(" "); } } } void set3231Date() { //T(sec)(min)(hour)(dayOfWeek)(dayOfMonth)(month)(year) //T(00-59)(00-59)(00-23)(1-7)(01-31)(01-12)(00-99) //Example: 02-Feb-09 @ 19:57:11 for the 3rd day of the week -> T1150004061016 seconds = (byte) ((Serial.read() - 48) * 10 + (Serial.read() - 48)); // Use of (byte) type casting and ascii math to achieve result. minutes = (byte) ((Serial.read() - 48) *10 + (Serial.read() - 48)); hours = (byte) ((Serial.read() - 48) *10 + (Serial.read() - 48)); day = (byte) (Serial.read() - 48); date = (byte) ((Serial.read() - 48) *10 + (Serial.read() - 48)); month = (byte) ((Serial.read() - 48) *10 + (Serial.read() - 48)); year = (byte) ((Serial.read() - 48) *10 + (Serial.read() - 48)); Wire.beginTransmission(DS3231_I2C_ADDRESS); //начали сессию Wire.write(0x00); //поставляемся в нулевой байт для чтения данных Wire.write(decToBcd(seconds)); Wire.write(decToBcd(minutes)); Wire.write(decToBcd(hours)); Wire.write(decToBcd(day)); Wire.write(decToBcd(date)); Wire.write(decToBcd(month)); Wire.write(decToBcd(year)); Wire.endTransmission();//закрыли сессию } byte get3231Register(byte regNo) { // send request to receive data starting at register regNo Wire.beginTransmission(DS3231_I2C_ADDRESS); // 104 is DS3231 device address Wire.write(regNo); // start at register regNo Wire.endTransmission(); Wire.requestFrom(DS3231_I2C_ADDRESS, 1); // request one byte if(Wire.available()) return Wire.read(); } void set3231Register(byte regNo, byte value) { Wire.beginTransmission(DS3231_I2C_ADDRESS); Wire.write(regNo); Wire.write(value); Wire.endTransmission(); } void get3231Date() { // send request to receive data starting at register 0 Wire.beginTransmission(DS3231_I2C_ADDRESS); // 104 is DS3231 device address Wire.write(0x00); // start at register 0 Wire.endTransmission(); Wire.requestFrom(DS3231_I2C_ADDRESS, 7); // request seven bytes if(Wire.available()) { seconds = Wire.read(); // get seconds minutes = Wire.read(); // get minutes hours = Wire.read(); // get hours day = Wire.read(); date = Wire.read(); month = Wire.read(); //temp month year = Wire.read(); //Конвертация происходит очень просто - битовым оператором & мы очищаем МЛАДШИЕ (0,1,2,3) четыре бита , сдвигаем все вправо на 4 позиции (очищенные биты //вылезут при этом с левой стороны и результат умножаем на 10, т.к. в старших битах хранится информация о десятках секунд. //После этого битовым оператором & очищаем СТАРШИЕ (4,5,6,7)четыре бита и получаем секунды. Затем суммируем десятки секунд и единиц. seconds = (((seconds & B11110000)>>4)*10 + (seconds & B00001111)); minutes = (((minutes & B11110000)>>4)*10 + (minutes & B00001111)); hours = (((hours & B00110000)>>4)*10 + (hours & B00001111)); day = (day & B00000111); // 1-7 date = (((date & B00110000)>>4)*10 + (date & B00001111)); // 1-31 month = (((month & B00010000)>>4)*10 + (month & B00001111)); //msb7 is century overflow year = (((year & B11110000)>>4)*10 + (year & B00001111)); } else { //oh noes, no data! } switch (day) { case 1: strcpy(weekDay, "Mon"); break; case 2: strcpy(weekDay, "Tue"); break; case 3: strcpy(weekDay, "Wed"); break; case 4: strcpy(weekDay, "Thu"); break; case 5: strcpy(weekDay, "Fri"); break; case 6: strcpy(weekDay, "Sat"); break; case 7: strcpy(weekDay, "Sun"); break; } } float get3231Temp() { //temp registers (11h-12h) get updated automatically every 64s Wire.beginTransmission(DS3231_I2C_ADDRESS); Wire.write(0x11); Wire.endTransmission(); Wire.requestFrom(DS3231_I2C_ADDRESS, 2); if(Wire.available()) { tMSB = Wire.read(); //2's complement int portion tLSB = Wire.read(); //fraction portion temp3231 = (tMSB & B01111111); //do 2's math on Tmsb temp3231 += ( (tLSB >> 6) * 0.25 ); //only care about bits 7 & 8 } else { //oh noes, no data! } return temp3231; }По нему можно разобраться с работой с RTC
Какую в точности библиотеку используете ? Я две наугад тыкнул в стандартном менеджере библиотек по отбору rtclib - не подходят, там все названия похожие.
Если Вы про скетч из #39, то там нет никакого loop, т.к. у того, что Вы планировали как loop, не закрыта фигурная скобка.
Толи я дурак, то ли лыжи не едут.
В случаях с компилятором - обычно первое. Всегда исходите из этого и ищите проблему у себя. Чтобы компилятор косячил - очень редкие случаи.
Я понял что рано мне еще меню осваивать
Правильно поняли. Начните с K&R. До меню доберётсь где-то через год. Но уже с понимаем и знаниями, как мужчина, а не как мартышка с очками.
Какую в точности библиотеку используете ? Я две наугад тыкнул в стандартном менеджере библиотек по отбору rtclib - не подходят, там все названия похожие.
https://github.com/adafruit/RTClib эту использую
Если долго мучиться, что-нибудь получится....
Почему ардуино не записывает новое значение времени в rtc, при чем дата устанавливается (спецом сентябрь поставл, для проверки, все идет кроме времени) и еще, почему дни недели стали выводиться цифрами, а не буквами то есть сейчас у меня горит 328 постоянно на lcd, хотя раньше, до того как перевел отслеживание времени в отдельную функцию все показывало четко
есть коментарии с описанием и вопросами.
#include <Wire.h> #include <SPI.h> #include <LiquidCrystal_I2C.h> LiquidCrystal_I2C lcd(0x27, 20, 4); #include <RTClib.h> //adafruit RTC_DS3231 rtc; char daysOfTheWeek[7][12] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; //DateTime now // datetime считывает время с модуля и выводит на команды #include <GyverButton.h> GButton butt2(10); GButton butt1(5); unsigned long zad; bool mode = 0; //0-показ времени, 1-настройка времени boolean blinkFlag, newTimeFlag; int mins, hrs, weeek, ddd, mmm, yyy; int znach; //для отслеживаня изменений при нажатии на клавишу, сейчас не видно чтобы часы менялись void setup() { lcd.init(); lcd.backlight(); lcd.clear(); rtc.begin(); rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); //команда для прошивки времени, не забыть отключить ее на финальной прошивке /*DateTime now = rtc.now(); mins = now.minute(); hrs = now.hour(); weeek = daysOfTheWeek[now.dayOfTheWeek()]; ddd = now.day(); mmm = now.month(); yyy = now.year();*/ } void loop() { DateTime now = rtc.now(); // datetime считывает время с модуля и выводит на команды mins = now.minute(); hrs = now.hour(); weeek = daysOfTheWeek[now.dayOfTheWeek()]; ddd = now.day(); mmm = now.month(); yyy = now.year(); butt1.tick(); butt2.tick(); if (mode == 0) { func_time(); //отслеживание времени lcd.setCursor(1, 0); lcd.print ("time"); } if (butt2.isHolded()) { mode ++; if (mode >= 2) mode = 0; } if(mode==1) { lcd.setCursor(1, 0); lcd.print ("sett"); //отслеживание переходад в установку времени func_time(); //работает. но как-то с запазданием что ли settings(); lcd.setCursor(2, 2); lcd.print (znach); DateTime(setTime()); } } void settings() { butt1.tick(); butt2.tick(); if (mode == 1) { if (!newTimeFlag) newTimeFlag = true; if (butt1.isClick() || butt1.isStep()) { mins ++; znach ++; if (mins > 59) { mins = 0; hrs ++; if (hrs> 23) hrs = 0; } } if (butt2.isClick()/* || butt2.isStep()*/ ) { mins --; znach --; if (mins < 0) { mins = 59; hrs --; if (hrs < 0) hrs = 23; } } if (millis() - zad > 30000) { //если прошло 30 сек возвращать в мод 0 и установить новое время zad = millis(); mode = 0; newTimeFlag = false; rtc.adjust(DateTime(2019, 9, 29, hrs, mins, 0)); // прописывается только дата????????????? } } } void func_time() { lcd.setCursor(0, 1); if (hrs < 10) { lcd.print("0"); lcd.print(hrs); } else if (hrs >= 10) { lcd.print(hrs); } lcd.print(":"); if (mins < 10) { lcd.print("0"); lcd.print(mins); } else if (mins >= 10) { lcd.print(mins); } lcd.setCursor(6, 1); lcd.print(weeek); //где буквы? ведь у меня четко заданы дни недели в начале кода lcd.setCursor(10, 1); if (ddd < 10) { lcd.print("0"); lcd.print( ddd, DEC); } else if (ddd >= 10) { lcd.print( ddd, DEC); } lcd.print ("/"); if (mmm < 10) { lcd.print("0"); lcd.print( mmm, DEC); } else if (mmm >= 10) { lcd.print( mmm, DEC); } lcd.print("/"); lcd.print(yyy); }А чего вы ждете, выводя на LCD переменную типа int - не цифр, а пряников?
/**/ const char sun[] PROGMEM = "Sun"; const char mon[] PROGMEM = "Mon"; const char tue[] PROGMEM = "Tue"; const char wed[] PROGMEM = "Wed"; const char thu[] PROGMEM = "Thu"; const char fri[] PROGMEM = "Fri"; const char sat[] PROGMEM = "Sat"; const char* const weekDay[7] PROGMEM = { sun, mon, tue, wed, thu, fri, sat }; void printWeekDay(byte b) { char buffer[30]; strcpy_P(buffer, (char*)pgm_read_word(&(weekDay[b]))); Serial.println(buffer); } //--------------------------------------------- void setup() { Serial.begin(9600); for (int i = 0; i < 6; i++)printWeekDay(i); } void loop() { }Если долго мучиться, что-нибудь получится....
Валерич, кончайте уже идиотизмом страдать. За то время, пока вы трахаетесь с несколькими строчками кода - давно бы уже учебник по языку прочитали.
По поводу дней недели - сравните как вы их выводили на монитор в скетчах в начале темы - и попытайтесь понять разницу. Там было правильно, теперь -нет
Если долго мучиться, что-нибудь получится....
Валерич, кончайте уже идиотизмом страдать. За то время, пока вы трахаетесь с несколькими строчками кода - давно бы уже учебник по языку прочитали.
Бесконечно читать можно про прогрмирование, этим я и знамаюсь, но только время отведенное на это все 2 часа максимум в день. так что много не начитаешься, единственное с чем я действительно сейчас мучаюсь это с тем что rtc перезаписать не удается. но это дело поправиться когда пойму что к чему.
[/quote]
По поводу дней недели - сравните как вы их выводили на монитор в скетчах в начале темы - и попытайтесь понять разницу. Там было правильно, теперь -нет
[/quote]
так вот я сейчас использую тот что работает (старый) + основной вопрос все же про модуль времени и команду rtc.adjust
Все те кто пользуются библиотекой не знают как она устроена, тем более для rst . Надо разумеется залезть в нее и прочитать. А там как минимум два класса. И это даже не библиотека для лсд.
ПС: соберите это устройство , залейте программу и понаблюдайте работу. #84 Это позволит вам сэкономить немного времени для понимания и обучения.
Я наконец-то понял как заставить дуинку писать время в rtc и настраивать его с кнопок, оказалось что в loop жестко задается значения и по этому не записывалось ничего(это я для себя добавил, вы то уже 100% это все знаете). одна осталось проблема. чтобы видеть какие цифры будут выводиться после записи мне необходимо сейчас отдельно на экране выводить минуты. Где в коде проблема, почему не обновляется время без всяких доп цифр на экране ( см ссылки )
КАК ПРИХОДИТСЯ УСТАНАВЛИВАТЬ ЧТОБЫ ВИДЕТЬ МИНУТЫ
ПОСЛЕ ОБНОВЛЕНИЯ ВРЕМЕНИ
#include <Wire.h> #include <SPI.h> #include <LiquidCrystal_I2C.h> LiquidCrystal_I2C lcd(0x27, 20, 4); #include <RTClib.h> RTC_DS3231 rtc; char daysOfTheWeek[7][12] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; //DateTime now // datetime считывает время с модуля и выводит на команды #include <GyverButton.h> GButton butt2(10); GButton butt1(5); unsigned long zad; bool mode = 0; //0-показ времени, 1-настройка времени boolean blinkFlag, newTimeFlag; int mins, hrs, ddd, mmm, yyy; int znach; char weeek; void setup() { lcd.init(); lcd.backlight(); lcd.clear(); rtc.begin(); rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); //команда для прошивки времени, не забыть отключить ее на финальной прошивке DateTime now = rtc.now(); mins = now.minute(); hrs = now.hour(); //weeek = daysOfTheWeek[now.dayOfTheWeek()]; ddd = now.day(); mmm = now.month(); yyy = now.year(); } void loop() { butt1.tick(); butt2.tick(); if (butt2.isHolded()) { mode ++; if (mode >1) mode = 0; } if (mode == 0) { func_time(); lcd.setCursor(1, 0); lcd.print ("time"); } if (mode == 1) { lcd.setCursor(1, 0); lcd.print ("sett"); settings(); lcd.setCursor(4, 2); lcd.print (mins); //чтобы увидеть изменилось время по нажатию или нет и только так сейчас это можно увидеть } } void settings() { butt1.tick(); butt2.tick(); if (mode == 1) { if (!newTimeFlag) newTimeFlag = true; if (butt1.isClick() || butt1.isStep()) { mins ++; znach ++; if (mins > 59) { mins = 0; hrs ++; if (hrs > 23) hrs = 0; } } if (butt2.isClick()/* || butt2.isStep()*/ ) { mins --; znach --; if (mins < 0) { mins = 59; hrs --; if (hrs < 0) hrs = 23; } } if (millis() - zad > 30000) { //если прошло 30 сек возвращать в мод 0 и установить новое время zad = millis(); newTimeFlag = false; rtc.adjust(DateTime(2019, 9, 8, hrs, mins, 0)); mode = 0; } } } void func_time() { DateTime now = rtc.now(); lcd.setCursor(1, 1); if (now.hour() < 10) { lcd.print("0"); lcd.print(now.hour()); } else if (now.hour() >= 10) { lcd.print(now.hour()); } lcd.print(":"); if (now.minute() < 10) { lcd.print("0"); lcd.print(now.minute()); } else if (now.minute() >= 10) { lcd.print(now.minute()); } lcd.setCursor(9, 1); lcd.print(daysOfTheWeek[now.dayOfTheWeek()]); lcd.setCursor(13, 1); if (now.day() < 10) { lcd.print("0"); lcd.print( now.day(), DEC); } else if (now.day() >= 10) { lcd.print( now.day(), DEC); } lcd.print ("/"); if (now.month() < 10) { lcd.print("0"); lcd.print( now.month(), DEC); } else if (now.month() >= 10) { lcd.print( now.month(), DEC); } }