Для данной поделки были использованы:
1. Микроконтроллер Arduino Nano
2. 4 -сегментный дисплей для Arduino
3. Модуль часов реального времени DS1307
4. Модуль реле 5v
5. ИК приёмник
Ну и всякие другие мелочи наподобие, проводов корпуса и т.д.
Код: Выделить всё
#include <Wire.h>
#include "TM1637.h" // http://www.seeedstudio.com/wiki/File:DigitalTube.zip
#include <TimerOne.h> // библиотека аппаратного таймера
#include "IRremote.h"
IRrecv irrecv(2); // указываем вывод, к которому подключен приемник
decode_results results;
int relay=0; //для реле
// 7сигментный индикатор
#define CLK 6
#define DIO 7
byte brightness = 3; // яркость, от 0 до 3 (4 режима яркости, больше не получается)
// кнопки
#define keyHor 5
#define keyMin 4
#define keyBr 8
#define keyPL 3
TM1637 tm1637(CLK,DIO);
#define DS3231_I2C_ADDRESS 0x68
unsigned char ClockPoint = 1;
volatile boolean flag;
///// часы ..
byte decToBcd(byte val){
return ( (val/10*16) + (val%10) );
}
byte bcdToDec(byte val){
return ( (val/16*10) + (val%16) );
}
void setDateDs3231(byte second, // 0-59
byte minute, // 0-59
byte hour, // 1-23
byte dayOfWeek, // 1-7
byte dayOfMonth, // 1-28/29/30/31
byte month, // 1-12
byte year) // 0-99
{
Wire.beginTransmission(DS3231_I2C_ADDRESS);
Wire.write(0);
Wire.write(decToBcd(second));
Wire.write(decToBcd(minute));
Wire.write(decToBcd(hour));
Wire.write(decToBcd(dayOfWeek));
Wire.write(decToBcd(dayOfMonth));
Wire.write(decToBcd(month));
Wire.write(decToBcd(year));
Wire.endTransmission();
}
void getDateDs3231(byte *second,
byte *minute,
byte *hour,
byte *dayOfWeek,
byte *dayOfMonth,
byte *month,
byte *year)
{
Wire.beginTransmission(DS3231_I2C_ADDRESS);
Wire.write(0);
Wire.endTransmission();
Wire.requestFrom(DS3231_I2C_ADDRESS, 7);
*second = bcdToDec(Wire.read() & 0x7f);
*minute = bcdToDec(Wire.read());
*hour = bcdToDec(Wire.read() & 0x3f);
*dayOfWeek = bcdToDec(Wire.read());
*dayOfMonth = bcdToDec(Wire.read());
*month = bcdToDec(Wire.read());
*year = bcdToDec(Wire.read());
}
void blink() {
digitalWrite(12, !digitalRead(12));
flag = !flag;
tm1637.point(flag);
}
void setup() {
Serial.begin(9600); // выставляем скорость COM порта
irrecv.enableIRIn(); // запускаем прием
// Serial.begin(9600);
Wire.begin();
//pinMode(9,INPUT);
pinMode(13, OUTPUT);
pinMode(keyHor, INPUT_PULLUP);
pinMode(keyMin, INPUT_PULLUP);
pinMode(keyPL, INPUT_PULLUP);
pinMode(keyBr, INPUT_PULLUP);
tm1637.init();
tm1637.set(brightness);
attachInterrupt(0, blink, CHANGE);
Timer1.initialize(500000); // таймер на 500мс
Timer1.attachInterrupt(TimingISR);// привяжем процедуру к прерыванию таймера
}
// мигаем точками каждые 0,5с
void TimingISR()
{
ClockPoint = (~ClockPoint) & 0x01;
}
void loop(){
// мигаем точками каждые 0,5с
if(ClockPoint)tm1637.point(POINT_ON);
else tm1637.point(POINT_OFF);
// читаем время из модуля
byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
getDateDs3231(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
// забиваем массив значениями для отпарвки на экран
int8_t TimeDisp[4];
TimeDisp[0] = hour / 10;
TimeDisp[1] = hour % 10;
TimeDisp[2] = minute / 10;
TimeDisp[3] = minute % 10;
// обработка кнопок
if (!digitalRead(keyHor) && !digitalRead(keyPL)){ // часы
second = 0; // сбрасываем секунды
hour++; // пребавляем единицу к часам
if (hour > 23) hour = 0; // если вылезли за границы присваеваем 0
setDateDs3231(second, minute, hour, dayOfWeek, dayOfMonth, month, year); // пишим в модуль
delay(200);
}
if (!digitalRead(keyMin) && !digitalRead(keyPL)){ // минуты
second = 0;
minute++;
if (minute > 59) minute = 0;
setDateDs3231(second, minute, hour, dayOfWeek, dayOfMonth, month, year);
delay(200);
}
if (!digitalRead(keyBr) && !digitalRead(keyPL)){
brightness++;
if (brightness > 3) brightness = 0;
tm1637.set(brightness);
delay(500);
// отправляем массив на экран
}
tm1637.display(TimeDisp);
if ( irrecv.decode( &results )) // если данные пришли
{
if (results.value==0xFFB04F&&relay==0){// если нажата кнопка и реле выкл (relay = 0) код кнопки делайте свой
// digitalWrite( 9, HIGH); // так не получается (реле изначально вкл состояние)
pinMode (9, OUTPUT); // вкл реле (подключая пин 9)
relay=1;results.value=0;
}
if (results.value==0xFFB04F&&relay==1){// если нажата кнопка и реле вкл (relay = 1) (код кнопки делайте свой)
// digitalWrite( 9, LOW); // так не получается (реле изначально вкл состояние)
pinMode (9, INPUT); // выкл реле (отключая пин 9)
relay=0;results.value=0;
}
irrecv.resume(); // принимаем следующую команду
}
}
Имеется возможность установки времени кнопками. Также можно регулировать яркость дисплея. На схеме указана лампочка, я же сделал розетку и запрограммировал включение через ИК приемник пультом от телевизора. Благодаря модулю часов реального времени DS1307, при отключении питания, время не сбрасывается, а продолжает идти.
phpBB [media]