Ардуино - будильник
1
В статье рассказано о том, как из ардуины и дисплея TM1637 сделать часы-будильник, управляемый при помощи любого ИК-пульта.
С помощью пульта можно будет программировать время и будильник, включать/отключать будильник и устанавливать отсрочку сигнала. То есть делать всё не вставая с дивана.
Так же будут рассмотрены варианты получения времени.
Что понадобится
Первый вариант:
• Ардуина
• Дисплей TM1637
• Два светодиода —
• Пищалка (buzzer)
Можно не покупать, а выдрать откуда-либо.
• ИК-приёмник — наиболее предпочтительный вариант — TSOPxx38 (38kHz).
Во втором варианте потребуется модуль часов DS 3231.
В начале вариант для тех, кто хочет просто подключить/проверить дисплей.
Подключаем всё по следующей схеме:
Скачиваем и устанавливаем библиотеку для дисплея TM1637.
Заливаем скетч:
#include "TM1637.h"
#define CLK 11 // пин 11
#define DIO 12 // пин 12
TM1637 tm1637(CLK,DIO);
#define ON 1
#define OFF 0
#define MAXMILLIS 4294967295
unsigned long timme = 0;
unsigned long timelapsed = 0;
int chas = 0;
int minuta = 0;
int secunda = 0;
int8_t TimeDisp[] = {0x00,0x00,0x00,0x00};
unsigned char ClockPoint = 1;
void setup()
{
tm1637.set(2); // яркость дисплея от 0 до 7
tm1637.init();
}
void loop()
{
unsigned long currtime = millis(); // счётчик времени
if(currtime > timme) timelapsed = (currtime - timme);
else timelapsed = (MAXMILLIS - timme + currtime);
if(timelapsed > 999)
{
timme = currtime;
secunda++;
if(secunda > 59)
{
secunda=0;
minuta++;
if(minuta > 59)
{
minuta=0;
chas++;
if(chas>23) chas=0;
}
}
disp();
}
} //END LOOP
void disp() // вывод на дисплей
{
ClockPoint = (~ClockPoint) & 0x01;
if(ClockPoint)tm1637.point(POINT_ON); // мигание двоеточием
else tm1637.point(POINT_OFF);
TimeDisp[0] = chas / 10; // первая цифра
TimeDisp[1] = chas % 10; // вторая цифра
TimeDisp[2] = minuta / 10; // третья цифра
TimeDisp[3] = minuta % 10; // четвёртая цифра
tm1637.display(TimeDisp);
}
Если всё работает, то переходим к следующему этапу. Добавим к схеме светики, пищалку и ик-приёмник…
У Вас может быть другая распиновка ик-приёмника. Резисторы 300-1000 ом.
Скачайте и установите библиотеки IRstD (инфа) и CyberLib (инфа).
Сначала залейте скетч для обнуления EEPROM…
#include <EEPROM.h>
void setup()
{
for ( int i = 0 ; i < EEPROM.length() ; i++ )
EEPROM.write(i, 0);
// По окончании загорится D13
digitalWrite(13, HIGH);
}
void loop(){ }
… а теперь этот:
#include "CyberLib.h"
#include "TM1637.h"
#define CLK 11 // пин 11
#define DIO 12 // пин 12
TM1637 tm1637(CLK,DIO);
#define ON 1
#define OFF 0
#include <IRstD.h>
IRrecvstd irrecvstd(4);
decode_resultsstd res_std;
#define MAXMILLIS 4294967295
unsigned long timme;
unsigned long timelapsed = 0;
int chas = 0;
int minuta = 0;
int secunda = 0;
///////////// B1 ////////////////////
uint8_t B1_flag = ReadEEPROM_Byte(1);
uint8_t B1chas_vkl = ReadEEPROM_Byte(2);
uint8_t B1minut_vkl = ReadEEPROM_Byte(3);
uint8_t val_shim = ReadEEPROM_Byte(4);
uint8_t flag_disp = 0;
uint8_t flag_zel_led = 0;
int buzzerPin = 5;
int8_t TimeDisp[] = {0x00,0x00,0x00,0x00};
int8_t BudDisp[] = {0x00,0x00,0x00,0x00};
unsigned char ClockPoint = 1;
void setup()
{
tm1637.set(val_shim);
tm1637.init();
pinMode(buzzerPin, OUTPUT);
D7_Out;
D7_Low;
D10_Out;
if(B1_flag) D10_High;
else D10_Low;
Serial.begin(57600);
irrecvstd.enableIRInstd();
}
void loop()
{
if(irrecvstd.decodestd(&res_std))
{
if(res_std.valuestd == 1886442794) // Прибавление часов
{
analogWrite(buzzerPin, 255);
chas++;
if(chas > 23) chas = 0;
disp();
analogWrite(buzzerPin, 0);
}
if(res_std.valuestd == 1886430554) // Убавление часов
{
analogWrite(buzzerPin, 255);
chas--;
if(chas < 1) chas = 0;
disp();
analogWrite(buzzerPin, 0);
}
if(res_std.valuestd == 1886397914) // Прибавление минут
{
analogWrite(buzzerPin, 255);
minuta++;
if(minuta > 59) minuta = 0;
disp();
analogWrite(buzzerPin, 0);
}
if(res_std.valuestd == 1886446874) // Убавление минут
{
analogWrite(buzzerPin, 255);
minuta--;
if(minuta < 1 || minuta > 60) minuta = 0;
disp();
analogWrite(buzzerPin, 0);
}
if(flag_disp && res_std.valuestd == 551521650) // Прибавление часов будильника
{
analogWrite(buzzerPin, 255);
B1chas_vkl++;
if(B1chas_vkl > 23) B1chas_vkl = 0;
WriteEEPROM_Byte(2, B1chas_vkl);
disp();
analogWrite(buzzerPin, 0);
}
if(flag_disp && res_std.valuestd == 551547150) // Убавление часов будильника
{
analogWrite(buzzerPin, 255);
B1chas_vkl--;
if(B1chas_vkl < 1 || B1chas_vkl > 24) B1chas_vkl = 0;
WriteEEPROM_Byte(2, B1chas_vkl);
disp();
analogWrite(buzzerPin, 0);
}
if(flag_disp && res_std.valuestd == 551489010) // Прибавление минут будильника
{
analogWrite(buzzerPin, 255);
B1minut_vkl++;
if(B1minut_vkl > 59) B1minut_vkl = 0;
WriteEEPROM_Byte(3, B1minut_vkl);
disp();
analogWrite(buzzerPin, 0);
}
if(flag_disp && res_std.valuestd == 551514510) // Убавление минут будильника
{
analogWrite(buzzerPin, 255);
B1minut_vkl--;
if(B1minut_vkl < 1 || B1minut_vkl > 60) B1minut_vkl = 0;
WriteEEPROM_Byte(3, B1minut_vkl);
disp();
analogWrite(buzzerPin, 0);
}
if(res_std.valuestd == 551505585) // Вкл/Откл будильник
{
analogWrite(buzzerPin, 255);
B1chas_vkl = ReadEEPROM_Byte(2);
B1minut_vkl = ReadEEPROM_Byte(3);
if(B1_flag)
{
B1_flag = 0;
D10_Low;
}
else
{
B1_flag = 1;
D10_High;
}
disp();
WriteEEPROM_Byte(1, B1_flag);
analogWrite(buzzerPin, 0);
}
if(res_std.valuestd == 551521905) // Вывод будильника на дисплей
{
analogWrite(buzzerPin, 255);
flag_zel_led = 0;
if(flag_disp)
{
flag_disp = 0;
D7_Low;
}
else
{
flag_disp = 1;
D7_High;
}
disp();
analogWrite(buzzerPin, 0);
}
if(res_std.valuestd == 551525475) // Подсветка +
{
analogWrite(buzzerPin, 255);
val_shim++;
if(val_shim > 7) val_shim = 7;
WriteEEPROM_Byte(4, val_shim);
tm1637.set(val_shim);
disp();
delay_ms(10);
analogWrite(buzzerPin, 0);
}
if(res_std.valuestd == 551519355) // Подсветка -
{
analogWrite(buzzerPin, 255);
val_shim--;
if(val_shim < 1 || val_shim > 254) val_shim = 0;
WriteEEPROM_Byte(4, val_shim);
tm1637.set(val_shim);
disp();
delay_ms(10);
analogWrite(buzzerPin, 0);
}
if(res_std.valuestd == 551519865) // +10 минут отсрочка
{
analogWrite(buzzerPin, 255);
B1minut_vkl = B1minut_vkl + 10;
if(B1minut_vkl > 59)
{
B1minut_vkl = 10;
B1chas_vkl++;
if(B1chas_vkl>23) B1chas_vkl=0;
}
delay_ms(5);
analogWrite(buzzerPin, 0);
flag_disp = 1;
D7_High;
disp();
delay_ms(300);
flag_disp = 0;
D7_Low;
}
Serial.println(res_std.valuestd); // Удалить после программирования пульта
irrecvstd.resumestd();
res_std.valuestd = 0;
}
unsigned long currtime = millis();
if(currtime > timme) timelapsed = (currtime - timme);
else timelapsed = (MAXMILLIS - timme + currtime);
if(timelapsed > 999)
{
timme = currtime;
if(flag_disp)
{
flag_zel_led++;
if(flag_zel_led > 59)
{
flag_zel_led = 0;
flag_disp = 0;
D7_Low;
analogWrite(buzzerPin, 255);
delay_ms(5);
analogWrite(buzzerPin, 0);
}
}
secunda++;
if(secunda > 59)
{
secunda=0;
minuta++;
if(minuta > 59)
{
minuta=0;
chas++;
if(chas>23) chas=0;
}
}
disp();
}
if(B1_flag)
{
if(chas == B1chas_vkl && minuta == B1minut_vkl)
{
buzz();
}
if(chas == B1chas_vkl && minuta == B1minut_vkl && secunda == 59)
{
B1minut_vkl = B1minut_vkl + 10;
if(B1minut_vkl > 59)
{
B1minut_vkl = 10;
B1chas_vkl++;
if(B1chas_vkl>23) B1chas_vkl=0;
}
}
}
} //END LOOP
void buzz()
{
if(B1_flag)
{
analogWrite(buzzerPin, 30);
delay_ms(100);
analogWrite(buzzerPin, 50);
delay_ms(100);
}
analogWrite(buzzerPin, 0);
delay_ms(100);
}
void disp()
{
if(!flag_disp)
{
ClockPoint = (~ClockPoint) & 0x01;
if(ClockPoint)tm1637.point(POINT_ON);
else tm1637.point(POINT_OFF);
TimeDisp[0] = chas / 10;
TimeDisp[1] = chas % 10;
TimeDisp[2] = minuta / 10;
TimeDisp[3] = minuta % 10;
tm1637.display(TimeDisp);
}
else
{
tm1637.point(POINT_ON);
BudDisp[0] = B1chas_vkl / 10;
BudDisp[1] = B1chas_vkl % 10;
BudDisp[2] = B1minut_vkl / 10;
BudDisp[3] = B1minut_vkl % 10;
tm1637.display(BudDisp);
}
}
Теперь я (немного забегая вперёд) опишу алгоритм, а после перейдём к программированию пульта.
Инструкция и как работает
Установите время на часах. Нажмите кнопку перехода в режим будильника (загорится
Чтоб вернуться в режим часов нужно снова нажать ту же кнопку. Если не возвращаться в режим часов, то через минуту это произойдёт автоматически.
Сигнал будильника будет воспроизводиться в течении минуты, после этого будет десятиминутная пауза и снова сигнал в течении минуты. Так будет происходить до тех пор, пока будильник не будет выключен. Если во время воспроизведения сигнала нажать кнопку отсрочки, то звук выключится, а время будильника переведётся на десять минут вперёд.
То есть в момент пробуждения у вас будет два варианта — нажать кнопку отключения будильника и вылезать из тряпок, либо нажать кнопку отсрочки и поваляться ещё 10 минут.
После нажатия кнопки отключения будильника установленное время вернётся к изначальному значению. То есть, вы встаёте в 7:00 утра, будильник зазвенел, вы нажали отсрочку, будильник перевёлся на 7:10, зазвенел, вы таки встали, отключили будильник — будильник вернулся на 7:00.
В момент нажатия отсрочки появляется индикация будильника.
Время будильника, его состояние (включён/отключён) и уровень яркости дисплея сохраняются в энергонезависимой памяти.
Нажатия на кнопки сопровождаются звуковым сигналом.
Программирование пульта
Возьмите какой-нибудь пульт, например от телевизора, выберите на нём несколько кнопок (у большинства пультов есть незадействованные кнопки), которыми будете управлять часами/будильником.
Нужно выбрать кнопки, которыми вы будете устанавливать время на часах (прибавлять/убавлять часы и минуты, четыре кнопки). Кнопки для установки будильника — прибавлять/убавлять часы и минуты будильника (четыре кнопки). Кнопка включения/отключения будильника (одна кнопка). Кнопка отсрочки будильника на 10 минут (одна кнопка) и кнопка перехода в режим установки будильника (одна кнопка). Кнопки для регулировки яркости (две штуки).
Заполучим коды кнопок. Откройте «Монитор последовательного порта», и нажмите на пульте кнопку, которой планируете устанавливать время — прибавлять часы:
Нажатия должны быть короткими. Иногда печатаются сразу два числа, первое число это код кнопки (то, что нам нужно), а второе это код повтора (он нам не интересен).
Скопируйте это число и вставьте в скетч:
...
void loop()
{
if(irrecvstd.decodestd(&res_std))
{
if(res_std.valuestd == 1886408114) // Прибавление часов ВСТАВЛЯТЬ ЗДЕСЬ
{
analogWrite(buzzerPin, 255);
chas++;
if(chas > 23) chas = 0;
disp();
analogWrite(buzzerPin, 0);
}
...
Повторяем процедуру для кнопки убавления часов:
Вставляем в скетч:
...
if(res_std.valuestd == 1886430554) // Убавление часов ВСТАВЛЯТЬ ЗДЕСЬ
{
analogWrite(buzzerPin, 255);
chas--;
if(chas < 1) chas = 0;
disp();
analogWrite(buzzerPin, 0);
}
...
Проделываем всё то же самое для остальных кнопок. В скетче есть комментарии.
И в конце комментируем или удаляем строку…
...
Serial.println(res_std.valuestd); // Удалить после программирования пульта
...
Заливаем скетч, и в принципе можно пользоваться. Однако такой способ подсчёта времени не выдерживает никакой критики, поэтому предложу пару вариантов. Первый — это использование модуля DS3231 (очень точный и стабильный), а второй — это ежесуточная коррекция времени от большого компьютера. Начну с последнего.
Сразу же скажу, что второй вариант подходит тем, у кого есть компьютер с линуксом или роутер с альтернативной прошивкой.
Синхронизация от компьютера
Идея заключается в следующем, часы подключены (USB, UART) к компьютеру с запущенной на нём программой, которая «слушает» USB-порт в ожидании запроса от часов. Ровно в 00:00:10 часы отправляют запрос компьютеру, а тот в ответ отсылает часам своё системное время.
Добавим в скетч необходимый функционал. Там где счётчик времени добавим блок отвечающий за запрос…
...
if(chas == 0 && minuta == 0 && secunda == 10)
{
Serial.print('T');
Serial.print('\n');
delay_ms(200);
}
disp();
...
И в конец основного цикла добавим блок отвечающий за приём:
...
if(Serial.available()>4)
{
byte descript[5];
char ot_irserver[10] = {0,};
if (Serial.read()=='Y')
{
for (byte i=0; i < 4; i++)
{
descript[i] = Serial.read();
}
byte i = 0;
if((descript[0] =='+') && (descript[1] =='=') && (descript[2] =='Z'))
{
switch (descript[3])
{
case 'T':
delay_ms(3);
while(Serial.available())
{
delay_ms(1);
ot_irserver[i] = Serial.read();
if(ot_irserver[i] == ':')
{
ot_irserver[i] = ' ';
}
if(ot_irserver[i] == '\n')
{
ot_irserver[i] = 0;
break;
}
i++;
}
sscanf(ot_irserver, "%d%d%d", &chas, &minuta, &secunda);
for(int i=0; i < 64; i++)
{
Serial.read();
}
break;
default:
break;
}
}
else
{
for(byte i=0; i < 128; i++)
{
Serial.read();
}
}
}
}
} //END LOOP
...
Скетч целиком
Не забудьте про коды кнопок пульта.
#include "CyberLib.h"
#include "TM1637.h"
#define CLK 11 // пин 11
#define DIO 12 // пин 12
TM1637 tm1637(CLK,DIO);
#define ON 1
#define OFF 0
#include <IRstD.h>
IRrecvstd irrecvstd(4);
decode_resultsstd res_std;
#define MAXMILLIS 4294967295
unsigned long timme;
unsigned long timelapsed = 0;
int chas = 0;
int minuta = 0;
int secunda = 0;
///////////// B1 ////////////////////
uint8_t B1_flag = ReadEEPROM_Byte(1);
uint8_t B1chas_vkl = ReadEEPROM_Byte(2);
uint8_t B1minut_vkl = ReadEEPROM_Byte(3);
uint8_t val_shim = ReadEEPROM_Byte(4);
uint8_t flag_disp = 0;
uint8_t flag_zel_led = 0;
int buzzerPin = 5;
int8_t TimeDisp[] = {0x00,0x00,0x00,0x00};
int8_t BudDisp[] = {0x00,0x00,0x00,0x00};
unsigned char ClockPoint = 1;
void setup()
{
tm1637.set(val_shim);
tm1637.init();
pinMode(buzzerPin, OUTPUT);
D7_Out;
D7_Low;
D10_Out;
if(B1_flag) D10_High;
else D10_Low;
Serial.begin(57600);
irrecvstd.enableIRInstd();
}
void loop()
{
if(irrecvstd.decodestd(&res_std))
{
if(res_std.valuestd == 1886442794) // Прибавление часов
{
analogWrite(buzzerPin, 255);
chas++;
if(chas > 23) chas = 0;
disp();
analogWrite(buzzerPin, 0);
}
if(res_std.valuestd == 1886430554) // Убавление часов
{
analogWrite(buzzerPin, 255);
chas--;
if(chas < 1) chas = 0;
disp();
analogWrite(buzzerPin, 0);
}
if(res_std.valuestd == 1886397914) // Прибавление минут
{
analogWrite(buzzerPin, 255);
minuta++;
if(minuta > 59) minuta = 0;
disp();
analogWrite(buzzerPin, 0);
}
if(res_std.valuestd == 1886446874) // Убавление минут
{
analogWrite(buzzerPin, 255);
minuta--;
if(minuta < 1 || minuta > 60) minuta = 0;
disp();
analogWrite(buzzerPin, 0);
}
if(flag_disp && res_std.valuestd == 551521650) // Прибавление часов будильника
{
analogWrite(buzzerPin, 255);
B1chas_vkl++;
if(B1chas_vkl > 23) B1chas_vkl = 0;
WriteEEPROM_Byte(2, B1chas_vkl);
disp();
analogWrite(buzzerPin, 0);
}
if(flag_disp && res_std.valuestd == 551547150) // Убавление часов будильника
{
analogWrite(buzzerPin, 255);
B1chas_vkl--;
if(B1chas_vkl < 1 || B1chas_vkl > 24) B1chas_vkl = 0;
WriteEEPROM_Byte(2, B1chas_vkl);
disp();
analogWrite(buzzerPin, 0);
}
if(flag_disp && res_std.valuestd == 551489010) // Прибавление минут будильника
{
analogWrite(buzzerPin, 255);
B1minut_vkl++;
if(B1minut_vkl > 59) B1minut_vkl = 0;
WriteEEPROM_Byte(3, B1minut_vkl);
disp();
analogWrite(buzzerPin, 0);
}
if(flag_disp && res_std.valuestd == 551514510) // Убавление минут будильника
{
analogWrite(buzzerPin, 255);
B1minut_vkl--;
if(B1minut_vkl < 1 || B1minut_vkl > 60) B1minut_vkl = 0;
WriteEEPROM_Byte(3, B1minut_vkl);
disp();
analogWrite(buzzerPin, 0);
}
if(res_std.valuestd == 551505585) // Вкл/Откл будильник
{
analogWrite(buzzerPin, 255);
B1chas_vkl = ReadEEPROM_Byte(2);
B1minut_vkl = ReadEEPROM_Byte(3);
if(B1_flag)
{
B1_flag = 0;
D10_Low;
}
else
{
B1_flag = 1;
D10_High;
}
disp();
WriteEEPROM_Byte(1, B1_flag);
analogWrite(buzzerPin, 0);
}
if(res_std.valuestd == 551521905) // Вывод будильника на дисплей
{
analogWrite(buzzerPin, 255);
flag_zel_led = 0;
if(flag_disp)
{
flag_disp = 0;
D7_Low;
}
else
{
flag_disp = 1;
D7_High;
}
disp();
analogWrite(buzzerPin, 0);
}
if(res_std.valuestd == 551525475) // Подсветка +
{
analogWrite(buzzerPin, 255);
val_shim++;
if(val_shim > 7) val_shim = 7;
WriteEEPROM_Byte(4, val_shim);
tm1637.set(val_shim);
disp();
delay_ms(10);
analogWrite(buzzerPin, 0);
}
if(res_std.valuestd == 551519355) // Подсветка -
{
analogWrite(buzzerPin, 255);
val_shim--;
if(val_shim < 1 || val_shim > 254) val_shim = 0;
WriteEEPROM_Byte(4, val_shim);
tm1637.set(val_shim);
disp();
delay_ms(10);
analogWrite(buzzerPin, 0);
}
if(res_std.valuestd == 551519865) // +10 минут отсрочка
{
analogWrite(buzzerPin, 255);
B1minut_vkl = B1minut_vkl + 10;
if(B1minut_vkl > 59)
{
B1minut_vkl = 10;
B1chas_vkl++;
if(B1chas_vkl>23) B1chas_vkl=0;
}
delay_ms(5);
analogWrite(buzzerPin, 0);
flag_disp = 1;
D7_High;
disp();
delay_ms(300);
flag_disp = 0;
D7_Low;
}
Serial.println(res_std.valuestd); // Удалить после программирования пульта
irrecvstd.resumestd();
res_std.valuestd = 0;
}
unsigned long currtime = millis();
if(currtime > timme) timelapsed = (currtime - timme);
else timelapsed = (MAXMILLIS - timme + currtime);
if(timelapsed > 999)
{
timme = currtime;
if(flag_disp)
{
flag_zel_led++;
if(flag_zel_led > 59)
{
flag_zel_led = 0;
flag_disp = 0;
D7_Low;
analogWrite(buzzerPin, 255);
delay_ms(5);
analogWrite(buzzerPin, 0);
}
}
secunda++;
if(secunda > 59)
{
secunda=0;
minuta++;
if(minuta > 59)
{
minuta=0;
chas++;
if(chas>23) chas=0;
}
}
if(chas == 0 && minuta == 0 && secunda == 10)
{
Serial.print('T');
Serial.print('\n');
delay_ms(200);
}
disp();
}
if(B1_flag)
{
if(chas == B1chas_vkl && minuta == B1minut_vkl)
{
buzz();
}
if(chas == B1chas_vkl && minuta == B1minut_vkl && secunda == 59)
{
B1minut_vkl = B1minut_vkl + 10;
if(B1minut_vkl > 59)
{
B1minut_vkl = 10;
B1chas_vkl++;
if(B1chas_vkl>23) B1chas_vkl=0;
}
}
}
if(Serial.available()>4)
{
byte descript[5];
char ot_irserver[10] = {0,};
if (Serial.read()=='Y')
{
for (byte i=0; i < 4; i++)
{
descript[i] = Serial.read();
}
byte i = 0;
if((descript[0] =='+') && (descript[1] =='=') && (descript[2] =='Z'))
{
switch (descript[3])
{
case 'T':
delay_ms(3);
while(Serial.available())
{
delay_ms(1);
ot_irserver[i] = Serial.read();
if(ot_irserver[i] == ':')
{
ot_irserver[i] = ' ';
}
if(ot_irserver[i] == '\n')
{
ot_irserver[i] = 0;
break;
}
i++;
}
sscanf(ot_irserver, "%d%d%d", &chas, &minuta, &secunda);
for(int i=0; i < 64; i++)
{
Serial.read();
}
break;
default:
break;
}
}
else
{
for(byte i=0; i < 128; i++)
{
Serial.read();
}
}
}
}
} //END LOOP
void buzz()
{
if(B1_flag)
{
analogWrite(buzzerPin, 30);
delay_ms(100);
analogWrite(buzzerPin, 50);
delay_ms(100);
}
analogWrite(buzzerPin, 0);
delay_ms(100);
}
void disp()
{
if(!flag_disp)
{
ClockPoint = (~ClockPoint) & 0x01;
if(ClockPoint)tm1637.point(POINT_ON);
else tm1637.point(POINT_OFF);
TimeDisp[0] = chas / 10;
TimeDisp[1] = chas % 10;
TimeDisp[2] = minuta / 10;
TimeDisp[3] = minuta % 10;
tm1637.display(TimeDisp);
}
else
{
tm1637.point(POINT_ON);
BudDisp[0] = B1chas_vkl / 10;
BudDisp[1] = B1chas_vkl % 10;
BudDisp[2] = B1minut_vkl / 10;
BudDisp[3] = B1minut_vkl % 10;
tm1637.display(BudDisp);
}
}
Далее скачиваем программу chasikom, кладём её в домашнюю папку, подключаем часы к компу и запускаем:
sudo /home/dima/chasikom /dev/ttyUSB0
У вас будет свой юзер и возможно другое устройство (/dev/ttyUSB0). Проверить можно так:
ls /dev/tty*
Через десять секунд установится точное время.
Исходник
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>
char device[20]={0,};
char bRead[10] = {0,};
int open_port(void)
{
int fd;
fd = open(device, O_RDWR | O_NOCTTY);
if(fd == -1)
{
printf("Not device\n");
}
else
{
struct termios options;
tcgetattr(fd, &options);
cfsetispeed(&options, B57600);
cfsetospeed(&options, B57600);
options.c_cflag |= (CLOCAL | CREAD);
options.c_cflag &= ~PARENB;
options.c_cflag &= ~CSTOPB;
options.c_cflag &= ~CSIZE;
options.c_cflag |= CS8;
options.c_cc[VMIN] = 1;
options.c_cc[VTIME] = 1;
options.c_lflag = ICANON;
options.c_oflag = 0;
options.c_oflag &= ~OPOST;
tcflush(fd, TCIFLUSH);
tcsetattr(fd, TCSANOW, &options);
}
return fd;
}
int main(int argc, char *argv[])
{
if(argc!=2)
{
printf("Example - ./chasikom /dev/ttyUSB0\n");
}
strncpy(device, argv[1], 19);
int fd = open_port();
sleep(2);
tcflush(fd, TCIFLUSH);
char to_Ardu[64] = {0,};
unsigned int i;
while(!VINTR)
{
int bytes = 0;
memset(bRead, 0, sizeof(bRead));
if((bytes = read(fd, bRead, 10))==-1)
{
printf("Error_Read_from_Arduino\n");
}
for(i = 0; i <= strlen(bRead); i++)
{
if(bRead[i] == '\n')
{
bRead[i] = 0;
break;
}
}
printf("bRead: %s\n", bRead);
if(bRead[0] == 'T')
{
time_t t;
time(&t);
char den[8] = {0,};
char mesiac[8] = {0,};
int chislo = 0;
char vremia[8] = {0,};
int god = 0;
sscanf(ctime( &t), "%s %s %d %s %d", den, mesiac, &chislo, vremia, &god);
snprintf(to_Ardu, 63, "echo 'Y+=ZT%s' > %s", vremia, device);
system(to_Ardu);
printf("to_Ardu: %s\n", to_Ardu);
memset(to_Ardu, 0, sizeof(to_Ardu));
}
}
}
// gcc -Wall -Wextra chasikom.c -o chasikom
// ./chasikom /dev/ttyUSB0
Если нужна прога для какого-либо роутера, тогда напишите в комментах.
Вариант с DS3231
Добавляем в схему модуль:
Скачиваем и устанавливаем библиотеку DS3231, заливаем новый скетч:
#include "CyberLib.h"
#include "TM1637.h"
#define CLK 11 // пин 11
#define DIO 12 // пин 12
TM1637 tm1637(CLK,DIO);
#define ON 1
#define OFF 0
#include <DS3231.h>
#include <Wire.h>
DS3231 rtc(SDA, SCL);
Time t;
#include <IRstD.h>
IRrecvstd irrecvstd(4);
decode_resultsstd res_std;
#define MAXMILLIS 4294967295
unsigned long timme;
unsigned long timelapsed = 0;
int chas = 0;
int minuta = 0;
int secunda = 0;
///////////// B1 ////////////////////
uint8_t B1_flag = ReadEEPROM_Byte(1);
uint8_t B1chas_vkl = ReadEEPROM_Byte(2);
uint8_t B1minut_vkl = ReadEEPROM_Byte(3);
uint8_t val_shim = ReadEEPROM_Byte(4);
uint8_t flag_disp = 0;
uint8_t flag_zel_led = 0;
int buzzerPin = 5;
int8_t TimeDisp[] = {0x00,0x00,0x00,0x00};
int8_t BudDisp[] = {0x00,0x00,0x00,0x00};
unsigned char ClockPoint = 1;
void setup()
{
tm1637.set(val_shim);
tm1637.init();
pinMode(buzzerPin, OUTPUT);
D7_Out;
D7_Low;
D10_Out;
if(B1_flag) D10_High;
else D10_Low;
Serial.begin(57600);
irrecvstd.enableIRInstd();
rtc.begin();
}
void loop()
{
if(irrecvstd.decodestd(&res_std))
{
if(res_std.valuestd == 429496722) // Прибавление часов
{
analogWrite(buzzerPin, 255);
chas++;
if(chas > 23) chas = 0;
rtc.setTime(chas, minuta, secunda);
disp();
analogWrite(buzzerPin, 0);
}
if(res_std.valuestd == 1886430554) // Убавление часов
{
analogWrite(buzzerPin, 255);
chas--;
if(chas < 1) chas = 0;
rtc.setTime(chas, minuta, secunda);
disp();
analogWrite(buzzerPin, 0);
}
if(res_std.valuestd == 1886397914) // Прибавление минут
{
analogWrite(buzzerPin, 255);
minuta++;
if(minuta > 59) minuta = 0;
rtc.setTime(chas, minuta, secunda);
disp();
analogWrite(buzzerPin, 0);
}
if(res_std.valuestd == 1886446874) // Убавление минут
{
analogWrite(buzzerPin, 255);
minuta--;
if(minuta < 1 || minuta > 60) minuta = 0;
rtc.setTime(chas, minuta, secunda);
disp();
analogWrite(buzzerPin, 0);
}
if(flag_disp && res_std.valuestd == 551521650) // Прибавление часов будильника
{
analogWrite(buzzerPin, 255);
B1chas_vkl++;
if(B1chas_vkl > 23) B1chas_vkl = 0;
WriteEEPROM_Byte(2, B1chas_vkl);
disp();
analogWrite(buzzerPin, 0);
}
if(flag_disp && res_std.valuestd == 551547150) // Убавление часов будильника
{
analogWrite(buzzerPin, 255);
B1chas_vkl--;
if(B1chas_vkl < 1 || B1chas_vkl > 24) B1chas_vkl = 0;
WriteEEPROM_Byte(2, B1chas_vkl);
disp();
analogWrite(buzzerPin, 0);
}
if(flag_disp && res_std.valuestd == 551489010) // Прибавление минут будильника
{
analogWrite(buzzerPin, 255);
B1minut_vkl++;
if(B1minut_vkl > 59) B1minut_vkl = 0;
WriteEEPROM_Byte(3, B1minut_vkl);
disp();
analogWrite(buzzerPin, 0);
}
if(flag_disp && res_std.valuestd == 551514510) // Убавление минут будильника
{
analogWrite(buzzerPin, 255);
B1minut_vkl--;
if(B1minut_vkl < 1 || B1minut_vkl > 60) B1minut_vkl = 0;
WriteEEPROM_Byte(3, B1minut_vkl);
disp();
analogWrite(buzzerPin, 0);
}
if(res_std.valuestd == 551505585) // Вкл/Откл будильник
{
analogWrite(buzzerPin, 255);
B1chas_vkl = ReadEEPROM_Byte(2);
B1minut_vkl = ReadEEPROM_Byte(3);
if(B1_flag)
{
B1_flag = 0;
D10_Low;
}
else
{
B1_flag = 1;
D10_High;
}
disp();
WriteEEPROM_Byte(1, B1_flag);
analogWrite(buzzerPin, 0);
}
if(res_std.valuestd == 551521905) // Вывод будильника на дисплей
{
analogWrite(buzzerPin, 255);
flag_zel_led = 0;
if(flag_disp)
{
flag_disp = 0;
D7_Low;
}
else
{
flag_disp = 1;
D7_High;
}
disp();
analogWrite(buzzerPin, 0);
}
if(res_std.valuestd == 551525475) // Подсветка +
{
analogWrite(buzzerPin, 255);
val_shim++;
if(val_shim > 7) val_shim = 7;
WriteEEPROM_Byte(4, val_shim);
tm1637.set(val_shim);
disp();
delay_ms(10);
analogWrite(buzzerPin, 0);
}
if(res_std.valuestd == 551519355) // Подсветка -
{
analogWrite(buzzerPin, 255);
val_shim--;
if(val_shim < 1 || val_shim > 254) val_shim = 0;
WriteEEPROM_Byte(4, val_shim);
tm1637.set(val_shim);
disp();
delay_ms(10);
analogWrite(buzzerPin, 0);
}
if(res_std.valuestd == 551519865) // +10 минут отсрочка
{
analogWrite(buzzerPin, 255);
B1minut_vkl = B1minut_vkl + 10;
if(B1minut_vkl > 59)
{
B1minut_vkl = 10;
B1chas_vkl++;
if(B1chas_vkl>23) B1chas_vkl=0;
}
delay_ms(5);
analogWrite(buzzerPin, 0);
flag_disp = 1;
D7_High;
disp();
delay_ms(300);
flag_disp = 0;
D7_Low;
}
//Serial.println(res_std.valuestd); // Удалить после программирования пульта
irrecvstd.resumestd();
res_std.valuestd = 0;
}
unsigned long currtime = millis();
if(currtime > timme) timelapsed = (currtime - timme);
else timelapsed = (MAXMILLIS - timme + currtime);
if(timelapsed > 999)
{
timme = currtime;
if(flag_disp)
{
flag_zel_led++;
if(flag_zel_led > 59)
{
flag_zel_led = 0;
flag_disp = 0;
D7_Low;
analogWrite(buzzerPin, 255);
delay_ms(5);
analogWrite(buzzerPin, 0);
}
}
disp();
}
t = rtc.getTime();
chas = t.hour,DEC;
minuta = t.min,DEC;
secunda = t.sec,DEC;
if(B1_flag)
{
if(chas == B1chas_vkl && minuta == B1minut_vkl)
{
buzz();
}
if(chas == B1chas_vkl && minuta == B1minut_vkl && secunda == 59)
{
B1minut_vkl = B1minut_vkl + 10;
if(B1minut_vkl > 59)
{
B1minut_vkl = 10;
B1chas_vkl++;
if(B1chas_vkl>23) B1chas_vkl=0;
}
}
}
} //END LOOP
void buzz()
{
if(B1_flag)
{
analogWrite(buzzerPin, 30);
delay_ms(100);
analogWrite(buzzerPin, 50);
delay_ms(100);
}
analogWrite(buzzerPin, 0);
delay_ms(100);
}
void disp()
{
if(!flag_disp)
{
ClockPoint = (~ClockPoint) & 0x01;
if(ClockPoint)tm1637.point(POINT_ON);
else tm1637.point(POINT_OFF);
TimeDisp[0] = chas / 10;
TimeDisp[1] = chas % 10;
TimeDisp[2] = minuta / 10;
TimeDisp[3] = minuta % 10;
tm1637.display(TimeDisp);
}
else
{
tm1637.point(POINT_ON);
BudDisp[0] = B1chas_vkl / 10;
BudDisp[1] = B1chas_vkl % 10;
BudDisp[2] = B1minut_vkl / 10;
BudDisp[3] = B1minut_vkl % 10;
tm1637.display(BudDisp);
}
}
Теперь возьмите пульт, выставите время (в этом скетче нет коррекции от большого компьютера) и передёрните ардуине питание. Если всё работает правильно, то на часах будет текущее время.
Ну и наконец скетч для работы с модулем часов и коррекцией времени:
#include "CyberLib.h"
#include "TM1637.h"
#define CLK 11 // пин 11
#define DIO 12 // пин 12
TM1637 tm1637(CLK,DIO);
#define ON 1
#define OFF 0
#include <DS3231.h>
#include <Wire.h>
DS3231 rtc(SDA, SCL);
Time t;
#include <IRstD.h>
IRrecvstd irrecvstd(4);
decode_resultsstd res_std;
#define MAXMILLIS 4294967295
unsigned long timme;
unsigned long timelapsed = 0;
int chas = 0;
int minuta = 0;
int secunda = 0;
///////////// B1 ////////////////////
uint8_t B1_flag = ReadEEPROM_Byte(1);
uint8_t B1chas_vkl = ReadEEPROM_Byte(2);
uint8_t B1minut_vkl = ReadEEPROM_Byte(3);
uint8_t val_shim = ReadEEPROM_Byte(4);
uint8_t flag_disp = 0;
uint8_t flag_zel_led = 0;
int buzzerPin = 5;
int8_t TimeDisp[] = {0x00,0x00,0x00,0x00};
int8_t BudDisp[] = {0x00,0x00,0x00,0x00};
unsigned char ClockPoint = 1;
void setup()
{
tm1637.set(val_shim);
tm1637.init();
pinMode(buzzerPin, OUTPUT);
D7_Out;
D7_Low;
D10_Out;
if(B1_flag) D10_High;
else D10_Low;
Serial.begin(57600);
irrecvstd.enableIRInstd();
rtc.begin();
}
void loop()
{
if(irrecvstd.decodestd(&res_std))
{
if(res_std.valuestd == 1886442794) // Прибавление часов
{
analogWrite(buzzerPin, 255);
chas++;
if(chas > 23) chas = 0;
rtc.setTime(chas, minuta, secunda);
disp();
analogWrite(buzzerPin, 0);
}
if(res_std.valuestd == 1886430554) // Убавление часов
{
analogWrite(buzzerPin, 255);
chas--;
if(chas < 1) chas = 0;
rtc.setTime(chas, minuta, secunda);
disp();
analogWrite(buzzerPin, 0);
}
if(res_std.valuestd == 1886397914) // Прибавление минут
{
analogWrite(buzzerPin, 255);
minuta++;
if(minuta > 59) minuta = 0;
rtc.setTime(chas, minuta, secunda);
disp();
analogWrite(buzzerPin, 0);
}
if(res_std.valuestd == 1886446874) // Убавление минут
{
analogWrite(buzzerPin, 255);
minuta--;
if(minuta < 1 || minuta > 60) minuta = 0;
rtc.setTime(chas, minuta, secunda);
disp();
analogWrite(buzzerPin, 0);
}
if(flag_disp && res_std.valuestd == 551521650) // Прибавление часов будильника
{
analogWrite(buzzerPin, 255);
B1chas_vkl++;
if(B1chas_vkl > 23) B1chas_vkl = 0;
WriteEEPROM_Byte(2, B1chas_vkl);
disp();
analogWrite(buzzerPin, 0);
}
if(flag_disp && res_std.valuestd == 551547150) // Убавление часов будильника
{
analogWrite(buzzerPin, 255);
B1chas_vkl--;
if(B1chas_vkl < 1 || B1chas_vkl > 24) B1chas_vkl = 0;
WriteEEPROM_Byte(2, B1chas_vkl);
disp();
analogWrite(buzzerPin, 0);
}
if(flag_disp && res_std.valuestd == 551489010) // Прибавление минут будильника
{
analogWrite(buzzerPin, 255);
B1minut_vkl++;
if(B1minut_vkl > 59) B1minut_vkl = 0;
WriteEEPROM_Byte(3, B1minut_vkl);
disp();
analogWrite(buzzerPin, 0);
}
if(flag_disp && res_std.valuestd == 551514510) // Убавление минут будильника
{
analogWrite(buzzerPin, 255);
B1minut_vkl--;
if(B1minut_vkl < 1 || B1minut_vkl > 60) B1minut_vkl = 0;
WriteEEPROM_Byte(3, B1minut_vkl);
disp();
analogWrite(buzzerPin, 0);
}
if(res_std.valuestd == 551505585) // Вкл/Откл будильник
{
analogWrite(buzzerPin, 255);
B1chas_vkl = ReadEEPROM_Byte(2);
B1minut_vkl = ReadEEPROM_Byte(3);
if(B1_flag)
{
B1_flag = 0;
D10_Low;
}
else
{
B1_flag = 1;
D10_High;
}
disp();
WriteEEPROM_Byte(1, B1_flag);
analogWrite(buzzerPin, 0);
}
if(res_std.valuestd == 551521905) // Вывод будильника на дисплей
{
analogWrite(buzzerPin, 255);
flag_zel_led = 0;
if(flag_disp)
{
flag_disp = 0;
D7_Low;
}
else
{
flag_disp = 1;
D7_High;
}
disp();
analogWrite(buzzerPin, 0);
}
if(res_std.valuestd == 551525475) // Подсветка +
{
analogWrite(buzzerPin, 255);
val_shim++;
if(val_shim > 7) val_shim = 7;
WriteEEPROM_Byte(4, val_shim);
tm1637.set(val_shim);
disp();
delay_ms(10);
analogWrite(buzzerPin, 0);
}
if(res_std.valuestd == 551519355) // Подсветка -
{
analogWrite(buzzerPin, 255);
val_shim--;
if(val_shim < 1 || val_shim > 254) val_shim = 0;
WriteEEPROM_Byte(4, val_shim);
tm1637.set(val_shim);
disp();
delay_ms(10);
analogWrite(buzzerPin, 0);
}
if(res_std.valuestd == 551519865) // +10 минут отсрочка
{
analogWrite(buzzerPin, 255);
B1minut_vkl = B1minut_vkl + 10;
if(B1minut_vkl > 59)
{
B1minut_vkl = 10;
B1chas_vkl++;
if(B1chas_vkl>23) B1chas_vkl=0;
}
delay_ms(5);
analogWrite(buzzerPin, 0);
flag_disp = 1;
D7_High;
disp();
delay_ms(300);
flag_disp = 0;
D7_Low;
}
//Serial.println(res_std.valuestd); // Удалить после программирования пульта
irrecvstd.resumestd();
res_std.valuestd = 0;
}
unsigned long currtime = millis();
if(currtime > timme) timelapsed = (currtime - timme);
else timelapsed = (MAXMILLIS - timme + currtime);
if(timelapsed > 999)
{
timme = currtime;
if(flag_disp)
{
flag_zel_led++;
if(flag_zel_led > 59)
{
flag_zel_led = 0;
flag_disp = 0;
D7_Low;
analogWrite(buzzerPin, 255);
delay_ms(5);
analogWrite(buzzerPin, 0);
}
}
secunda++;
if(secunda > 59)
{
secunda=0;
minuta++;
if(minuta > 59)
{
minuta=0;
chas++;
if(chas>23) chas=0;
}
}
if(chas == 0 && minuta == 0 && secunda == 10)
{
Serial.print('T');
Serial.print('\n');
delay_ms(200);
}
disp();
}
t = rtc.getTime();
chas = t.hour,DEC;
minuta = t.min,DEC;
secunda = t.sec,DEC;
if(B1_flag)
{
if(chas == B1chas_vkl && minuta == B1minut_vkl)
{
buzz();
}
if(chas == B1chas_vkl && minuta == B1minut_vkl && secunda == 59)
{
B1minut_vkl = B1minut_vkl + 10;
if(B1minut_vkl > 59)
{
B1minut_vkl = 10;
B1chas_vkl++;
if(B1chas_vkl>23) B1chas_vkl=0;
}
}
}
if(Serial.available()>4)
{
byte descript[5];
char ot_irserver[10] = {0,};
if (Serial.read()=='Y')
{
for (byte i=0; i < 4; i++)
{
descript[i] = Serial.read();
}
byte i = 0;
if((descript[0] =='+') && (descript[1] =='=') && (descript[2] =='Z'))
{
switch (descript[3])
{
case 'T':
delay_ms(3);
while(Serial.available())
{
delay_ms(1);
ot_irserver[i] = Serial.read();
if(ot_irserver[i] == ':')
{
ot_irserver[i] = ' ';
}
if(ot_irserver[i] == '\n')
{
ot_irserver[i] = 0;
break;
}
i++;
}
sscanf(ot_irserver, "%d%d%d", &chas, &minuta, &secunda);
rtc.setTime(chas, minuta, secunda);
for(int i=0; i < 64; i++)
{
Serial.read();
}
break;
default:
break;
}
}
else
{
for(byte i=0; i < 128; i++)
{
Serial.read();
}
}
}
}
} //END LOOP
void buzz()
{
if(B1_flag)
{
analogWrite(buzzerPin, 30);
delay_ms(100);
analogWrite(buzzerPin, 50);
delay_ms(100);
}
analogWrite(buzzerPin, 0);
delay_ms(100);
}
void disp()
{
if(!flag_disp)
{
ClockPoint = (~ClockPoint) & 0x01;
if(ClockPoint)tm1637.point(POINT_ON);
else tm1637.point(POINT_OFF);
TimeDisp[0] = chas / 10;
TimeDisp[1] = chas % 10;
TimeDisp[2] = minuta / 10;
TimeDisp[3] = minuta % 10;
tm1637.display(TimeDisp);
}
else
{
tm1637.point(POINT_ON);
BudDisp[0] = B1chas_vkl / 10;
BudDisp[1] = B1chas_vkl % 10;
BudDisp[2] = B1minut_vkl / 10;
BudDisp[3] = B1minut_vkl % 10;
tm1637.display(BudDisp);
}
}
На этом пожалуй всё.
Вступайте в Telegram-группу Arduino
- +306
- stD
45939
Поддержать автора
Комментарии (17)
'ReadEEPROM_Byte' was not declared in this scope и останавливается на строке \B1chas_vkl = ReadEEPROM_Byte(2);\ хотя в начале она вроде определена. Какая то тут хитрость закралась.
Библиотеку CyberLib установили?