RTC DS3231 и LCD 2004A: вместе по I2C не работают
- Войдите на сайт для отправки комментариев
Добрый день!
Дано: Arduino UNO, RTC DS3231, LCD экран 20х4 на I2C (чип PCF8574AT). Часы и экран подключены по I2C к Arduino. На SQW RTC установлена частота 1 Гц. На первое прерывание повешан выход SQW с RTC. Написан простейший скетч: по прерыванию надо мигать светодиодом и выводить на экран время.
Используемые дополнительные библиотеки: DS3231 (версия 1.01 от 25 Aug 2014), LiquidCrystal_I2C_V112
Код скетча
#include <TimeLib.h> #include <Time.h> //http://www.arduino.cc/playground/Code/Time #include <Wire.h> #include <LiquidCrystal_I2C.h> #include <DS3231.h> LiquidCrystal_I2C lcd(0x3F, 20, 4); DS3231 rtc(SDA, SCL); volatile int state = LOW; void setup() { rtc.begin(); rtc.setSQWRate(1); lcd.init(); lcd.backlight(); lcd.setCursor(0, 0); lcd.print("Start"); pinMode(LED_BUILTIN, OUTPUT); attachInterrupt(1, blink, FALLING); } void blink() { state = !state; digitalWrite(LED_BUILTIN, state); //lcd.setCursor(0, 2); //lcd.print(" "); //lcd.print(String(hour(),1)+":"+String(minute(),1)+":"+String(second(),1)+" "+String(day(),1)+"."+String(month(),1)+"."+String(year(),1)); delay(200); } void loop(void) { }
Преамбула: по отдельности часы и экран работают. Скетч, в том виде, что приведен, тоже работает: светодиод мигает.
Проблема:
как только я раскомментирую любую из закомментируемых строк, все встает в ступор: светодиод не мигает, соответственно на экране ни чего не отображается.
Буду благодарен за любые идеи, бъюсь уже третий день, попробовал несколько библиотек rtc - все без изменения.
Вот пример, специально для Uni, что бывает, когда чайники используют прерывания.
Не то что ООП туда тащить, а вообще из фреймворка убрать attachIntrrrupt! Тогда вот таких вопросов не будет.
А зачем, собственно, вся работа с экраном и даже delay() вынесены в прерывание?
to wdrakula: А более расширенные комменты можно услышать? Что не так с приведенным примером?
to andriano: delay остался от эксперимента. Работа с экраном вынесена в прерывание, т.к. в дальнейшем необходимо по прерыванию выводить время и состояние на экран.
to andriano: delay остался от эксперимента. Работа с экраном вынесена в прерывание, т.к. в дальнейшем необходимо по прерыванию выводить время и состояние на экран.
Так и выводите, только не в прерывании, а после.
to andriano: delay остался от эксперимента. Работа с экраном вынесена в прерывание, т.к. в дальнейшем необходимо по прерыванию выводить время и состояние на экран.
Ну так и выводите по прерыванию, а не из прерывания: в прерывании выставляется флаг, который анализируется из loop() и уже оттуда осуществляется вывод.
Вот Ваш переделанный код
В таком виде, как НАДО было делать. Я старался почти ничего не менять.
Даже оставил все Ваши библиотеки. Хоть это и мусор какой-то.
Я убрал в выводе на экран извращения со стрингами. Простите уж.
вот фото комментарий:
Леонардо, часы, экран. Принес на кухню.
макет собран.
все работает, строки на экране по-своему разместил.
==========================
при редактировании:
есссно, что была некая адаптация под леонардо, например номер прерывания.
Если Нужно показать на Нанке или Меге - пожалуйста, если занят не буду.
Всем огромное спасибо за пинок в нужном направлении!
Вопрос: а может ли кто рассказать, ПОЧЕМУ в приведенном мной коде все вставало в ступор? Почему вывод на lcd в прерывании не отработал?
to wdrakula: спасибо за указание направления! А почему приведенные библиотеки - мусор?
to wdrakula: спасибо за указание направления! А почему приведенные библиотеки - мусор?
Преобразования в "time.h" проще делать руками. А обращение к hour(), min() и прочее, скрывает обращение к часам КАЖДЫЙ РАЗ.
Я с этими часами вообще без библиотек работаю, но Вам - совет: посмотрите что-то нибудь более приличное. Один раз запросить время в структуру, а потом из нее преобразовывать. Таких библиотек много.
Но еще лучше - преобразовывать руками, так как Вам нужно, не тратя память на ерунду.
Всем огромное спасибо за пинок в нужном направлении!
Вопрос: а может ли кто рассказать, ПОЧЕМУ в приведенном мной коде все вставало в ступор? Почему вывод на lcd в прерывании не отработал?
вы прерывание сделали 1000 раз в секунду, а не один! и за 1 мс оно не успевало выполниться. и накладывалось само-на-себя.
Вы б вообще поаккуратнее с прерываниями. Вот не нужны они новичкам. Есть millis() и micros() - вот и отмеряйте себе время.
Просто создаете поток вопросов, однотипных и предсказуемых. А отвечать просите специалистов. А мы - люди злые и невоспитанные, по большей части.
Наверно в прерывании все остальные прерывания запрещены и тайминги протокола общения с LCD не работали?
Наверно в прерывании все остальные прерывания запрещены и тайминги протокола общения с LCD не работали?
Это - в первую очередь. А если прерывания разрешить - то всанет вопрос нереентерабельности.
Не нужны прерывания новичкам. Не пользуйтесь delay() и никакие прерывания вам не будут нужны в коде.
:) еще раз спасибо за пояснения