Доброго времени суток. Подключил модуль DS 3231 к Arduino Uno. При включении монитора порта выдает такое сообщение:"45:165:85 165/165/165 Day of week: ". Пробовал различные библиотеки, но результат практически одинаковый. Отсюда вопрос, что не так в коде программы, или что нужно переписать? Заранее спасибо. Сам скетч: #include "Wire.h" #define DS3231_I2C_ADDRESS 0x68 // Convert normal decimal numbers to binary coded decimal byte decToBcd(byte val) { return( (val/10*16) + (val%10) ); } // Convert binary coded decimal to normal decimal numbers byte bcdToDec(byte val) { return( (val/16*10) + (val%16) ); } void setup() { Wire.begin(); Serial.begin(9600); // set the initial time here: // DS3231 seconds, minutes, hours, day, date, month, year // setDS3231time(30,42,21,4,26,11,14); } void setDS3231time(byte second, byte minute, byte hour, byte dayOfWeek, byte dayOfMonth, byte month, byte year) { // sets time and date data to DS3231 Wire.beginTransmission(DS3231_I2C_ADDRESS); Wire.write(0); // set next input to start at the seconds register Wire.write(decToBcd(second)); // set seconds Wire.write(decToBcd(minute)); // set minutes Wire.write(decToBcd(hour)); // set hours Wire.write(decToBcd(dayOfWeek)); // set day of week (1=Sunday, 7=Saturday) Wire.write(decToBcd(dayOfMonth)); // set date (1 to 31) Wire.write(decToBcd(month)); // set month Wire.write(decToBcd(year)); // set year (0 to 99) Wire.endTransmission(); } void readDS3231time(byte *second, byte *minute, byte *hour, byte *dayOfWeek, byte *dayOfMonth, byte *month, byte *year) { Wire.beginTransmission(DS3231_I2C_ADDRESS); Wire.write(0); // set DS3231 register pointer to 00h Wire.endTransmission(); Wire.requestFrom(DS3231_I2C_ADDRESS, 7); // request seven bytes of data from DS3231 starting from register 00h *second = bcdToDec(Wire.read() & 0x7f); *minute = bcdToDec(Wire.read()); *hour = bcdToDec(Wire.read() & 0x3f); *dayOfWeek = bcdToDec(Wire.read()); *dayOfMonth = bcdToDec(Wire.read()); *month = bcdToDec(Wire.read()); *year = bcdToDec(Wire.read()); } void displayTime() { byte second, minute, hour, dayOfWeek, dayOfMonth, month, year; // retrieve data from DS3231 readDS3231time(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year); // send it to the serial monitor Serial.print(hour, DEC); // convert the byte variable to a decimal number when displayed Serial.print(":"); if (minute<10) { Serial.print("0"); } Serial.print(minute, DEC); Serial.print(":"); if (second<10) { Serial.print("0"); } Serial.print(second, DEC); Serial.print(" "); Serial.print(dayOfMonth, DEC); Serial.print("/"); Serial.print(month, DEC); Serial.print("/"); Serial.print(year, DEC); Serial.print(" Day of week: "); switch(dayOfWeek){ case 1: Serial.println("Sunday"); break; case 2: Serial.println("Monday"); break; case 3: Serial.println("Tuesday"); break; case 4: Serial.println("Wednesday"); break; case 5: Serial.println("Thursday"); break; case 6: Serial.println("Friday"); break; case 7: Serial.println("Saturday"); break; } } void loop() { displayTime(); // display the real-time clock data on the Serial Monitor, delay(1000); // every second }
Посмотрел, вроде нет в библиотеки описания. Прикрепил библиотеку которую использую.Может вы подскажите что нужно настроить.
Батенька, да Вы, наверное, не умеете пользоваться библиотеками. Зачем копировать содержимое методов библиотек в основной код? Пользовался я этой библиотекой, работает. Но нарыл другую, которая мне понравилась больше. Для вывода в Serial, файл, на LCD-экран она сразу формирует строки. Для использования значений времени в коде для алгоритмов используется вывод данных в экземпляр класса "Time". Мне не хватало индивидуального задания часов, минут и секунд, поэтому библиотеку модифицировал под себя. Мод во вложении. В библиотеке есть примеры. Если убрать все комментарии, то вывод в Serial может быть таким: Код (Text): #include <DS3231.h> DS3231 rtc(SDA, SCL); void setup() { Serial.begin(115200); rtc.begin(); } void loop() { // Send Day-of-Week Serial.print(rtc.getDOWStr()); Serial.print(" "); // Send date Serial.print(rtc.getDateStr()); Serial.print(" -- "); // Send time Serial.println(rtc.getTimeStr()); delay (1000); } Для работы со значением времени в алгоритмах Код (Text): #include <DS3231.h> DS3231 rtc(SDA, SCL); Time RTC_T; void setup() { rtc.begin(); } void loop() { RTC_T = rtc.getTime(); // if (RTC_T.hour == 0 && RTC_T.min == 0) bla-bla-bla delay (1000); } Вечером могу выложить код под эти часы с установкой времени по времени компиляции
Библиотеку в предыдущем посту обновил, добавил возможность синхронизации часов по времени компиляции (__TIME__, __DATE__). Этот код можно использовать в качестве стандартного решения для DS3231. Код (Text): #include <DS3231.h> #include <EEPROM.h> //Массив, содержащий время компиляции char compileTime[] = __TIME__; char compileDate[] = __DATE__; DS3231 Clock(SDA, SCL); Time RTC_Time; void setup() { Serial.begin(115200); Clock.begin(); //Получаем число из строки, зная номер первого символа byte hour = getInt(compileTime, 0); byte minute = getInt(compileTime, 3); byte second = getInt(compileTime, 6); unsigned int hash = hour * 60 * 60 + minute * 60 + second; if (EEPROMReadInt(0) != hash) { //Сохраняем новый хэш EEPROMWriteInt(0, hash); // Записываем время в часы Clock.adjust(compileDate, compileTime); } } void loop() { //Для запроса времени в структуру "Time" //RTC_Time = Clock.getTime(); //Вывод дня недели //Serial.print(Clock.getDOWStr()); //Serial.print(" "); //Вывод даты //Serial.print(Clock.getDateStr()); //Serial.print(" -- "); //Вывод времени. //Serial.println(Clock.getTimeStr()); delay(1000); } char getInt(const char* string, int startIndex) { return int(string[startIndex] - '0') * 10 + int(string[startIndex+1]) - '0'; } //Запись двухбайтового числа в память void EEPROMWriteInt(int address, int value) { EEPROM.write(address, lowByte(value)); EEPROM.write(address + 1, highByte(value)); } //Чтение числа из памяти unsigned int EEPROMReadInt(int address) { byte lowByte = EEPROM.read(address); byte highByte = EEPROM.read(address + 1); return (highByte << 8) | lowByte; } Методы .getDOWStr, .getTimeStr(), .getTimeStr() имеют необязательные параметры, которые отвечают за формат выводимой строки. Читайте DS3231.pdf в архиве библиотеки.
Спасибо большое, буду разбираться. Просто я начинающий пользователь данных железок. На той недели попали в руки эти платы, заинтересовался... стал разбираться.СПС!
Перепробовал почти все библиотеки, которые удалось скачать, а так же различные настройки.....долго мучился, а проблема оказалась в производственном браке (фото прикладываю). Попросил на время другую Arduino и все заработало. Подключил дисплей LCD 16x2 выводит время, дату, температуру на LCD в Цельсия.Прикрепляю скетч и библиотеку, которую использую. Если брать пример Set Serial из библиотеки, то в монитор порта исправно выдается температура с интервалом в минуту. [/quote]
Ребят, а я вот что то все никак не пойму, как по наступлению на часах нужного времени, заставить сработать другой датчик?
Я так думаю, что нужно с определенным интервалом опрашивать часы и при наступлении нужного времени выполнять действие
А что вас остановило от того, чтобы вынуть чип и выпрямить ногу? Запросить время у модуля, сравнить с требуемым значением, если совпало- исполнить. Следует учесть, то, что проверять нужно чаще чем может измениться младший разряд, ну например раз в секунду для точности до минут будет более чем достаточно, если же речь идет не о будильнике, можно и раз в десять секунд, от задачи зависит и загруженности МК.
Просто идея на скорую руку. Библиотека RTC.h int H; //Установленное время часы int M;//Установленное время минуты int tmp_h; int tmp_m; tmp_h = time.Hours; tmp_m = time.minutes; if (tmp_h==H && tmp_m==M) { // ваша функция }
Я вот так понял Библиотека RTC.h int H; //Установленное время часы int M;//Установленное время минуты int S;//Установленное время секунды int tmp_h; int tmp_m; int tmp_s; tmp_h = time.Hours; tmp_m = time.minutes; tmp_s = time.second; //Мотор if (tmp_h==H && tmp_m==M && tmp_s==S) { digitalWrite(led, HIGH); else { digitalWrite(led, LOW); } } //Свет if (tmp_h==H && tmp_m==M && tmp_s==S) { digitalWrite(led, HIGH); else { digitalWrite(led, LOW); } } //Кулер if (tmp_h==H && tmp_m==M && tmp_s==S) { digitalWrite(led, HIGH); else { digitalWrite(led, LOW); } }
Тогда вот еще - как заставить Мотор отработать 10 секунд, и выключится? А Свет заставить проработать 9 часов и выключиться? //Мотор if (tmp_h==12 && tmp_m==15 && tmp_s==05) { digitalWrite(led, HIGH); else (tmp_h==12 && tmp_m==15 && tmp_s==15) { digitalWrite(led, LOW); } } //Свет if (tmp_h==12 && tmp_m==00 && tmp_s==00) { digitalWrite(led, HIGH); else (tmp_h==21 && tmp_m==00 && tmp_s==00) { digitalWrite(led, LOW); } } Таким кодом?
Трудности начнутся при переходе через сутки, если отработаете код для корректного перехода через сутки, увидите, что нужно отрабатывать переход через месяц и т.д. Меня эксперименты с таймерами привели вот к этой библиотеке: http://playground.arduino.cc/Code/Time Её удобно использовать в дополнение к библиотекам обеспечивающим взаимодействие с микросхемой таймера. В ней определены типы данных time_t и tm и процедуры, которые преобразуют их друг в друга. time_t - время в секундах от 01 января 1970 г. (страндарт де-факто для храненения времени в языке С) tm - структура, поля которой - части времени в привычном и удобном для ввода/вывода виде (год, месяц, число, час, минута, секунда). Время полученное с таймера переводим в time_t, таймеры храним тоже в time_t. Тогда проверка наступления времени - одна простая операция сравнения, без логических операций "И" и "ИЛИ". Установка таймера тоже тривиальна: - либо прибавляем требуемое количество секунд к текущему вермени Код (C++): alarm_time = current_time + 9 * 60 * 60; //таймер на 9 часов от текущего момента - либо формируем структуру tm соответсвующую требуемому моменту срабоатывания будильника и переводим её в time_t Код (C++): tmp.Second = 0; tmp.Minute = 0; tmp.Hour = 7; tmp.Day = 8; tmp.Month =3; tmp.Year = 2016-1970; alarm_time = makeTime(tmp); // установили таймер на 07 часов утра восьмого марта текущего года
А можно по подробней про трудности, часовые модули тем и хороши, что выдают текущие время. Пока я вижу трудность в том, если время активации устройства пришлось как раз на 00:00, тогда да,будет пилить еще час. Тут следует добавить проверку времени а еще... Time.h и стандартный счетчик времени Но в принципе можно вполне обходиться и без, но что то не слишком сложное, но опять же програмные таймеры и прочие. Если по простому то можно так Для мотора, если он включается в <49 сек, то как то так if(tmp_h==12 && tmp_m==15 && tmp_s==05) { while(time.second < tmp_s+10) {//motor run} //motor stop А для света просто задать два времени и использовать запись типа if((tmp_h==12 && tmp_m==15 && tmp_s==05) || (tmp_h==20 && tmp_m==15 && tmp_s==05)) { digitalWrite(_powerPin, !digitalRead(_powerPin)); } Такая команда просто изменяет состояние указанного пина
Доброго дня. Если не сложно помогите разобраться : имеется ds3231 + mega + lcd16x2 все по i2c. Заработала только с библиотекой DS3232RTC-master.zip. При перезапуске сбивается системно время. Менял батарейки 2 раза (правда не замерил напряжение на них, нужно сделать). В процедуре сетапа естественно при последующем запуске использую функцию RTC.set(now()) -чтение установленного системного времени. Первый запуск: void setup() { setTime(17, 35, 30, 28, 12, 2015);//выставляем текущее время //RTC.set(now()); } Последующий перезапуск void setup() { //setTime(17, 35, 30, 28, 12, 2015);//выставляем текущее время RTC.set(now()); }
Попробуйте сделать такую вещь, не устанавливать время в сетапе, а по нажатию кнопки в отдельной функции. Затем, вставив его один раз, сможете пронаблюдать, не сбиваетсяли время при отключении. Как один из вариантов, если включить ваши часы от другого источника питания, либо неверно выбран порт в IDE будет неоткуда взять время для установки.