DS3231 настройка часов
- Войдите на сайт для отправки комментариев
Пт, 10/06/2016 - 11:58
Привет всем полдня убился не могу устоновить время...
библиотека https://github.com/rodan/ds3231
Привет всем полдня убился не могу устоновить время...
библиотека https://github.com/rodan/ds3231
И? Ваш код где?
Привет всем полдня убился не могу устоновить время...
Если не принципиально какой библиотекой пользоваться, посмотрите эту.
Приветствую всех! Да простит меня топикстартер, что в его тему влезу, но проблема тоже с часами DS3231. Думаю многим начинающим будет полезно, если здесь подскажут ответ.
Я также занялся Дуиной недавно и наигравшись со стандартными примерами и чужими скетчами решил пустить ее в дело. Решил собрать метеостанцию с часами и датчиками ВМР280 и DHT22 с выводом данных на 2004. Вопрос в седующем: после загрузки скетча и установки часов через СОМ-порт, что-то в скетче влияет на точность хода часов. Не знаю где проблема. Укажите пожалуйста на ошибку в скетче, и как ее исправить...
После установки времени я ещё закомментировал строки 31,42,43,а то был сдвиг на пол секунды назад при каждом подключении к компу.
Можно пояснить, какую функцию выполняют вышеуказанные строки, чтобы я уже знал на будущее и не делал подобных ошибок. Может они там совсем не нужны?
Самому разобраться в описании библиотеки к DS3231 не получится - не дружу с аглицким языком.
П.С. и есть ли способ устанавливать время, скажем в реальном времени, через СОМ-порт? Так чтобы ввел в строке "отправить" дату и время и в момент обнуления секунд нажать ENTER. Библиотек много есть на модуль часов, но не пойму как там устанавливать время (в примерах).
И еще один глюк - после сброса питания или нажатия RESET на Дуине, время не корректируется, а начинает идти с того момента как последний раз заливал скетч. Т.е. загрузил я скетч в 11:00. Через 10 минут нажимаю резет и на часах снова время 11:00 и считает секунды с 00.
Так стояли раскоммнетированными эти строки, а уважаемый letyagin посоветовал их убрать после установки времени...
Вот видео, на нем видно пропуски секунд...
http://radikal.ru/video/5i7EXflOi4
Можно пояснить, какую функцию выполняют вышеуказанные строки, чтобы я уже знал на будущее и не делал подобных ошибок. Может они там совсем не нужны?
Самому разобраться в описании библиотеки к DS3231 не получится - не дружу с аглицким языком.
П.С. и есть ли способ устанавливать время, скажем в реальном времени, через СОМ-порт? Так чтобы ввел в строке "отправить" дату и время и в момент обнуления секунд нажать ENTER. Библиотек много есть на модуль часов, но не пойму как там устанавливать время (в примерах).
И еще один глюк - после сброса питания или нажатия RESET на Дуине, время не корректируется, а начинает идти с того момента как последний раз заливал скетч. Т.е. загрузил я скетч в 11:00. Через 10 минут нажимаю резет и на часах снова время 11:00 и считает секунды с 00.
Зачем использовать в коде библиотеки для DS1307 если есть более корректные и более функциональные для DS3231. Вот я из примера переделал скетч под себя, где выводится и температура:
[code]
#include <Wire.h>
#include "ds3231.h"
#include <LiquidCrystal.h>
LiquidCrystal lcd(2,3,4,5,6,7);
#define BUFF_MAX 128
uint8_t time[8];
char recv[BUFF_MAX];
unsigned int recv_size = 0;
unsigned long prev, interval = 1000;
void setup()
{
//Serial.begin(9600);
Wire.begin();
DS3231_init(DS3231_INTCN);
memset(recv, 0, BUFF_MAX);
//Serial.println("GET time");
lcd.begin(16, 2);
lcd.clear();
//Serial.println("Setting time");
//parse_cmd("T005811613062016",16); // здесь установка времени и даты
}
void loop()
{
char in;
char tempF[6];
float temperature;
char buff[BUFF_MAX];
unsigned long now = millis();
struct ts t;
// show time once in a while
if ((now - prev > interval) && (Serial.available() <= 0)) {
DS3231_get(&t); //Get time
parse_cmd("C",1);
temperature = DS3231_get_treg(); //Get temperature
dtostrf(temperature, 5, 1, tempF);
lcd.clear();
lcd.setCursor(1,0);
lcd.print(t.mday);
printMonth(t.mon);
lcd.print(t.year);
lcd.setCursor(0,1); //Go to second line of the LCD Screen
lcd.print(t.hour);
lcd.print(":");
if(t.min<10)
{
lcd.print("0");
}
lcd.print(t.min);
lcd.print(":");
if(t.sec<10)
{
lcd.print("0");
}
lcd.print(t.sec);
lcd.print(' ');
lcd.print(tempF);
lcd.print((char)223);
lcd.print("C ");
prev = now;
}
if (Serial.available() > 0) {
in = Serial.read();
if ((in == 10 || in == 13) && (recv_size > 0)) {
parse_cmd(recv, recv_size);
recv_size = 0;
recv[0] = 0;
} else if (in < 48 || in > 122){; // ignore ~[0-9A-Za-z]
}
else if (recv_size > BUFF_MAX - 2) { // drop lines that are too long
// drop
recv_size = 0;
recv[0] = 0;
}
else if (recv_size < BUFF_MAX - 2) {
recv[recv_size] = in;
recv[recv_size + 1] = 0;
recv_size += 1;
}
}
}
void parse_cmd(char *cmd, int cmdsize)
{
uint8_t i;
uint8_t reg_val;
char buff[BUFF_MAX];
struct ts t;
//snprintf(buff, BUFF_MAX, "cmd was '%s' %d\n", cmd, cmdsize);
//Serial.print(buff);
// TssmmhhWDDMMYYYY aka set time
if (cmd[0] == 84 && cmdsize == 16) {
//T355720619112011
t.sec = inp2toi(cmd, 1);
t.min = inp2toi(cmd, 3);
t.hour = inp2toi(cmd, 5);
t.wday = inp2toi(cmd, 7);
t.mday = inp2toi(cmd, 8);
t.mon = inp2toi(cmd, 10);
t.year = inp2toi(cmd, 12) * 100 + inp2toi(cmd, 14);
DS3231_set(t);
Serial.println("OK");
}
else if (cmd[0] == 49 && cmdsize == 1) { // "1" get alarm 1
DS3231_get_a1(&buff[0], 59);
Serial.println(buff);
}
else if (cmd[0] == 50 && cmdsize == 1) { // "2" get alarm 1
DS3231_get_a2(&buff[0], 59);
Serial.println(buff);
}
else if (cmd[0] == 51 && cmdsize == 1) { // "3" get aging register
Serial.print("aging reg is ");
Serial.println(DS3231_get_aging(), DEC);
}
else if (cmd[0] == 65 && cmdsize == 9) { // "A" set alarm 1
DS3231_set_creg(DS3231_INTCN | DS3231_A1IE);
//ASSMMHHDD
for (i = 0; i < 4; i++) {
time[i] = (cmd[2 * i + 1] - 48) * 10 + cmd[2 * i + 2] - 48; // ss, mm, hh, d
}
byte flags[5] = { 0, 0, 0, 0, 0 };
DS3231_set_a1(time[0], time[1], time[2], time[3], flags);
DS3231_get_a1(&buff[0], 59);
Serial.println(buff);
}
else if (cmd[0] == 66 && cmdsize == 7) { // "B" Set Alarm 2
DS3231_set_creg(DS3231_INTCN | DS3231_A2IE);
//BMMHHDD
for (i = 0; i < 4; i++) {
time[i] = (cmd[2 * i + 1] - 48) * 10 + cmd[2 * i + 2] - 48; // mm, hh, dd
}
byte flags[5] = { 0, 0, 0, 0 };
DS3231_set_a2(time[0], time[1], time[2], flags);
DS3231_get_a2(&buff[0], 59);
Serial.println(buff);
}
else if (cmd[0] == 67 && cmdsize == 1) { // "C" - get temperature register
Serial.print("temperature reg is ");
Serial.println(DS3231_get_treg(), DEC);
}
else if (cmd[0] == 68 && cmdsize == 1) { // "D" - reset status register alarm flags
reg_val = DS3231_get_sreg();
reg_val &= B11111100;
DS3231_set_sreg(reg_val);
}
else if (cmd[0] == 70 && cmdsize == 1) { // "F" - custom fct
reg_val = DS3231_get_addr(0x5);
Serial.print("orig ");
Serial.print(reg_val,DEC);
Serial.print("month is ");
Serial.println(bcdtodec(reg_val & 0x1F),DEC);
}
else if (cmd[0] == 71 && cmdsize == 1) { // "G" - set aging status register
DS3231_set_aging(0);
}
else if (cmd[0] == 83 && cmdsize == 1) { // "S" - get status register
Serial.print("status reg is ");
Serial.println(DS3231_get_sreg(), DEC);
}
else
{
Serial.print("unknown command prefix ");
Serial.println(cmd[0]);
Serial.println(cmd[0], DEC);
}
}
void printMonth(int month)
{
switch(month)
{
case 1: lcd.print(" January ");break;
case 2: lcd.print(" February ");break;
case 3: lcd.print(" March ");break;
case 4: lcd.print(" April ");break;
case 5: lcd.print(" May ");break;
case 6: lcd.print(" June ");break;
case 7: lcd.print(" July ");break;
case 8: lcd.print(" August ");break;
case 9: lcd.print(" September ");break;
case 10: lcd.print(" October ");break;
case 11: lcd.print(" November ");break;
case 12: lcd.print(" December ");break;
default: lcd.print(" Error ");break;
}
}
[/code]
При выключении питания ничего не сбрасывается и не сбивается . Можно было еще сократить объем скетча, убрав вывод на монитор. Но для меня это было не важно.
датчики тепмературы нужно обновлять раз в 2 сек, но так как это в Вашем скетче тормозит программу delay(2000) нужно убрать, и написать через millis(), посмотрите пример blink без delay и сделайте вместо blink обновление датчиков температуры...
этот комент к скетчу Петровича
Температура с модуля часов?
А с пропусками секунд, как на видео, что делать, или это нормальное явление?
сейчас Вам скетч поправлю...
сейчас Вам скетч поправлю...
Пожалуйста, если не сложно и с заменой библиотеки DS1307 на DS3231 (без вывода температуры с модуля часов)
Температура с модуля часов?
А с пропусками секунд, как на видео, что делать, или это нормальное явление?
Да с модуля часов. Представте себе этот модуль имеет термодатчик. Я сравнивал с ВМЕ280 показания не отличаются.
Да с модуля часов. Представте себе этот модуль имеет термодатчик. Я сравнивал с ВМЕ280 показания не отличаются.
Да, я знаю о том, что датчик там есть, но не особо надеялся на его точность...
Да с модуля часов. Представте себе этот модуль имеет термодатчик. Я сравнивал с ВМЕ280 показания не отличаются.
Да, я знаю о том, что датчик там есть, но не особо надеялся на его точность...
В скетче, приведенном више температура выводитя с точностью 0.1 .
попробуйте так
Вообще - разумно. Можно сэкономить на комнатном датчике, пусть из часов берет температуру... Посмотрю потом Ваш скетч, возьму себе на вооружение данную функию.
Mr.Privet спасибо за помощь, сейчас попробую.
Попробовал - ругается. Я так понимаю не видит данных t и h с DHT.
Обращаюсь к Genry5. Скомпилировал Ваш код с выводом температуры с DS3231, переделав в нем подключение дисплея по I2C. Показывает дату и время, но вторая строка мерцает при смене показаний секунд, как-будто происходит полная инициализация и очистка дисплея. Но первая строка с датой остается статичной. Это особенность подключения по I2C или и при обычном подключении такое происходит?
У меня их несколько искал на github-е библиотеки : https://github.com/rodan/ds3231
:https://github.com/jarzebski/Arduino-DS3231
Во второй целый набор для всех нужд
У меня их несколько искал на github-е библиотеки : https://github.com/rodan/ds3231
:https://github.com/jarzebski/Arduino-DS3231
Во второй целый набор для всех нужд
Спасибо, скачал.
Еще замечено из багов - в Вашем скетче выводятся показания даты в первой строке 16 June 1916, а в СОМ порт нормально отображается 2016 год
Нужно разкоментировать строку где подписано "установка времени и даты" установить текущее время и дату, прошить. Потом можно обратно закоментировать. Что бы не влияло при последуующих прошивках.
Понял, сейчас сделаю. Только поподробнее про данный процесс, если можно. Он немного отличается от того. которым я пользовался изначально, поэтому пока не ясно как это реализовать.
Попробовал - ругается. Я так понимаю не видит данных t и h с DHT.
Ругается потому, что переменные t и h будут объявлены только спустя две секунды после запуска программы.
Если Вы никак не используете выход SQW модуля часов, то следующие строки можно убрать:
В следующем фпагменте:
Переменным Pressure, Altitude и temp3 - значения присваиваются, но сами переменные нигде больше не используются. Это какая-то особенность работы с этими датчиками?
Насколько я понимаю, эти переменные дальше используются при печати на экран: lcd.print((bme.readPressure()/ 133.3, 1); и так с остальными переменными. Или я не правильно думаю?
В строк в скетче: //Serial.println("Setting time");
//parse_cmd("T005811613062016",16); // здесь установка времени и даты
убираете // и получается : parse_cmd("T005811613062016",16); // здесь установка времени и даты
Затем в скобках ставите текущие дату и время с право на лево - год_месяц_число_часы_минуты_секунды.
Да, не мало важно, для того, что бы датчик температуры не врал, то на модуле стоит светодиод - источник тепла. :-)
Все, с коррекцией даты и времени разобрался, немного не удобно, нужно высчитывать сколько длится загрузка скетча и за столько секунд начинать ее, чтобы к моменту обнуления секунд скетч был загружен. Нельзя использовать для этого СОМ порт? Скажем, ввести в строку для отправки в порт все эти данные и при нажатии кн. "Отправить", чтобы они моментально оказывались в памяти модуля.
Со светодиодом я знаю эту проблемку, потом его удалю вместе с его резистором.
Да, сорее всего есть, даже синхронизация времени с компом, но я не разбирался.
Тогда спасибо за терпение, разжевали "Арду-чайнику". Начал понимать по-чуть. Буду дальше изучать и раскладывать приведенные примеры по "косточкам", чтобы уже иметь понимание при написании исходников, в будущем. Будут вопросы буду задавать в других темах, так что не ругайте за назойливость...
Вот скейч, который синхронизирует через комп:
[code]
#include <DS3232RTC.h>
#include <Time.h>
#include <Wire.h>
#include <LiquidCrystal.h>
LiquidCrystal lcd(2,3,4,5,6,7);
void setup(void)
{
Serial.begin(9600);
setSyncProvider(RTC.get); // the function to get the time from the RTC
if(timeStatus() != timeSet)
Serial.println("Unable to sync with the RTC");
else
Serial.println("RTC has set the system time");
lcd.begin(16, 2);
lcd.clear();
}
void loop(void)
{
digitalClockDisplay();
delay(1000);
}
void digitalClockDisplay(void)
{
// digital clock display of the time
lcd.clear();
lcd.print(hour());
printDigits(minute());
printDigits(second());
lcd.print(' ');
lcd.print(day());
lcd.print(' ');
lcd.print(month());
lcd.print(' ');
lcd.setCursor(0, 1);
lcd.print(year());
}
void printDigits(int digits)
{
// utility function for digital clock display: prints preceding colon and leading 0
lcd.print(':');
if(digits < 10)
lcd.print('0');
lcd.print(digits);
}
[/code]
Можно сначало залить его. Он установит дату и время, а потом свой без установки. :-)
Чудесно, то что нужно было. Без всяких танцев с бубном!!! Спасибо! :-)
П.С. Как-раз и топикстартеру ответ на его первое сообщение...