Ардуино и 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
#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(" "); } } } //------------------------------------------------------------А что изменилось?
Понял.
Вы пытаетесь устанавливать время аж в пяти местах (это, кстати, говорит о том, что структура программы недостаточно продумана). Это строки №№ 701, 716, 731, 746 и 761. Все эти строки выглядят одинаково
Вы уверены что время не устанавливается? Может Вы просто не пытаетесь его устанавливать. Попробуйте вставить контрольную печать в Serial. т.е. во всех пяти местах замените строку "if (pmenu ..." на примерно такое:
if (pmenu == 5) { clock.setDateTime(..<оставьте что было>...); RTCDateTime control = clock.getDateTime(); Serial.print("Line "); Serial.print(__LINE__); Serial.print(": "); Serial.println(clock.dateFormat("d-m-Y H:i:s", control)); }И не забудьте потавить Serial.begin в setup.
Теперь Вы сможете поконтролировать попытки установки времени и точно понять оно действительно не устанавливается или Вы его не устанавливаете. Сделайте и покажите, что выдаёт.
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); RTCDateTime control = clock.getDateTime(); Serial.print("Line "); Serial.print(__LINE__); Serial.print(": "); Serial.println(clock.dateFormat("d-m-Y H:i:s", control)); } 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); RTCDateTime control = clock.getDateTime(); Serial.print("Line "); Serial.print(__LINE__); Serial.print(": "); Serial.println(clock.dateFormat("d-m-Y H:i:s", control)); } 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); RTCDateTime control = clock.getDateTime(); Serial.print("Line "); Serial.print(__LINE__); Serial.print(": "); Serial.println(clock.dateFormat("d-m-Y H:i:s", control)); } 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); RTCDateTime control = clock.getDateTime(); Serial.print("Line "); Serial.print(__LINE__); Serial.print(": "); Serial.println(clock.dateFormat("d-m-Y H:i:s", control)); } 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); RTCDateTime control = clock.getDateTime(); Serial.print("Line "); Serial.print(__LINE__); Serial.print(": "); Serial.println(clock.dateFormat("d-m-Y H:i:s", control)); }} if (pmenu == 4) regim = 1; } }Получил результат:
Так, давайте смотреть что Вы вводили. Привыкайте работать с открытыми глазами. Вот смотрите, сейчас у Вас вот так:
if (pmenu == 5){ clock.setDateTime(ye, mo, da, th, tm, se); RTCDateTime control = clock.getDateTime(); Serial.print("Line "); Serial.print(__LINE__); Serial.print(": "); Serial.println(clock.dateFormat("d-m-Y H:i:s", control)); }Теперь добавляйте печать того, что Вы передаёте часам
if (pmenu == 5){ Serial.print("ye=); Serial.println(ye); Serial.print("mo=); Serial.println(mo); Serial.print("th=); Serial.println(th); Serial.print("tm=); Serial.println(tm); Serial.print("se=); Serial.println(se); clock.setDateTime(ye, mo, da, th, tm, se); RTCDateTime control = clock.getDateTime(); Serial.print("Line "); Serial.print(__LINE__); Serial.print(": "); Serial.println(clock.dateFormat("d-m-Y H:i:s", control)); }Теперь Вы будете видеть что Вы пихаете часам. Если пихаете то, что надо, а часы ставятся не так, разбирайтесь с setDateTime (порядок параметров и т.п.). А если пихаете не то что надо, то разбирайтесь почему эти переменные имеют неверные значения.
Т.е. мы разделили программу и немного локализовали проблему. Вот так мы и работаем.
Перед первым set задал жестко
void SET_T(){ regim=2; /* ye = dt.year; mo = dt.month; da = dt.day; th = dt.hour; tm = dt.minute; */ ye = "2018"; mo = "04"; da = "03"; th = "20"; tm = ""; se = dt.second;Потом цифры поправил
Надо было
Надо, наверное, в библиотеку Serial куда-то вставить?
Перед первым set задал жестко
void SET_T(){ regim=2; /* ye = dt.year; mo = dt.month; da = dt.day; th = dt.hour; tm = dt.minute; */ ye = "2018"; mo = "04"; da = "03"; th = "20"; tm = ""; se = dt.second;Наверное что-то в библиотеке не так?
Да, нет, это в голове у Вас непонятки.
Нафига Вы строки присваивали, когда там числа нужны? Ставьте ЧИСЛА, а не строки!
Это вообще Ваш скетч?
Это вообще Ваш скетч?
конечно нет. Он бы на десятой строчке завопил "Памагите" с такими знаниями...
Спасибо за помощь.
Здравствуйте ! У меня такая проблема..не идут часы. Показывает одно и то же время, хотя дата по прошествии суток изменяется Пара Arduino nano и RTC3231 Перепробовал с десяток библиотек, но безуспешно. Взял библиотеку из этой темы (https://github.com/jarzebski/Arduino-DS3231) но как и ожидалось, не тикают часы Скетч:
#include <Wire.h> #include <DS3231.h> DS3231 clock; RTCDateTime dt; void setup() { Serial.begin(9600); // Initialize DS3231 Serial.println("Initialize DS3231");; clock.begin(); // Set sketch compiling time clock.setDateTime(__DATE__, __TIME__); } void loop() { dt = clock.getDateTime(); // For leading zero look to DS3231_dateformat example Serial.print("Raw data: "); Serial.print(dt.year); Serial.print("-"); Serial.print(dt.month); Serial.print("-"); Serial.print(dt.day); Serial.print(" "); Serial.print(dt.hour); Serial.print(":"); Serial.print(dt.minute); Serial.print(":"); Serial.print(dt.second); Serial.println(""); delay(1000); }Проверил сканнером, все находит:
Подскажите, в чем может быть проблема? Столько времени убил казалось бы на простую задачу