"Умные часы"
от Metalismatic
Сегодня сказ пойдет о бесполезнейшей поделке - о часах и работе с датчиками, в общем о том, как я лепил велосипед и сделал часы. Данные часы работают на базе ардуино. Они измеряют температуру(погрешность 1-2 градуса), влажность и проверяют воздух на наличие углекислого газа(что лично для меня немаловажно). Да, с одной стороны вы можете смело кидаться помидорками и кричать с пеной у рта, что глупо и бесполезно, но не торопитесь. Ведь по факту мы рассмотрим относительно примитивную систему умного дома(если чуть-чуть допилить).
Компоненты
Ну, давайте по порядку, из чего же точно состоят наши часы? Вот примерный список стоимости необходимых компонентов:
arduino(подойдет абсолютно любая) - 200 рублей
12864 v2(дисплей) - 500 рублей
aht10 - 100 рублей
mq135 - 100 рублей
динамик - 5 рублей
Датчик напряжения 0-25В - 20 рублей
повышающий преобразователь напряжения - 40р
модуль часов реального времени - 130 рублей
2 аккумулятора 18560(1200мА/ч каждая батарейка) с платой зарядки tp4056 - 200 рублей
тактовая кнопка - 15 рублей
Подготовка к сборке
aht10, модуль часов - подключаются через I2C. Для того, чтобы подключить 2 или более датчика на один разъем нам нужен хаб/макетка, ну и конечно знать адреса наших модулей(в случае использования других датчиков не из моей статьи). Для этого подключаем наши модули и запускаем скетч:
Далее переходим к нашему замечательному дисплею, единственному в своем роде для ардуинки(больше и удобнее дисплея вам нигде не сыскать). Припаеваем проводки по схеме:
Далее берем датчик газа MQ135 и оставляем его на сутки:
Советую собрать вот такой тестовый агрегат для калибровки:
После чего нам необходимо будет замерить воздух на улице и вписать полученное значение в скетч. Предельно допустимые значения воздуха в помещении до 1100 ppm, с этого значения и выше - начинает болеть голова.
Ну и как же без красочной 8 битной музыки на оповещении о превышении углекислого газа? Для этого советую воспользоваться сервисом по конвертированию midi файлов в код:
https://extramaster.net/tools/midiToArduino/
В моем примере ее не будет, но вы запросто можете добавить ее в свой проект
Часы настраиваем с помощью скетча:
Сборка
Собираем вот такой модуль питания состоящий из 18650, платы tp4056 и преобразователя напряжения(при сборке по моей схеме, выходное напряжение получается в районе 3,6В, что мало для нашей системы, поэтому мы повысим его до 12В и подадим напрямую в ардуино, на вход VIN
)
В целом в сборке нет ничего сложного, как и ранее писал, датчик температуры и модуль часов подключаем через I2C, выводим 5В и землю на макетку, дисплей подключаем по схеме, кроме контакта на яркость BLA, его я запитал от 9 пина, для реализации включения подсветки дисплея при нажатии на кнопку(загорается у меня на 30 секунд):
В чем универсальность данного проекта? По факту через разъем i2c можно прикрутить бесконечное количество датчиков и всю эту лабуду выводить на сервер через NodeMCU и на основе полученных данных, что-то делать, к примеру, можно сделать пожарную сигнализацию, а если углубиться и запариться создать сеть из датчиков с общим выводом данных на единый сервер на NodeMCU.
Данный проект был задуман изначально как проверка себя, на сколько я смогу далеко зайти и не более того. Да это велосипед, но он мой.
и на последок вот весь исходник:
Оригинального в коде нет ничего, я не знаю язык C, но черт возьми, даже у меня получилось сделать это. Проект ни у кого не тырил, полностью оригинальный продукт. Если зайдет вам такой стиль изложения и будет интересно, то могу ответить на вопросы о сборке и напишу новую статью о сборке умного дома на raspberry и ардуино(сейчас в процессе)
Компоненты
Ну, давайте по порядку, из чего же точно состоят наши часы? Вот примерный список стоимости необходимых компонентов:
arduino(подойдет абсолютно любая) - 200 рублей
12864 v2(дисплей) - 500 рублей
aht10 - 100 рублей
mq135 - 100 рублей
динамик - 5 рублей
Датчик напряжения 0-25В - 20 рублей
повышающий преобразователь напряжения - 40р
модуль часов реального времени - 130 рублей
2 аккумулятора 18560(1200мА/ч каждая батарейка) с платой зарядки tp4056 - 200 рублей
тактовая кнопка - 15 рублей
Подготовка к сборке
aht10, модуль часов - подключаются через I2C. Для того, чтобы подключить 2 или более датчика на один разъем нам нужен хаб/макетка, ну и конечно знать адреса наших модулей(в случае использования других датчиков не из моей статьи). Для этого подключаем наши модули и запускаем скетч:
- #include <Wire.h>
- void setup() {
- Wire.begin();
- Serial.begin(9600);
- while (!Serial);
- Serial.println("\nI2C Scanner");
- }
- void loop(){
- byte error, address;
- int nDevices;
- Serial.println("Scanning...");
- nDevices = 0;
- for(address = 8; address < 127; address++ ){
- Wire.beginTransmission(address);
- error = Wire.endTransmission();
- if (error == 0) {
- Serial.print("I2C device found at address 0x");
- if (address<16)
- Serial.print("0");
- Serial.print(address,HEX);
- Serial.println(" !");
- nDevices++;
- }
- else if (error==4) {
- Serial.print("Unknow error at address 0x");
- if (address<16)
- Serial.print("0");
- Serial.println(address,HEX);
- }
- }
- if (nDevices == 0)
- Serial.println("No I2C devices found\n");
- else
- Serial.println("done\n");
- delay(5000);
- }
Далее переходим к нашему замечательному дисплею, единственному в своем роде для ардуинки(больше и удобнее дисплея вам нигде не сыскать). Припаеваем проводки по схеме:
Далее берем датчик газа MQ135 и оставляем его на сутки:
- // библиотека для работы с датчиками MQ (Troyka-модуль)
- #include <TroykaMQ.h>
- // имя для пина, к которому подключен датчик
- #define PIN_MQ135 A0
- // имя для пина, к которому подключен нагреватель датчика
- #define PIN_MQ135_HEATER 11
- // создаём объект для работы с датчиком
- // и передаём ему номер пина выходного сигнала и нагревателя
- MQ135 mq135(PIN_MQ135);
- void setup() {
- // открываем последовательный порт
- Serial.begin(9600);
- // включаем нагреватель
- mq135.heaterPwrHigh();
- Serial.println("Heated sensor");
- }
- void loop()
- {
- // если прошёл интервал нагрева датчика
- // и калибровка не была совершена
- if (!mq135.isCalibrated() && mq135.heatingCompleted()) {
- // выполняем калибровку датчика на чистом воздухе
- mq135.calibrate();
- // если известно сопротивление датчика на чистом воздухе
- // можно его указать вручную, допустим 160
- // mq135.calibrate(160);
- // выводим сопротивление датчика в чистом воздухе (Ro) в serial-порт
- Serial.print("Ro = ");
- Serial.println(mq135.getRo());
- }
- // если прошёл интевал нагрева датчика
- // и калибровка была совершена
- if (mq135.isCalibrated() && mq135.heatingCompleted()) {
- // выводим отношения текущего сопротивление датчика
- // к сопротивлению датчика в чистом воздухе (Rs/Ro)
- Serial.print("Ratio: ");
- Serial.print(mq135.readRatio());
- // выводим значения газов в ppm
- Serial.print("\tCO2: ");
- Serial.print(mq135.readCO2());
- Serial.println(" ppm");
- delay(100);
- }
- }
Советую собрать вот такой тестовый агрегат для калибровки:
После чего нам необходимо будет замерить воздух на улице и вписать полученное значение в скетч. Предельно допустимые значения воздуха в помещении до 1100 ppm, с этого значения и выше - начинает болеть голова.
Ну и как же без красочной 8 битной музыки на оповещении о превышении углекислого газа? Для этого советую воспользоваться сервисом по конвертированию midi файлов в код:
https://extramaster.net/tools/midiToArduino/
В моем примере ее не будет, но вы запросто можете добавить ее в свой проект
Часы настраиваем с помощью скетча:
- #include <Wire.h>
- #include <TimeLib.h>
- #include <DS1307RTC.h>
- const char *monthName[12] = {
- "Jan", "Feb", "Mar", "Apr", "May", "Jun",
- "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
- };
- tmElements_t tm;
- void setup() {
- bool parse=false;
- bool config=false;
- // get the date and time the compiler was run
- if (getDate(__DATE__) && getTime(__TIME__)) {
- parse = true;
- // and configure the RTC with this info
- if (RTC.write(tm)) {
- config = true;
- }
- }
- Serial.begin(9600);
- while (!Serial) ; // wait for Arduino Serial Monitor
- delay(200);
- if (parse && config) {
- Serial.print("DS1307 configured Time=");
- Serial.print(__TIME__);
- Serial.print(", Date=");
- Serial.println(__DATE__);
- } else if (parse) {
- Serial.println("DS1307 Communication Error :-{");
- Serial.println("Please check your circuitry");
- } else {
- Serial.print("Could not parse info from the compiler, Time=\"");
- Serial.print(__TIME__);
- Serial.print("\", Date=\"");
- Serial.print(__DATE__);
- Serial.println("\"");
- }
- }
- void loop() {
- }
- bool getTime(const char *str)
- {
- int Hour, Min, Sec;
- if (sscanf(str, "%d:%d:%d", &Hour, &Min, &Sec) != 3) return false;
- tm.Hour = Hour;
- tm.Minute = Min;
- tm.Second = Sec;
- return true;
- }
- bool getDate(const char *str)
- {
- char Month[12];
- int Day, Year;
- uint8_t monthIndex;
- if (sscanf(str, "%s %d %d", Month, &Day, &Year) != 3) return false;
- for (monthIndex = 0; monthIndex < 12; monthIndex++) {
- if (strcmp(Month, monthName[monthIndex]) == 0) break;
- }
- if (monthIndex >= 12) return false;
- tm.Day = Day;
- tm.Month = monthIndex + 1;
- tm.Year = CalendarYrToTm(Year);
- return true;
- }
Сборка
Собираем вот такой модуль питания состоящий из 18650, платы tp4056 и преобразователя напряжения(при сборке по моей схеме, выходное напряжение получается в районе 3,6В, что мало для нашей системы, поэтому мы повысим его до 12В и подадим напрямую в ардуино, на вход VIN
)
В целом в сборке нет ничего сложного, как и ранее писал, датчик температуры и модуль часов подключаем через I2C, выводим 5В и землю на макетку, дисплей подключаем по схеме, кроме контакта на яркость BLA, его я запитал от 9 пина, для реализации включения подсветки дисплея при нажатии на кнопку(загорается у меня на 30 секунд):
- if (val=val>=600){
- m=100;
- n=1;
- analogWrite(6, 110);
- }
- m=m-n;
- if(m<=0){
- digitalWrite(6, LOW);
- n=0;
- }
В чем универсальность данного проекта? По факту через разъем i2c можно прикрутить бесконечное количество датчиков и всю эту лабуду выводить на сервер через NodeMCU и на основе полученных данных, что-то делать, к примеру, можно сделать пожарную сигнализацию, а если углубиться и запариться создать сеть из датчиков с общим выводом данных на единый сервер на NodeMCU.
Данный проект был задуман изначально как проверка себя, на сколько я смогу далеко зайти и не более того. Да это велосипед, но он мой.
и на последок вот весь исходник:
- #include <U8glib.h>
- #include <Wire.h>
- #include <Thinary_AHT10.h>
- #include <TimeLib.h>
- #include <DS1307RTC.h>
- #include <TroykaMQ.h>
- #define PIN_MQ135 A0
- int analogInput = A1;
- float vout = 0.0;
- float vin = 0.0;
- float R1 = 30000.0; //
- float R2 = 7500.0; //
- float zarad=0;
- int value = 0;
- AHT10Class AHT10;
- MQ135 mq135(PIN_MQ135);
- #define PIN_MQ135_HEATER 3
- U8GLIB_ST7920_128X64_1X u8g(10); // Создаём объект u8g для работы с дисплеем, указывая номер вывода CS для аппаратной шины SPI
- uint32_t timeStart; // Объявляем переменную для подсчёта количества секунд прошедших с момента старта скетча
- uint8_t timeHours; // Объявляем переменную для вывода часов прошедших с момента старта скетча
- uint8_t timeMinutes; // Объявляем переменную для вывода минут прошедших с момента старта скетча
- uint8_t timeSeconds;
- int analogPin = 3; // номер порта к которому подключен потенциометр
- int val = 0; // переменная для хранения считываемого значения
- int m=0;
- int n=0;
- void setup()
- {
- Serial.begin(9600); // установка связи по serial
- mq135.heaterPwrHigh();
- pinMode(analogInput, INPUT);
- mq135.calibrate();
- Wire.begin();
- if(AHT10.begin(eAHT10Address_Low))
- Serial.println("Init AHT10 Sucess.");
- else
- Serial.println("Init AHT10 Failure.");
- }
- void loop (){
- value = analogRead(analogInput);
- vout = (value * 5.0) / 1024.0; // see text
- vin = vout / (R2/(R1+R2));
- zarad=10+(((vin-2.5)*100)/4.2);
- val = analogRead(analogPin); // считываем значение
- Serial.println(val);
- if (val=val>=600){
- m=100;
- n=1;
- analogWrite(6, 110);
- }
- m=m-n;
- if(m<=0){
- digitalWrite(6, LOW);
- n=0;
- }
- tmElements_t tm;
- u8g.firstPage(); // Всё что выводится на дисплей указывается в цикле: u8g.firstPage(); do{ ... команды ... }while(u8g.nextPage());
- do{ u8g.setColorIndex(1); // Выбираем белый цвет
- u8g.drawBox(0, 0, 128, 11); // Выводим прямоугольник с координатами левого верхнего угла 0,0 и размерами 128x11 пикселей
- u8g.drawBox(0, 53, 128, 11);
- u8g.setFont(u8g_font_6x10); // Выбираем шрифт u8g_font_6x10
- u8g.setColorIndex(0); // Выбираем цвет фона
- u8g.setPrintPos(82, 9); u8g.print(zarad);
- u8g.drawStr(115 , 9, "%");
- u8g.setPrintPos( 4, 62); u8g.print(AHT10.GetTemperature());
- u8g.drawStr(36, 62, "C");
- u8g.setPrintPos(46, 62); u8g.print(AHT10.GetHumidity());
- u8g.drawStr(77, 62, "%");
- u8g.drawStr(84, 62, "AIR");
- u8g.setPrintPos(102, 62); u8g.print(mq135.readCO2());
- u8g.setColorIndex(1); // Выбираем белый цвет
- u8g.setFont(u8g_font_courB24n); // Выбираем шрифт u8g_font_courB24n
- u8g.setPrintPos(35, 43); u8g.print(tm.Hour); // Выводим старший разряд часов в позиции 3х43
- u8g.drawStr ( 55, 43, ":"); // Выводим двоеточие в позиции 33х43
- u8g.setPrintPos( 65, 43); u8g.print(tm.Minute); // Выводим старший разряд минут в позиции 46х43
- // Выводим двоеточие в позиции 76х43
- } while(u8g.nextPage());
- }
Оригинального в коде нет ничего, я не знаю язык C, но черт возьми, даже у меня получилось сделать это. Проект ни у кого не тырил, полностью оригинальный продукт. Если зайдет вам такой стиль изложения и будет интересно, то могу ответить на вопросы о сборке и напишу новую статью о сборке умного дома на raspberry и ардуино(сейчас в процессе)