Рассматриваемые в данной статье часы реального времени на основе платы Arduino представляют собой цифровые часы, которые показывают реальное (истинное) время на основе использования RTC IC DS1307 (микросхема часов истинного времени), которая работает по протоколу I2C. Часы реального (истинного) времени означают что они будут работать (считать время) даже если возникнет проблема с электропитанием. Когда подача питания возобновится, часы будут показывать правильное (реальное) время независимо от того сколько времени они были без питания.
В этом проекте мы будем использовать ЖК дисплей 16x2 для отображения значения времени на нем в формате: час, минута, секунда, дата, месяц и год. Также в наш проект часов реального времени добавлена опция будильника – мы можем устанавливать время "пробуждения". Время будильника будет записываться в энергонезависимую память EEPROM платы Arduino, поэтому оно будет сохраняться там даже при отключении питания. Подобные часы реального времени часто используются в наших компьютерах чтобы они могли обновляться в режиме реального времени.
Протокол I2C является способом объединения двух или более устройств в единую систему при помощи двух проводников, поэтому этот протокол также называется двухпроводным протоколом. Его можно использовать для соединения до 127 устройств в единое устройство или процессор. Большинство устройств на основе протокола I2C работает на частоте 100 кГц.
Необходимые шаги для записи данных от ведущего (master) к ведомому (slave) в протоколе I2C (slave receiving mode - режим приема для ведомого):
1. Передать состояние (команду) START к ведомому.
2. Передать адрес ведомого к ведомому устройству.
3. Передать бит (0) к ведомому.
4. Принять бит ACK (подтверждения) от ведомого.
5. Передать адрес слова (words address) ведомому.
6. Принять бит ACK (подтверждения) от ведомого.
7. Передать данные ведомому.
8. Принять бит ACK (подтверждения) от ведомого.
9. Передать команду STOP ведомому.
Шаги для чтения данных от ведомого (slave) к ведущему (master) в протоколе I2C (slave transmitting mode – режим передачи для ведомого):
1. Передать команду START ведомому.
2. Передать адрес ведомого к ведомому устройству.
3. Передать бит чтения (1) к ведомому.
4. Принять бит ACK (подтверждения) от ведомого.
5. Принять данные отведомого.
6. Принять бит ACK (подтверждения) от ведомого.
7. Передать команду STOP ведомому.
Работа схемы
Схема устройства представлена на следующем рисунке.
Схема построена на основе трех главных компонентов: микросхемы DS1307, платы Arduino Pro Mini и ЖК дисплея 16x2.
Плата Arduino используется для чтения времени от ds1307 и отображения его на ЖК дисплее 16x2. Микросхема DS1307 передает время/дату на Arduino используя 2 провода. Звонок (буззер) используется для подачи сигнала будильника. Структурная схема работы устройства приведена на следующем рисунке.
Как можно видеть из представленной схемы, контакты микросхемы DS1307 SDA и SCL соединены с контактами платы Arduino SDA и SCL с помощью подтягивающих резисторов которые поддерживают состояние высокого напряжения на этих линиях. Кварцевый генератор на 32.768 кГц подсоединен к микросхеме DS1307 для генерации точной 1-секундной задержки. Также батарейка на 3 В подсоединена к контакту 3 (BAT) микросхемы DS1307 чтобы обеспечивать подсчет времени во время отключения питания устройства.
ЖК дисплей 16x2 подключен к плате Arduino в 4-битном режиме. Его контакты управления RS, RW и En подключены к контактам Arduino 2, GND и 3. Контакты данных ЖК дисплея D0-D7 подключены к контактам 4, 5, 6, 7 платы Arduino. Звонок (буззер) подключен к контакту 13 Arduino при помощи NPN транзистора BC547 и резистора 1 кОм.
Три кнопки под названиями set, INC и Next используются для установки времени будильника и подключены к контактам 12, 11 и 10 платы Arduino. Когда мы будем нажимать кнопку set, будет включаться режим установки времени срабатывания будильника, в котором можно будет установить это время с помощью кнопок INC и Next.
Рассматриваемые часы реального времени с будильником на основе платы Arduino, собранные на макетной плате, показаны на следующем рисунке.
Исходный код программы
Для написания программы часов реального времени с будильником нам необходимо подключить ряд библиотек.
#include <Wire.h>
#include<EEPROM.h>
#include <RTClib.h>
#include <LiquidCrystal.h>
Затем в функции setup необходимо произвести инициализацию RTC (часов реального времени), ЖК дисплея, задать режимы работы ряда контактов.
Остальные необходимые функции, такие как считывание времени, установка времени срабатывания будильника и другие будут выполняться в функции void loop.
Далее представлен полный текст программы.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 |
#include <Wire.h> #include<EEPROM.h> #include <RTClib.h> #include <LiquidCrystal.h> LiquidCrystal lcd(3, 2, 4, 5, 6, 7); RTC_DS1307 RTC; int temp,inc,hours1,minut,add=11; int next=10; int INC=11; int set_mad=12; #define buzzer 13 int HOUR,MINUT,SECOND; void setup() { Wire.begin(); RTC.begin(); lcd.begin(16,2); pinMode(INC, INPUT); pinMode(next, INPUT); pinMode(set_mad, INPUT); pinMode(buzzer, OUTPUT); digitalWrite(next, HIGH); digitalWrite(set_mad, HIGH); digitalWrite(INC, HIGH); lcd.setCursor(0,0); lcd.print("Real Time Clock"); lcd.setCursor(0,1); lcd.print("Circuit Digest "); delay(2000); if(!RTC.isrunning()) { RTC.adjust(DateTime(__DATE__,__TIME__)); } } void loop() { int temp=0,val=1,temp4; DateTime now = RTC.now(); if(digitalRead(set_mad) == 0) // установка времени будильника { lcd.setCursor(0,0); lcd.print(" Set Alarm "); delay(2000); defualt(); time(); delay(1000); lcd.clear(); lcd.setCursor(0,0); lcd.print(" Alarm time "); lcd.setCursor(0,1); lcd.print(" has been set "); delay(2000); } lcd.clear(); lcd.setCursor(0,0); lcd.print("Time:"); lcd.setCursor(6,0); lcd.print(HOUR=now.hour(),DEC); lcd.print(":"); lcd.print(MINUT=now.minute(),DEC); lcd.print(":"); lcd.print(SECOND=now.second(),DEC); lcd.setCursor(0,1); lcd.print("Date: "); lcd.print(now.day(),DEC); lcd.print("/"); lcd.print(now.month(),DEC); lcd.print("/"); lcd.print(now.year(),DEC); match(); delay(200); } void defualt() { lcd.setCursor(0,1); lcd.print(HOUR); lcd.print(":"); lcd.print(MINUT); lcd.print(":"); lcd.print(SECOND); } /* функция для установки времени будильника и его загрузки в память eeprom*/ void time() { int temp=1,minuts=0,hours=0,seconds=0; while(temp==1) { if(digitalRead(INC)==0) { HOUR++; if(HOUR==24) { HOUR=0; } while(digitalRead(INC)==0); } lcd.clear(); lcd.setCursor(0,0); lcd.print("Set Alarm Time "); //lcd.print(x); lcd.setCursor(0,1); lcd.print(HOUR); lcd.print(":"); lcd.print(MINUT); lcd.print(":"); lcd.print(SECOND); delay(100); if(digitalRead(next)==0) { hours1=HOUR; EEPROM.write(add++,hours1); temp=2; while(digitalRead(next)==0); } } while(temp==2) { if(digitalRead(INC)==0) { MINUT++; if(MINUT==60) {MINUT=0;} while(digitalRead(INC)==0); } // lcd.clear(); lcd.setCursor(0,1); lcd.print(HOUR); lcd.print(":"); lcd.print(MINUT); lcd.print(":"); lcd.print(SECOND); delay(100); if(digitalRead(next)==0) { minut=MINUT; EEPROM.write(add++, minut); temp=0; while(digitalRead(next)==0); } } delay(1000); } /* Function to chack medication time – функция чтобы прервать ваш сон*/ void match() { int tem[17]; for(int i=11;i<17;i++) { tem[i]=EEPROM.read(i); } if(HOUR == tem[11] && MINUT == tem[12]) { beep(); beep(); beep(); beep(); lcd.clear(); lcd.print("Wake Up........"); lcd.setCursor(0,1); lcd.print("Wake Up......."); beep(); beep(); beep(); beep(); } } /* функция включения буззера */ void beep() { digitalWrite(buzzer,HIGH); delay(500); digitalWrite(buzzer, LOW); delay(500); } |