Ардуино и DS3231 не корректируется время
- Войдите на сайт для отправки комментариев
Пнд, 02/04/2018 - 21:37
Уважаемые специалисты! Прошу помощи. Собрал из различных источников многофункциональное устройство с двумя будильниками и таймером с возможность переключения выходов и настройкой ШИМ (последнее пока не доделано). Почему-то не хочет записывать корректировку даты и времени. Будильники и таймер работают нормально. Из примера другой библиотеки часы настраиваются. Не знаю как присоединить файлы библиотеки и скетч. Библиотека DS3231.
Скетч:
#include <avr/io.h>
#include <avr/eeprom.h>
#include <avr/sleep.h>
#include <Wire.h>
#include <IRremote.h> // Здесь задействован 2-й таймер
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x3F, 16, 2); //0x3F - адрес LCD
// С этой библиотекой установка даты и времени почему-то не происходит!!!!!!!
#include <DS3231.h> // 0x68 - адрес часов
DS3231 clock; // 0х57 - адрес EEPROM в часах
RTCDateTime dt;
RTCAlarmTime a1;
RTCAlarmTime a2;
decode_results results;
const uint8_t RECV_PIN = 10; // PB0 PCINT0
IRrecv irrecv(RECV_PIN);
/*
#define chip1 0x50 // Адрес внешнего EEPROM
unsigned int pointer;
byte d=0;
*/
//const uint8_t SQW_INT =2;
//#define ON_SQW clock.setOutput(1)
//#define OFF_SQW clock.setOutput(0)
const uint8_t alarmLED = 13; // PB5 SCK
const uint8_t alarmPWM = 8; // выход PWM PB1 OC1A
const uint8_t PinBuzzer = 9; // PB2
const uint8_t LED = 13;
volatile boolean alarm_on = false; // Статус 1-го будильника
volatile boolean alarm_on1 = false; // Статус 2-го будильника
volatile boolean alarm_on2 = false; // Статус таймера
const uint8_t addr_al2 = 0; // ячейка EEPROM состояние таймера вкл/выкл
const uint8_t addr_ah2 = 1; // ячейка EEPROM часы в таймере
const uint8_t addr_am2 = 2; // ячейка EEPROM минуты в таймере
const uint8_t addr_ahout2 = 3; // ячейка EEPROM часы в таймере для обратного отсчета
const uint8_t addr_amout2 = 4; // ячейка EEPROM минуты в таймере для обратного отсчета
const uint8_t addr_q = 5; // ячейка EEPROM скважность
const uint16_t addr_f = 6; // ячейка EEPROM частота
volatile int8_t var_q = 0; // переменная скважности
volatile int16_t var_f = 0; // переменная частоты старшие разряды
volatile int8_t ah = 0;
volatile int8_t am = 0;
volatile uint8_t regim = 0; // переменная для переходов при настройках
volatile uint8_t pmenu = 9; // меню: в меню пункта 9 не должно быть
volatile uint8_t blinkCursor = 0;
long button = 0;
const long bmenu = 10039503; //menu для просмотра кодов кнопок при выкл таймере pmenu=55
const long balarm1 = 10063983; // <1> 1-й будильник pmenu=6
const long balarm2 = 10074183; // <2> 2-й будильник pmenu=7
const long btimer = 10090503; // <3> таймер pmenu=0
const long btime = 10072143; // <4> корректировка часов pmenu=3
const long bPWM = 10066023; // <5> Регулировка скважности pmenu=10
const long bF = 10082343; // <6> Регулировка частоты pmenu=12
const long bout_t = 10061943; // <7> Выбор выхода по таймеру pmenu=13
const long bout_a1 = 10070103; // <8> Выбор выхода по 1-му будильнику pmenu=14
const long bout_a2 = 10086423; // <9> Выбор выхода по 2-му будильнику pmenu=15
const long bout_PWM = 10053783; // <+10> Выбор выхода PWM pmenu=11
const long bright = 10091013; // <RIGHT> pmenu=8
const long bleft = 10058373; // <LEFT> pmenu=8
const long bplus = 10042053; // <UP> Прибавляем значения pmenu=1
const long bminus = 10074693; // <DOWN> Уменьшаем значения pmenu=2
const long bcancel = 10084383; // <ESC> Top menu pmenu=4
const long bselect = 10037463; // OK pmenu=5
//const long bset = 10072653; //SETUP
//10045623 - 10/0
//10047663 - return
//10027773 -card/usb
//10056333-OSD, 10054293-SUBTITLE, 10078773-O)), 10037973-камера это 4 верхних кнопки
//10057863-влево, 10082853-вправо большая нижняя кнопка, 10033383-AUDIO MODE, 10080303-DIGEST
volatile int8_t th, tm, da, mo, se;
uint16_t ye;
uint8_t bell[8] = {0x4, 0xe, 0xe, 0xe, 0x1f, 0x0, 0x4}; //колокольчик
uint8_t temp_cel[8] = {B00111, B00101, B00111, B00000, B00000, B00000, B00000}; // Градус
// Переменные для генератора с регулировкой частоты и скважности
volatile uint8_t duty=50;
#define set_duty() {OCR1A=(uint16_t)ICR1*duty/100;}
//--------------------------------------------------------------------------
//Предопределение функций
void blink_temp_rh(unsigned long interval); // Основной экран, переключаемый на таймер
void SET_A1();
void SET_outA1();
void SET_A2();
void SET_outA2();
void SET_T();
void SET_outT();
void SET_outPWM(); // На каком выходе будет PWM
void SET_PWM(); // Регулировка скважности
void SET_F(); // Регулировка частоты PWM
void blink_set_time (unsigned long interval); //мигаем переменной настройки часов
void SET_Timer();
void blink_set_timer (unsigned long interval); //мигаем переменной настройки таймера
void Timer_off();
void Timer_on();
void blink_alarm_on(unsigned long interval);
void blink_alarm_off(unsigned long interval);
void blink_set_alarm (unsigned long interval, uint8_t nom); //мигаем переменной включаем будильник
void dump(decode_results *results); // Дешифрация нажатых ИК-кнопок
void buttons(); // Обработка кнопок
void myTone(uint32_t i){
i+=(millis());
while(i>millis()){
digitalWrite(PinBuzzer, HIGH);
delayMicroseconds(500);
digitalWrite(PinBuzzer, LOW);
delayMicroseconds(300);
}
}
void SET_freq(); // Изменение частоты генератора
void SET_duty(); // Изменение скважности генератора
void blink_set_qf (unsigned long interval, uint16_t qf);
/* Делал для внешнего EEPROM, но пка не работает
byte decToBcd(byte val) //Преобразует обычное десятичное число в двоично-десятичное
{
return( (val/10*16) + (val%10) );
}
byte bcdToDec(byte val) //Преобразует двоично-десятичное число в обычное десятичное
{
return( (val/16*10) + (val%16) );
}
void writeData(int device, unsigned int address, byte data)
// записывает байт данных 'data' в ЭСППЗУ с I2C-адресом 'device'
// в ячейку с номером 'address'
{
Wire.beginTransmission(device);
Wire.write((byte)(address >> 8)); // старший байт номера ячейки
Wire.write((byte)(address & 0xFF)); // и младший байт
Wire.write(decToBcd(data));
Wire.endTransmission();
delay(10);
}
byte readData(int device, unsigned int address)
// читает байт данных из ячейки с номером 'address'
// в ЭСППЗУ с I2C-адресом 'device'
{
byte result; // возвращаемое значение
Wire.beginTransmission(device);
Wire.write((byte)(address >> 8)); // старший байт номера ячейки
Wire.write((byte)(address & 0xFF)); // и младший байт
Wire.endTransmission();
Wire.requestFrom(device,1);
result = Wire.read();
return bcdToDec(result); // вернуть прочитанный байт как
// результат функции readData
}
*/
//==========================================================================
void setup()
{
// Serial.begin(9600);
Wire.begin();
irrecv.enableIRIn();
lcd.begin();
clock.begin();
DDRD = 0;
PORTD = 0;
DDRB |= (1<<alarmPWM) | (1<<alarmLED) | (1<<PinBuzzer) | (1<<LED);
PORTB = 0;
alarm_on = (clock.isAlarm1())? true: false; // Инициализaция будильников при перезагрузке
alarm_on1 = (clock.isAlarm2())? true: false;
if (eeprom_read_byte(addr_ah2) == 255) {
eeprom_update_byte(addr_ah2,0);
eeprom_update_byte(addr_am2,0);
}
/*
if (readData(chip1,addr_ah2) == 255) {
writeData(chip1,addr_ah2,0);
writeData(chip1,addr_am2,0);
}
//writeData(chip1,a,a);
//d=readData(chip1,a);
*/
lcd.createChar(0, bell); //колокольчик
lcd.createChar(1, temp_cel); //цельсии
TCCR1A=1<<COM1A1; //подключить выход OC1A первого таймера
TCCR1B=0;//
OCR1A = eeprom_read_byte(addr_q); //читаем скважность выхода для PB1 (OC1A)
ICR1 = eeprom_read_word(addr_f); //читаем частоту выхода для PB1 (OC1A)
}
//==========================================================================
void loop()
{
while(1)
{
buttons(); //Проверяем нажатия клавиш
// Здесь надо сделать проверку кодов клавиш при pmenu=55
while (regim==55){
lcd.clear();
lcd.setCursor(0,0);
if (pmenu == 4) { // Прервать настройку, ничего не менять
lcd.clear();
regim = 1;
}
}
dt = clock.getDateTime();
a1 = clock.getAlarm1();
a2 = clock.getAlarm2();
if (clock.isAlarm1())
{
myTone(1000);
alarm_on = false;
clock.armAlarm1(alarm_on);
}
if (clock.isAlarm2())
{
myTone(1000);
alarm_on1 = false;
clock.armAlarm2(alarm_on1);
}
if (pmenu == 9) {
lcd.setCursor(0, 0);
lcd.print(clock.dateFormat("H:i:s ", dt));
lcd.print(clock.readTemperature()); // Считываем температуру с DS3231
lcd.write(1);
lcd.print("C"); //цельсия lcd.setCursor(0, 1);
blink_temp_rh(2000); //показ таймера и даты (смена каждые 3 сек)
}
}
}
//==========================================================================
void SET_freq(){
uint16_t icr=ICR1;
uint16_t divider=1; //переменная коэфф. деления прескалера
static boolean gen_mode=0; //флаг режима управления частотой
regim = 2;
uint8_t i = 1;
int16_t f = eeprom_read_word (addr_f); //читаем частоту выхода для PB1 (OC1A)
while (regim==2) { //задание скважности
buttons();
blinkCursor = 1;
blink_set_qf(250, f);
if (f <= 15) i=1;
else if ((f > 10) && (f <= 50)) i=5;
else if ((f > 50) && (f <=200)) i=10;
else if ((f > 200) && (f <= 2000)) i=100;
else if ((f >2000) && (f <= 12000)) i=1000;
else i=5000;
if (pmenu == 1) f += i;
if (pmenu == 2) f -= i;
if ((f > 65535) || (f < 0)) f = 0;
if (f > 2848) gen_mode=1; //переключение режима управления по OCR
else gen_mode=0; //переключение режима управления по частоте
if ((pmenu == 5) || (pmenu == 8) || (pmenu == 4)) {
lcd.clear();
regim = 1;
}
}
if(gen_mode){
ICR1 = f;
set_duty();
}
else { //расчёт прескалера и ICR по нужной частоте
icr = (F_CPU / f /2 /divider);
byte shifts[] = {3,3,2,2};
for(byte i = 0; i < 4; i++){
if (icr > 65536) {
divider <<= shifts[i];
icr = F_CPU / f /2 /divider;
}
else { //запись в регистр прескалера
TCCR1B = (i+1)|(1<<WGM13);
break;
}
}
ICR1=icr-1;
set_duty();
} //конец "если частота менее 2848 герц)
eeprom_update_word(addr_f, ICR1);
}
//------------------------------------------------------------
void blink_set_qf (unsigned long interval, uint16_t qf){
static unsigned long prevTime=0;
if(millis() - prevTime > interval){
static boolean flag = false;
prevTime = millis();
lcd.clear();
flag = !flag;
lcd.setCursor(0,0);
// if (blinkCursor == 1)
lcd.print((blinkCursor == 1)? "Worked frequenze": "Worked sqwaiuer");
lcd.setCursor(5, 1);
if(flag){
lcd.print(qf);
}
else {
lcd.print(" ");
}
}
}
//------------------------------------------------------------
void SET_duty(){
regim = 2;
uint8_t i = 1;
int8_t q = eeprom_read_byte(addr_q); //читаем скважность выхода для PB1 (OC1A)
var_q = q;
while (regim==2) { //задание скважности
buttons();
blinkCursor = 2;
blink_set_qf(250, q);
if (q <= 10) i=1;
else if ((q > 10) && (q <= 30)) i=5;
else i=10;
if (pmenu == 1) q += i;
if (pmenu == 2) q -= i;
if ((q >= 100) || (q < 0)) q = 0;
if ((pmenu == 5) || (pmenu == 8)) {
if (var_q != q)
duty = q;
set_duty();
eeprom_update_byte(addr_q, OCR1A);
lcd.clear();
regim = 1;
}
if (pmenu == 4) {
lcd.clear();
regim = 1;
}
}
}
//------------------------------------------------------------
void blink_temp_rh(unsigned long interval){
static unsigned long prevTime=0;
uint8_t ah=0, am=0, ahout=0, amout=0;
uint16_t t_sec = 0, a_sec = 0;
// alarm_on2 = readData(chip1,addr_al2);
alarm_on2 = eeprom_read_byte(addr_al2); //читаем состояние Timer
// alarm_on2 = clock.EEPROM_ReadByte(addr_al2);
buttons();
switch (pmenu) {
case (0) :
SET_Timer(); // Timer
break;
case (3) : // Часы
SET_T();
break;
case (6) :
SET_A1(); // 1-й
break;
case (7) :
SET_A2(); // 2-й
break;
case (10) : // <5> Регулировка скважности
SET_duty();
break;
case (11) : // <+10> Выбор выхода PWM
pmenu = 11;
break;
case (12) : // <6> Регулировка частоты PWM
SET_freq();
break;
case (13) : // <7> Выбор выхода по таймеру
break;
case (14) : // <8> Выбор выхода по 1-му будильнику
break;
case (15) : // <9> Выбор выхода по 2-му будильнику
break;
}
if (millis() - prevTime > interval){
static boolean flag = 0;
prevTime = millis();
flag = !flag;
lcd.setCursor(0, 1);
if(flag){
lcd.print(clock.dateFormat("d-m-y l", dt));
lcd.setCursor(9,1);
if (alarm_on) lcd.write(0); // Колокольчик 1-го будильника
else lcd.print("-");
if (alarm_on1) lcd.write(0); // Колокольчик 2-го будильника
else lcd.print("-");
if (alarm_on2){
lcd.write(0); // Колокольчик таймера
lcd.print(" ");
}
else lcd.print("- ");
}
else {
lcd.print(" ");
lcd.setCursor(0, 1); // Не успевала срабатывать команда пробелов
if (alarm_on2) {
ah = eeprom_read_byte(addr_ah2);
am = eeprom_read_byte(addr_am2);
ahout = eeprom_read_byte(addr_ahout2);
amout = eeprom_read_byte(addr_amout2);
/*
ah = readData(chip1,addr_ah2);
am = readData(chip1,addr_am2);
ahout = readData(chip1,addr_ahout2);
amout = readData(chip1,addr_amout2);
*/ t_sec = (dt.hour*3600) + (dt.minute*60); // Текущее время в секундах
a_sec = (ahout*3600) + (amout*60);
ahout = (a_sec - t_sec)/3600;
amout = (((a_sec - t_sec)-(ahout*3600))/60);
if ((ahout==0) && (amout==0)) { // Проверка таймера
Timer_off();
}
if (ah<10) lcd.print("0");
lcd.print(ah);
lcd.print(":");
if (am<10) lcd.print("0");
lcd.print(am);
lcd.print("m");
lcd.print(" >>");
if (ahout<10) lcd.print("0");
lcd.print(ahout);
lcd.print(":");
if (amout<10) lcd.print("0");
lcd.print(amout);
lcd.print("<<");
}
else lcd.print("Timer not includ");
}
}
}
//------------------------------------------------------------
//----------- Работа с ИК-пультом 2 функции ниже -------------
// Здесь будем расшифровывать нажатые клавиши
void dump(decode_results *results) {
pmenu = 9;
int count = results->rawlen;
long button = results->value;
/* Для просмотра кодов кнопок раскомментировать
lcd.setCursor(0,1);
int tt = millis();
while (millis< tt+3000) lcd.print(button);
*/
if (button > 10000000) {
switch (button) {
case (balarm1) : // 1-й будильник. Используется EEPROM
pmenu = 6;
break;
case (balarm2) : // 2-ой будильник. Используется EEPROM
pmenu = 7;
break;
case (btimer) : // 3 Таймер. Используется EEPROM
pmenu = 0;
break;
case (bplus) : // Приращение переменной(UP)
pmenu = 1;
break;
case (bminus): // Уменьшение переменной(DOWN)
pmenu = 2;
break;
case (btime) : // 4 Коррект часов
pmenu = 3;
break;
case (bPWM) : // <5> Регулировка скважности
pmenu = 10;
break;
case (bout_PWM) : // <+10> Выбор выхода PWM
pmenu = 11;
break;
case (bF) : // <6> Регулировка частоты PWM
pmenu = 12;
break;
case (bout_t) : // <7> Выбор выхода по таймеру
pmenu = 13;
break;
case (bout_a1) : // <8> Выбор выхода по 1-му будильнику
pmenu = 14;
break;
case (bout_a2) : // <9> Выбор выхода по 2-му будильнику
pmenu = 15;
break;
case (bcancel): // Прерывание/Сброс(Top menu)
pmenu = 4;
break;
case (bselect): // OK
pmenu = 5;
break;
case (bright) : // RIGHT
pmenu = 8;
break;
case (bleft): // LEFT
pmenu = 8;
break;
case (bmenu) :
pmenu = 55;
regim = 55;
break;
default:
pmenu = 9;
}
}
}
//------------------------------------------------------------
void buttons() {
static unsigned long prevTime=0;
pmenu = 9;
if (irrecv.decode(&results)) {
if (millis() - prevTime > 250) { // Если прошло по крайней мере 1/4 секунды с момента нажатия
dump(&results);
}
prevTime = millis();
irrecv.resume(); // Receive the next value
}
}
//--------------------------------------------------------------------------
//----- Настройка и включение/выключение таймера 4 функции ниже
void Timer_on () {
// Включаем что-нибудь
digitalWrite(LED, 1);
// myTone(1000);
}//------------------------------------------------------------
void Timer_off() {
uint8_t ahout=0, amout=0;
uint16_t t_sec = 0, a_sec = 0;
myTone(1000);
PORTB &= !(1<<LED);
SET_Timer();
}
//------------------------------------------------------------
void SET_Timer () { // Пробуем настраивать один таймер
regim=2;
digitalWrite(LED, 0);
uint8_t ahout=0, amout=0, ahout1=0, amout1=0, ah1=0, am1=0, al1=alarm_on2;
uint16_t t_sec = 0, a_sec = 0;
lcd.clear();
lcd.setCursor(1, 0);
while (regim==2) { //включение отключение таймеров
buttons();
lcd.print("on Timer off");
// al1 = readData(chip1,addr_al2);
if ((pmenu == 1) ||(pmenu == 2)) alarm_on2 = !alarm_on2;
if (alarm_on2) blink_alarm_on(250);
else blink_alarm_off(250);
ah = eeprom_read_byte(addr_ah2);
am = eeprom_read_byte(addr_am2);
// ah = readData(chip1,addr_ah2);
// am = readData(chip1,addr_am2);
// ah1 = ah;
// am1 = am;
lcd.setCursor(5, 1);
if (ah<10) lcd.print("0");
lcd.print(ah);
lcd.print(":");
if (am<10) lcd.print("0");
lcd.print(am);
if ((pmenu == 5) || (pmenu == 8)) {
eeprom_update_byte(addr_al2, alarm_on2);
// if (al1 != alarm_on2) writeData(chip1,addr_al2,alarm_on2);
// al1 = alarm_on2;
if (alarm_on2) {
t_sec = (dt.hour*3600) + (dt.minute*60); // Текущее время в секундах
a_sec = (ah*3600) + (am*60);
ahout = (a_sec + t_sec)/3600;
amout = (((a_sec + t_sec)-(ahout*3600))/60);
eeprom_update_byte(addr_ahout2, ahout);
eeprom_update_byte(addr_amout2, amout);
// writeData(chip1,addr_ahout2,ahout);
// ahout1 = ahout;
// writeData(chip1,addr_amout2,amout);
// amout1 = amout;
if (pmenu == 5) regim++;
else {
regim = 1;
lcd.clear();
Timer_on();
}
}
else {
regim = 1;
lcd.clear();
}
}
if (pmenu == 4) {
lcd.clear();
regim = 1;
return;
}
}
while (regim==3) { //установка часов таймеров
buttons();
blinkCursor = 1;
blink_set_timer(250);
if (pmenu == 1) ah++;
if (pmenu == 2) ah--;
if (ah>23) ah=0;
if (ah<0) ah=23;
if ((pmenu == 5) || (pmenu == 8)) {
if (alarm_on2) {
eeprom_update_byte(addr_ah2, ah);
t_sec = (dt.hour*3600) + (dt.minute*60); // Текущее время в секундах
a_sec = (ah*3600) + (am*60);
ahout = (a_sec + t_sec)/3600;
amout = (((a_sec + t_sec)-(ahout*3600))/60);
eeprom_update_byte(addr_ahout2, ahout);
eeprom_update_byte(addr_amout2, amout);
/* if (ah1 != ah) writeData(chip1,addr_ah2,ah);
ah1 = ah;
if (am != am1) writeData(chip1,addr_am2,am);
am1 = am;
if (ahout != ahout1) writeData(chip1,addr_ahout2,ahout);
ahout1 = ahout;
if (amout != amout1) writeData(chip1,addr_amout2,amout);
amout1 = amout;
*/
if (pmenu == 5) regim++;
else {
regim = 1;
lcd.clear();
Timer_on();
}
}
else {
regim = 1;
lcd.clear();
}
}
if (pmenu == 4) {
lcd.clear();
regim = 1;
return;
}
}
while(regim==4){ //установка минут таймеров
buttons();
blinkCursor = 2;
blink_set_timer(250);
if (pmenu == 1) am++;
if (pmenu == 2) am--;
if (am>59) am=0;
if (am<0) am=59;
if ((pmenu == 5) || (pmenu == 8)) {
eeprom_update_byte(addr_am2, am);
t_sec = (dt.hour*3600) + (dt.minute*60); // Текущее время в секундах
a_sec = (ah*3600) + (am*60);
ahout = (a_sec + t_sec)/3600;
amout = (((a_sec + t_sec)-(ahout*3600))/60);
// eeprom_update_byte(addr_ahout2, ahout);
eeprom_update_byte(addr_amout2, amout);
/* if (am1 != am) writeData(chip1,addr_am2,am);
if (ahout1 != ahout) writeData(chip1,addr_ahout2,ahout);
if (amout1 != amout) writeData(chip1,addr_amout2,amout);
*/ regim = 1;
pmenu = 9;
Timer_on();
}
if (pmenu == 4) {
pmenu = 9;
regim = 1;
return;}
}
}
//------------------------------------------------------------
void blink_set_timer (unsigned long interval){ //мигаем переменной включаем будильник
static unsigned long prevTime=0;
if(millis() - prevTime > interval){
static boolean flag = 0;
prevTime = millis();
flag = !flag;
if(flag){
lcd.clear();
lcd.setCursor(1, 0);
lcd.print("on Timer off");
lcd.setCursor(5, 1);
if (ah<10) lcd.print("0");
lcd.print(ah);
lcd.print(":");
if (am<10) lcd.print("0");
lcd.print(am);
}
else {
switch (blinkCursor) {
case 1: lcd.setCursor(5, 1); break;
case 2: lcd.setCursor(8, 1); break;
}
lcd.print(" ");
}
}
}
//--------------------------------------------------------------------------
void SET_T(){
regim=2;
ye = dt.year;
mo = dt.month;
da = dt.day;
th = dt.hour;
tm = dt.minute;
se = dt.second;
while (regim == 2) { //установка часов
buttons();
blinkCursor = 1;
blink_set_time(250);
if (pmenu == 1) th++;
if (pmenu == 2) th--;
if (th>23) th=0;
if (th<0) th=23;
if ((pmenu == 5) || (pmenu == 8)) {
regim++;
if (pmenu == 5) clock.setDateTime(2018, 2, 25, 18, 12, se);
else regim = 1;
}
if (pmenu == 4) regim = 1;
}
while (regim == 3) { //установка минут
buttons();
blinkCursor = 2;
blink_set_time(250);
if (pmenu == 1) tm++;
if (pmenu == 2) tm--;
if (tm>59) tm=0;
if (tm<0) tm=59;
if ((pmenu == 5) || (pmenu == 8)) {
regim++;
if (pmenu == 5) clock.setDateTime(2018, 2, 25, th, tm, se);
else regim = 1;
}
if (pmenu == 4) regim = 1;
}
while (regim == 4) { //установка числа
buttons();
blinkCursor = 3;
blink_set_time(250);
if (pmenu == 1) da++;
if (pmenu == 2) da--;
if (da>31)da=1;
if (da<1)da=31;
if ((pmenu == 5) || (pmenu == 8)) {
regim++;
if (pmenu == 5) clock.setDateTime(2018, 2, da, th, tm, se);
else regim = 1;
}
if (pmenu == 4) regim = 1;
}
while (regim == 5) { //установка месяца
buttons();
blinkCursor = 4;
blink_set_time(250);
if (pmenu == 1) mo++;
if (pmenu == 2) mo--;
if (mo>12) mo=1;
if (mo<1) mo=12;
if ((pmenu == 5) || (pmenu == 8)) {
regim++;
if (pmenu == 5) clock.setDateTime(ye, mo, da, th, tm, se);
else regim = 1;
}
if (pmenu == 4) regim = 1;
}
while (regim == 6) { //установка года
buttons();
blinkCursor = 5;
blink_set_time(250);
if (pmenu == 1) ye++;
if (pmenu == 2) ye--;
if (ye>2100) ye=2018;
if (ye<2018) ye=2099;
if ((pmenu == 5) || (pmenu == 8)) {
regim=1;
if (pmenu == 5) clock.setDateTime(ye, mo, da, th, tm, se);
}
if (pmenu == 4) regim = 1;
}
}
//------------------------------------------------------------
void blink_set_time(unsigned long interval){ //мигаем переменной в установке даты и времени
static unsigned long prevTime=0;
if(millis() - prevTime > interval){
static boolean flag = 0;
prevTime = millis();
flag = !flag;
lcd.setCursor(0, 0);
if(flag){
if (th<10) lcd.print("0");
lcd.print(th); //показать врем
lcd.print(":");
if (tm<10) lcd.print("0");
lcd.print(tm);
lcd.setCursor(0, 1);
if (da<10) lcd.print("0");
lcd.print(da); //показать дату
lcd.print(".");
if (mo<10) lcd.print("0");
lcd.print(mo);
lcd.print(".");
lcd.print(ye);
lcd.print(" ");
lcd.print(clock.dateFormat("D ", dt)); // Думаю, что день недели
}
else {
switch (blinkCursor) {
case 1: lcd.setCursor(0, 0); break;
case 2: lcd.setCursor(3, 0); break;
case 3: lcd.setCursor(0, 1); break;
case 4: lcd.setCursor(3, 1); break;
case 5: lcd.setCursor(8, 1); break;
}
lcd.print(" ");
}
}
}
//--------------------------------------------------------------------------
void SET_A1 () { // Пробуем настраивать будильник1
regim=2;
lcd.clear();
lcd.setCursor(1, 0);
uint8_t da=a1.day, as=a1.second;
ah=a1.hour;
am=a1.minute;
alarm_on = (clock.isArmed1()) ? true: false;
lcd.print("on Alarm1 off");
while (regim==2) {
buttons();
if ((pmenu == 1) || (pmenu == 2)) alarm_on = !alarm_on;
// if (pmenu == 2) alarm = !alarm;
if (alarm_on) blink_alarm_on(250);
else blink_alarm_off(250);
if ((pmenu == 5) || (pmenu == 8)) { //Сохранить настройку
if (alarm_on) {
if (pmenu == 5) regim++;
else {
if (ah || am) {
clock.armAlarm1(true);
regim = 1;
lcd.clear();
}
else {
clock.armAlarm1(false);
alarm_on = false;
regim = 1;
lcd.clear();
}
}
}
else {
clock.armAlarm1(false);
regim = 1;
lcd.clear();
}
}
if (pmenu == 4) { // Прервать настройку, ничего не менять
lcd.clear();
regim = 1;
}
}
while (regim==3) { //установка часов таймеров
buttons();
blinkCursor = 1;
blink_set_alarm(250);
if (pmenu == 1) ah++;
if (pmenu == 2) ah--;
if (ah>23) ah=0;
if (ah<0) ah=23;
if ((pmenu == 5) || (pmenu == 8)) {
if (ah || am) {
clock.armAlarm1(true);
clock.setAlarm1(0, ah, am, 0, DS3231_MATCH_H_M_S);
}
if (pmenu == 5) regim++;
else {
regim = 1;
lcd.clear();
}
}
if (pmenu == 4) {
lcd.clear();
regim = 1;
}
}
while(regim==4){ //установка минут таймеров
buttons();
blinkCursor = 2;
blink_set_alarm(250);
if (pmenu == 1) am++;
if (pmenu == 2) am--;
if (am>59) am=0;
if (am<0) am=59;
if ((pmenu == 5) || (pmenu == 8)) {
if (ah || am) {
clock.armAlarm1(true);
clock.setAlarm1(0, ah, am, dt.second, DS3231_MATCH_H_M_S);
}
else {
clock.armAlarm1(false); alarm_on = false;
}
if (pmenu == 5) regim++;
else {
regim = 1;
lcd.clear();
}
}
if (pmenu == 4) {
pmenu = 9;
regim = 1;
}
}
}
//------------------------------------------------------------
void SET_A2 () {
regim=2;
lcd.clear();
uint8_t da=a1.day;
ah=a2.hour;
am=a2.minute;
alarm_on1 = (clock.isArmed2()) ? true : false;
lcd.setCursor(1, 0);
lcd.print("on Alarm2 off");
while (regim==2) {
buttons();
if ((pmenu == 1) || (pmenu == 2)) alarm_on1 = !alarm_on1;
// if (pmenu == 2) alarm_on1 = !alarm_on1;
if (alarm_on1) blink_alarm_on(250);
else blink_alarm_off(250);
if ((pmenu == 5) || (pmenu == 8)) { //Сохранить настройку
if (alarm_on1) {
clock.armAlarm2(true);
if (pmenu == 5) regim++;
else {
regim = 1;
lcd.clear();
}
}
else {
clock.armAlarm2(false);
regim = 1;
lcd.clear();
}
}
if (pmenu == 4) {
lcd.clear();
regim = 1;
return;
}
}
while (regim==3) { //установка часов таймеров
buttons();
blinkCursor = 1;
blink_set_alarm(300);
if (pmenu == 1) ah++;
if (pmenu == 2) ah--;
if (ah>23) ah=0;
if (ah<0) ah=23;
if ((pmenu == 5) || (pmenu == 8)) {
clock.setAlarm2(0, ah, 0, DS3231_MATCH_H_M);
if (pmenu == 5) regim++;
else {
regim = 1;
lcd.clear();
}
}
if (pmenu == 4) {
lcd.clear();
regim = 1;
return;
}
}
while(regim==4){ //установка минут таймеров
buttons();
blinkCursor = 2;
blink_set_alarm(250);
if (pmenu == 1) am++;
if (pmenu == 2) am--;
if (am>59) am=0;
if (am<0) am=59;
if ((pmenu == 5) || (pmenu == 8)) {
if (!ah && !am) {
clock.armAlarm2(false); !alarm_on1;
}
else clock.setAlarm2(0, ah, am, DS3231_MATCH_H_M);
if (pmenu == 5) regim++;
else {
regim = 1;
lcd.clear();
}
}
if (pmenu == 4) {
pmenu = 9;
regim = 1;
return;}
}
}
//------------------------------------------------------------
void blink_alarm_on(unsigned long interval){
static unsigned long prevTime=0;
if(millis() - prevTime > interval){
static boolean flag = false;
prevTime = millis();
flag = !flag;
lcd.setCursor(1, 0);
if (flag) lcd.print("on");
else lcd.print(" ");
}
}
//------------------------------------------------------------
void blink_alarm_off(unsigned long interval){
static unsigned long prevTime=0;
if(millis() - prevTime > interval){
static boolean flag = false;
prevTime = millis();
flag = !flag;
lcd.setCursor(11, 0);
if(flag) lcd.print("off");
else lcd.print(" ");
}
}
//------------------------------------------------------------
void blink_set_alarm (unsigned long interval){ //мигаем переменной настройки часов/минут будильников
static unsigned long prevTime=0;
if(millis() - prevTime > interval){
static boolean flag = false;
prevTime = millis();
flag = !flag;
if(flag){
lcd.setCursor(5, 1);
if (ah<10) lcd.print("0");
lcd.print(ah);
lcd.print(":");
if (am<10) lcd.print("0");
lcd.print(am);
}
else {
switch (blinkCursor) {
case 1: lcd.setCursor(5, 1); break;
case 2: lcd.setCursor(8, 1); break;
case 3: lcd.setCursor(11, 1); break;
}
lcd.print(" ");
}
}
}
//------------------------------------------------------------
Если хотите продолжения разговора, то
1. Вставьте код как положено
2. Дайте ссылку на библиотеку.
А то в той библиотеке DS3231, что есть у меня просто нет функции setDateTime, которую Вы дважды используете в ... ХЗ какой строке (это к правильности вставки кода)
Вот хеадер библиотеки
У Вас нет привычки читать форум, прежде, чем писать в него?
http://arduino.ru/forum/obshchii/vstavka-programmnogo-koda-v-temukomment...
Встаьте нормально Ваш код
Что, до библиотеки, достаточно ссылки, где Вы её скачивали.
Нашел ссылку на библиотеку
https://github.com/jarzebski/Arduino-DS3231
А что изменилось?
Понял.
Вы пытаетесь устанавливать время аж в пяти местах (это, кстати, говорит о том, что структура программы недостаточно продумана). Это строки №№ 701, 716, 731, 746 и 761. Все эти строки выглядят одинаково
Вы уверены что время не устанавливается? Может Вы просто не пытаетесь его устанавливать. Попробуйте вставить контрольную печать в Serial. т.е. во всех пяти местах замените строку "if (pmenu ..." на примерно такое:
И не забудьте потавить Serial.begin в setup.
Теперь Вы сможете поконтролировать попытки установки времени и точно понять оно действительно не устанавливается или Вы его не устанавливаете. Сделайте и покажите, что выдаёт.
Получил результат:
Так, давайте смотреть что Вы вводили. Привыкайте работать с открытыми глазами. Вот смотрите, сейчас у Вас вот так:
Теперь добавляйте печать того, что Вы передаёте часам
Теперь Вы будете видеть что Вы пихаете часам. Если пихаете то, что надо, а часы ставятся не так, разбирайтесь с setDateTime (порядок параметров и т.п.). А если пихаете не то что надо, то разбирайтесь почему эти переменные имеют неверные значения.
Т.е. мы разделили программу и немного локализовали проблему. Вот так мы и работаем.
Перед первым set задал жестко
Потом цифры поправил
Надо было
Надо, наверное, в библиотеку Serial куда-то вставить?
Перед первым set задал жестко
Наверное что-то в библиотеке не так?
Да, нет, это в голове у Вас непонятки.
Нафига Вы строки присваивали, когда там числа нужны? Ставьте ЧИСЛА, а не строки!
Это вообще Ваш скетч?
Это вообще Ваш скетч?
конечно нет. Он бы на десятой строчке завопил "Памагите" с такими знаниями...
Спасибо за помощь.
Здравствуйте ! У меня такая проблема..не идут часы. Показывает одно и то же время, хотя дата по прошествии суток изменяется Пара Arduino nano и RTC3231 Перепробовал с десяток библиотек, но безуспешно. Взял библиотеку из этой темы (https://github.com/jarzebski/Arduino-DS3231) но как и ожидалось, не тикают часы Скетч:
Проверил сканнером, все находит:
Подскажите, в чем может быть проблема? Столько времени убил казалось бы на простую задачу