- дисплей
- контролер
- Цифровий датчик температури і вологості
- 3D-джойстик
- Пьезодінамік
- релейний модуль
- Годинник реального часу
- Елемент живлення
- Технічні характеристики
- Електрична схема
- Монтажна схема
- Друкована плата
Наша сеть партнеров Banwar
Те, що у вас вже є, ви можете видалити в кошику.
Сьогодні зберемо годинник з використанням модуля реального часу. А щоб ускладнити завдання зробимо з них будильник і прикрутимо релейний модуль ну, наприклад, для включення світла у ванній або чайника. А якщо ти початківець техноманіяк, то не зайвим буде датчик температури і вологості. Вийде якась метеостанція керуюча чайником або таймер який стане в нагоді якщо потрібно автоматично годувати рибок, перевертати яйця в інкубаторі або запалювати ялинку на новий рік.
Як заліза будемо використовувати Амперкіни трійки, іскру і дюймовий OLED дисплей.
дисплей
0.96inch OLED (A) - це вбудований двоколірний (жовтий / синій) OLED дисплей з інтерфейсом I2C / SPI. Дозвіл екрану 128х64 пікселів, а кут огляду більше 160 градусів.
Розміри плати 29мм х 33 мм.
контролер
Iskra Mini - повноцінна Arduino-платформа, тільки маленька: всього 33 × 20 мм.
Зверніть увагу, що на платі немає власного USB-порту.
Тому для її прошивки знадобиться посередник!
Їм може бути інший контролер Arduino
Характеристики Iskra Mini
- Мікроконтролер: ATmega328
- Тактова частота: 16 МГц
- Флеш-пам'ять: 32 КБ (2 КБ використовуються загрузчиком)
- Оперативна пам'ять SRAM: 2 КБ
- Незалежна пам'ять EEPROM: 1 КБ
- Робоча напруга: 5 В
- Вхідна напруга: 5,3-12 В
- Портів введення-виведення загального призначення: 20
- Портів з підтримкою ШІМ: 6
- Портів, підключених до АЦП: 8 (4 з них на нераспаянних висновках)
- Розрядність АЦП: 10 біт
- Апаратні інтерфейси: UART, SPI, I²C (на нераспаянних висновках)
- Максимальний струм одного висновку: 40 мА
- Максимальний струм з пина + 5V: 150 мА
Цифровий датчик температури і вологості
Troyka-Temperature Humidity Sensor DHT11.
Дані температури і вологості датчик віддає по одному дроту у вигляді цифрового сигналу. Це дозволяє передавати дані на відстань до декількох десятків метрів.
У серці модуля - популярна серед любителів сенсорна збірка DHT11. Він працює за власним протоколу. На борту модуля - популярна серед любителів сенсорна збірка DHT11.
Характеристики
- Напруга живлення: 3-5 В
- Струм при запиті даних: 2,5 мА
- Струм в очікуванні: 100 мкА
- Діапазон температур: 0-50 ° С
- Похибка температури: ± 2 ° С
- Діапазон вологості: 20-90%
- Похибка вологості: ± 5%
- Габарити: 25 × 25 мм
3D-джойстик
3D Joystick - зробить управління нашим пристроєм швидким і зручним.
Модуль-джойстик схожий з «грибочком» на маніпуляторах PlayStation і XBox. Він комбінує в собі двовісний джойстик і тактову кнопку. У нейтральному положенні аналоговий сигнал відповідає половині напруги живлення. При переміщенні джойстика в одну сторону напруга буде наростати, а при русі джойстика в іншу сторону - падати. Таким чином, можна отримувати точне положення ручки джойстика і реагувати на кут нахилу, а не тільки на сам факт нахилу ручки. Хоча в цьому проекті ми використовуємо тільки факт нахилу.
Характеристики
- Напруга живлення: 3-5 В
- Інтерфейс по осях X, Y: аналоговий, лінійний
- Інтерфейс кнопки: цифровий, бінарний
- Габарити: 25 × 25 мм
управління джойстиком
Натискання вліво - вхід в меню налаштувань
змінюване значення підсвічується
натискання вгору - зміна значення
натискання вправо - перехід до наступного значенням
при настройки будильника зліва з'являється значок "а"
натискання вліво - вихід з меню зі збереженням змін
час будильника зберігається в незалежній пам'яті
Натискання вниз - вкл / викл будильника
Коли спрацював будильник
перше натискання на кнопку - відключення пищалки
друге натиснення на кнопку - відключення реле
Пьезодінамік
У нашому проекті потрібно пищати. Скористаємося модулем Buzzer.
Характеристики
- Номінальна частота: 4 кГц
- Інтенсивність: 80 дБ
- Номінальна робоча напруга: 5 В
- Габарити: 25,4 × 25,4 мм
релейний модуль
Модуль Relay це просто механічний рубильник, яким можна керувати за допомогою мікроконтролера, такого як Arduino. За допомогою реле можна включати і вимикати електроприлади, які підключені до побутової електромережі 220 В. На модулі розташований світлодіод, який завжди підкаже - замкнуто реле чи ні.
У цього реле є є не тільки нормально розімкнутий (NO) контакт, але і нормально замкнутий (NC). Це зручно.
Характеристики
- Номінальна напруга живлення: 5 В
- Номінальна напруга сигналу: 3-5 В
- Максимальний струм комутації: 16 А
- Коммутируемое змінну напругу (пікове): 250 В
- Струм: 87 мА
- Робоча температура: -40 ... + 85 ° C
- Магнітна система котушки: моностабільний
- Рекомендована частота перемикання: до 1 Гц
- Електрична зносостійкість (NO) контакту: 30 × 10³ перемикань
- Електрична зносостійкість (NC) контакту: 10 × 10³ перемикань
- Габарити: 50,8 × 25,4 мм
Годинник реального часу
Модуль RTC - зроблений на основі популярного чіпа DS1307. Він спілкується з керуючою електронікою по протоколу I²C / TWI.
Слот призначений для годинникової батарейки розміру CR1225 на 3В. Без неї модуль не працює навіть із зовнішнім живленням.
Характеристики
- Напруга зовнішнього живлення: 4,5-5,5 В
- Напруга живлення батарейки: 2-3,5 В
- Струм: 500 нА (≈6 місяців на батарейці)
- Вихідний інтерфейс: I²C
- Габарити: 25,4 × 25,4 мм
Елемент живлення
CR1225 - літієва батарейка
Характеристики
- Напруга: 3В
- Типорозмір cr1225
Технічні характеристики
Індикація Дата, місяць, години, хвилини, температура, вологість Точність часу, секунд / добу 2 Діапазон температур 0-50 ° С Похибка температури ± 2 ° С Діапазон вологості 20-90% Похибка вологості ± 5% Максимальний струм комутації 16 А Комутоване змінна напруга (пікове) 250 В Номінальна напруга живлення 5 В
Електрична схема
Монтажна схема
У цьому проекті немає.
Друкована плата
У цьому проекті немає.
#include <DS1307RTC.h> #include <Time.h> #include <Wire.h> #include <PinChangeInt.h> #include <EEPROM.h> #include "clock.h" #include <Adafruit_SSD1306.h> # include <Adafruit_GFX.h> #include <TroykaDHT11.h> #include <TimerOne.h> #include <Tone.h> volatile boolean JoyStickZPressFlag = false; byte AlarmHour = 7; byte AlarmMinute = 0; boolean AlarmFlag; boolean AlarmSetFlag; volatile boolean UpdateScreenFlag = false; Adafruit_SSD1306 display (OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS); DHT11 dht (TEMP_SEN_PIN); Tone Buzzer; void setup () {digitalWrite (JOYSTICK_Z_PIN, HIGH); PCintPort :: attachInterrupt (JOYSTICK_Z_PIN, & JOYSTICK_Z_PIN_ISR, FALLING); pinMode (RELAY_PIN, OUTPUT); digitalWrite (RELAY_PIN, LOW); // pinMode (BUZZER_PIN, OUTPUT); // digitalWrite (BUZZER_PIN, LOW); Buzzer.begin (BUZZER_PIN); AlarmHour = EEPROM.read (ALARM_HOUR_ADR); if (AlarmHour> 23) AlarmHour = 7; AlarmMinute = EEPROM.read (ALARM_MINT_ADR); if (AlarmMinute> 59) AlarmMinute = 0; AlarmFlag = EEPROM.read (ALARM_FLAG_ADR); if (AlarmFlag> 1) AlarmFlag = ALARM_FLAG_DEFAULT; Wire.begin (); tmElements_t CurTime; RTC.read (CurTime); dht.begin (); display.begin (SSD1306_SWITCHCAPVCC); UpdateScreenFlag = true; // період оновлення екрану по перериванню таймера Timer1.initialize (8000000); Timer1.attachInterrupt (TimerOne_ISR); } // --------------------------------- void loop () {static tmElements_t CurrentTime; if (UpdateScreenFlag) // якщо оновлення екрану {RTC.read (CurrentTime); // читання часу з RTC display.clearDisplay (); // очищення дисплея UpdateTime (& CurrentTime); // оновлення часу UpdateDate (& CurrentTime); // оновлення дати UpdateTemp (); // оновлення показань температури і вологості if (AlarmFlag) // якщо включений будильник {// відображення символу "а" display.setTextSize (ALARM_SIZE); display.setCursor (ALARM_HOR_POS, ALARM_VER_POS); display.print ( "a"); } Display.display (); // відображення на дисплеї оновленої інформації if (AlarmFlag) // якщо включений будильник CheckAlarm (& CurrentTime); // перевірка часу UpdateScreenFlag = false; // стирання прапора оновлення екрану} switch (ScanJoyStick ()) // перевірка натискання джойстівка {case JOYSTICK_LEFT_: // якщо вліво ChangeSettings (); // меню налаштувань break; case JOYSTICK_DOWN_: // якщо вниз ChangeAlarmState (& CurrentTime); // вкл / викл будильник break; default: break; } If ((JoyStickZPressFlag) && (digitalRead (RELAY_PIN))) // якщо натиснута кнопка джойстика {delay (100); if (! digitalRead (JOYSTICK_Z_PIN)) {static byte JoyStickZPressCnt = 0; if (JoyStickZPressCnt == 0) // якщо перше натискання {// digitalWrite (BUZZER_PIN, LOW); Buzzer.stop (); // вимикання пищалки JoyStickZPressCnt ++; } Else if (JoyStickZPressCnt == 1) // якщо друге натиснення {digitalWrite (RELAY_PIN, LOW); // вимикання реле JoyStickZPressCnt = 0; } JoyStickZPressFlag = false; // стирання прапора натискання кнопки джойстика}}} // --------------------------------- void UpdateTime (tmElements_t * TimeVal) {display.setTextColor (WHITE); // установка неінверсного відображення display.setTextSize (TIME_SIZE); // установка розміру тексту display.setCursor (HOUR_HOR_POS, HOUR_VER_POS); // установка курсору // висновок часу if (TimeVal-> Hour <10) display.print ( "0"); display.print (TimeVal-> Hour); display.print ( ":"); if (TimeVal-> Minute <10) display.print ( "0"); display.print (TimeVal-> Minute); } // --------------------------------- void UpdateDate (tmElements_t * TimeVal) {display.setTextColor (WHITE) ; display.setTextSize (TEMP_SIZE); display.setCursor (DATE_HOR_POS, DATE_VER_POS); // вивід дати if (TimeVal-> Day <10) display.print ( "0"); display.print (TimeVal-> Day); display.print ( "/"); if (TimeVal-> Month <10) display.print ( "0"); display.print (TimeVal-> Month); } // --------------------------------- void UpdateTemp () {display.setTextColor (WHITE); display.setTextSize (TEMP_SIZE); display.setCursor (TEMP_HOR_POS, TEMP_VER_POS); if (dht.read () == DHT_OK) // якщо читання даних без помилок {// висновок температури і вологості display.print ( "t"); display.print (dht.getTemperatureC ()); display.print ( "C"); display.print ( "h"); display.print (dht.getHumidity ()); display.print ( "%"); } Else // інакше {// висновок написи "Chip & Dip" display.print ( "Chip & Dip"); }} // --------------------------------- void CheckAlarm (tmElements_t * TimeVal) {// якщо будильник НЕ включений і збіг часу будильника з поточним часом if ((! AlarmSetFlag) && (TimeVal-> Hour == AlarmHour) && (TimeVal-> Minute == AlarmMinute)) {digitalWrite (RELAY_PIN, HIGH); // включення реле // digitalWrite (BUZZER_PIN, HIGH); Buzzer.play (NOTE_A3); // включення пищалки AlarmSetFlag = true; // установка прапора включення будильника} // інакше else if ((AlarmSetFlag) && ((TimeVal-> Hour! = AlarmHour) || (TimeVal-> Minute! = AlarmMinute))) AlarmSetFlag = false; // стирання прапора включення будильника} // --------------------------------- void ChangeSettings () {tmElements_t tm; RTC.read (tm); byte TimeParts [6] = {tm.Hour, tm.Minute, AlarmHour, AlarmMinute, tm.Day, tm.Month}; byte TimeMAXVals [6] = {23, 59, 23, 59, 31, 12}; byte CurTimePart = 0; boolean ExitSetUp = false; // відображення початкового екрана налаштувань: // значення годин відображається инверсно display.clearDisplay (); UpdateTemp (); UpdateDate (& tm); display.setTextSize (TIME_SIZE); display.setCursor (HOUR_HOR_POS, HOUR_VER_POS); display.setTextColor (BLACK, WHITE); // інверсне відображення if (TimeParts [0] <10) display.print ( "0"); display.print (TimeParts [0]); display.setTextColor (WHITE); display.print ( ":"); if (TimeParts [1] <10) display.print ( "0"); display.print (TimeParts [1]); display.display (); delay (500); // цикл меню налаштувань while (! ExitSetUp) {delay (150); switch (ScanJoyStick ()) // перевірка натискання джойстівка {case JOYSTICK_UP_: // якщо вгору {// зміна значення на один TimeParts [CurTimePart] ++; if (TimeParts [CurTimePart]> TimeMAXVals [CurTimePart]) {TimeParts [CurTimePart] = 0; if (CurTimePart> 3) TimeParts [CurTimePart] = 1; }} Break; case JOYSTICK_RIGHT_: // якщо вправо {// перехід до наступного значення CurTimePart ++; if (CurTimePart> 5) CurTimePart = 0; } Break; case JOYSTICK_LEFT_: // якщо вліво ExitSetUp = true; // вихід з меню break; } // відображення на екрані // змінюване значення відображається инверсно // при налаштуванні будильника відображається символ "а" // змінюване значення визначає змінна CurTimePart: // CurTimePart = 0 - годинник часу // CurTimePart = 1 - хвилини часу // CurTimePart = 2 - годинник будильника // CurTimePart = 3 - хвилини будильника // CurTimePart = 4 - день // CurTimePart = 5 - місяць, см. визначення масиву TimeParts [] display.clearDisplay (); if (CurTimePart <= 3) {UpdateTemp (); display.setCursor (DATE_HOR_POS, DATE_VER_POS); if (TimeParts [4] <10) display.print ( "0"); display.print (TimeParts [4]); display.print ( "/"); if (TimeParts [5] <10) display.print ( "0"); display.print (TimeParts [5]); display.setTextSize (TIME_SIZE); display.setCursor (HOUR_HOR_POS, HOUR_VER_POS); if ((CurTimePart% 2) == 0) {display.setTextColor (BLACK, WHITE); // інверсне відображення if (TimeParts [CurTimePart] <10) display.print ( "0"); display.print (TimeParts [CurTimePart]); display.setTextColor (WHITE); display.print ( ":"); if (TimeParts [CurTimePart + 1] <10) display.print ( "0"); display.print (TimeParts [CurTimePart + 1]); } Else {if (TimeParts [CurTimePart - 1] <10) display.print ( "0"); display.print (TimeParts [CurTimePart - 1]); display.print ( ":"); display.setTextColor (BLACK, WHITE); // інверсне відображення if (TimeParts [CurTimePart] <10) display.print ( "0"); display.print (TimeParts [CurTimePart]); }} Else {display.setTextColor (WHITE); display.setTextSize (TIME_SIZE); display.setCursor (HOUR_HOR_POS, HOUR_VER_POS); if (TimeParts [2] <10) display.print ( "0"); display.print (TimeParts [2]); display.print ( ":"); if (TimeParts [3] <10) display.print ( "0"); display.print (TimeParts [3]); UpdateTemp (); display.setCursor (DATE_HOR_POS, DATE_VER_POS); if (CurTimePart == 4) {display.setTextColor (BLACK, WHITE); // інверсне відображення if (TimeParts [CurTimePart] <10) display.print ( "0"); display.print (TimeParts [CurTimePart]); display.setTextColor (WHITE); display.print ( "/"); if (TimeParts [CurTimePart + 1] <10) display.print ( "0"); display.print (TimeParts [CurTimePart + 1]); } Else {if (TimeParts [CurTimePart - 1] <10) display.print ( "0"); display.print (TimeParts [CurTimePart - 1]); display.print ( "/"); display.setTextColor (BLACK, WHITE); // інверсне відображення if (TimeParts [CurTimePart] <10) display.print ( "0"); display.print (TimeParts [CurTimePart]); }} If (CurTimePart> 1) {display.setTextColor (WHITE); display.setTextSize (ALARM_SIZE); display.setCursor (ALARM_HOR_POS, ALARM_VER_POS); display.print ( "a"); } Display.display (); } // будильник AlarmHour = TimeParts [2]; AlarmMinute = TimeParts [3]; // запис в пам'ять EEPROM.write (ALARM_HOUR_ADR, AlarmHour); EEPROM.write (ALARM_MINT_ADR, AlarmMinute); // установка часу в RTC tm.Second = 0; tm.Minute = TimeParts [1]; tm.Hour = TimeParts [0]; tm.Day = TimeParts [4]; tm.Month = TimeParts [5]; tm.Year = 16; RTC.write (tm); UpdateScreenFlag = true; // установка прапора оновлення екрану delay (500); } // --------------------------------- void ChangeAlarmState (tmElements_t * TimeVal) {display.clearDisplay (); if (! AlarmFlag) // якщо будильник вимкнений {AlarmFlag = true; // установка прапора включення будильника // відображення символу "а" display.setTextSize (ALARM_SIZE); display.setCursor (ALARM_HOR_POS, ALARM_VER_POS); display.print ( "a"); } Else // інакше {AlarmFlag = false; // стирання прапора включення будильника} EEPROM.write (ALARM_FLAG_ADR, AlarmFlag); // запис стану будильника в пам'ять UpdateTemp (); UpdateDate (TimeVal); UpdateTime (TimeVal); display.display (); delay (500); } // --------------------------------- byte ScanJoyStick () {byte Direction = JOYSTICK_RELEASED; unsigned int X_Val = analogRead (JOYSTICK_X_PIN); unsigned int Y_Val = analogRead (JOYSTICK_Y_PIN); if ((Y_Val> = 900) && (X_Val> = 400)) {Direction = JOYSTICK_UP_; } Else if ((Y_Val <= 400) && (X_Val> = 400)) {Direction = JOYSTICK_DOWN_; } Else if ((Y_Val> = 400) && (X_Val> = 900)) {Direction = JOYSTICK_RIGHT_; } Else if ((Y_Val> = 400) && (X_Val <= 400)) {Direction = JOYSTICK_LEFT_; } Return Direction; } // --------------------------------- void JOYSTICK_Z_PIN_ISR () {JoyStickZPressFlag = true; // установка прапора натискання кнопки джойстика} // --------------------------------- void TimerOne_ISR () {UpdateScreenFlag = true; // установка прапора оновлення екрану}