| Ваш IP: 3.236.132.132 | Online(30) - гости: 22, боты: 8 | Загрузка сервера: 0.85 ::::::::::::


Погодная станция + часы + будильник (Arduino)

На сайте уже есть несколько проектов погодных станций, но с появлением у меня высокоточного датчика AHT10 я решил снова разработать погодную станцию. Погодная станция как правило имеет возможность измерять температуру в помещении и на улице, давление и влажность. Дополнительно на дисплей будет выводится время и добавлена функция будильника.

В погодной станции используются следующие компоненты:

  • Датчик влажности и температуры AHT10 (модуль)
  • Датчик давления BMP280 (модуль)
  • Датчик температуры DS18B20
  • Часы реального времени DS3231 (модуль)
  • Дисплей LCD2004
  • Расширитель портов PCF8574 I2C который работает совместно с LCD2004 (модуль)
  • 5 кнопок
  • Пьезоизлучатель
  • Транзистор BC547
  • Резисторы 4,7 кОм 0,125 Вт 2 шт

Параметры датчиков:

  • AHT10
    • Напряжение питания: 1.8 В … 3.6 В для AHT10
    • Диапазон измерения температуры: -40°C .. + 85°C
    • Разрешающая способность по температуре: 0.01°C
    • Точность измерения температуры: ± 0.3°C
    • Диапазон измерения относительной влажности: 0% .. 100%
    • Разрешающая способность по влажности: 0,024%
    • Точность измерения относительной влажности: ± 2% при 25°C
    • Рекомендуемая частота опроса: 8 сек … 30 сек
  • BMP280
    • Напряжение питания: 1.71 В … 3.6 В
    • Интерфейс обмена данными: I2C или SPI
    • Ток потребления в рабочем режиме: 2.7 мкА при частоте опроса 1 Гц
    • Диапазон измерения атмосферного давления: 300hPa – 1100hPa (±0.12hPa), что эквивалентно диапазону от -500 до 9000 м над уровнем моря
    • Диапазон измерения температуры: -40°С … +85°С (±0.01°С)
    • Максимальная частота работы интерфейса I2C: 3.4 МГц
    • Максимальная частота работы интерфейса SPI: 10 МГц
  • DS18B20
    • Напряжение питания: 3 В … 5.5 В
    • Протокол обмена данными: 1-Wire
    • Способ подключения: прямой / по одной линии с паразитным питанием
    • Разрешение преобразования температуры: 9 бит – 12 бит
    • Диапазон измерения температуры: от -55 до +125 оС
    • Период измерения температуры при максимальной точности 12 бит: 750 мс
    • Тип индексации на линии 1-Wire: уникальный 64-битный адрес
  • DS3231
    • Напряжение питания: 3.3 В … 5 В
    • Чип памяти: AT24C32 (32 Кб)
    • Точность: ± 0.432 сек в день
    • Частота кварца:32.768 кГц
    • Поддерживаемый протокол: I2C

В погодной станции используется датчик DS18B20 в металлическом корпусе, он не имеет подтягивающего резистора который необходим для правильной работы, поэтому в схему добавлен подтягивающий резистор.

I2C модуль на базе микросхем PCF8574 позволяют подключить символьный дисплей 2004 к плате Arduino всего по двум проводам SDA и SCL (А4 и А5), что дает возможность не использовать цифровые выходы Arduino при подключении дисплея.

Данные с датчиков считываются каждые 10 секунд.

В качестве органов управления используются 5 кнопок, две из которых участвую в установке текущего времени и даты, эти кнопки редко используемые, поэтому выводить их на лицевую панель прибора не обязательно. Основные кнопки это кнопки отключения/включения будильника и коррекция времени будильника.

Для установки времени необходимо нажать и удерживать кнопку «УСТ. ВРЕМЯ» и нажимая на кнопки «ЧАСЫ / ДАТА» и «МИНУТЫ / МЕСЯЦ» установить часы и минуты. Рекомендую устанавливать на одну минуту больше положенного времени, это необходимо для точной установки секунд. При смене минуты необходимо удерживать кнопку «УСТ. ВРЕМЯ» и нажать на кнопку «ОБНУЛЕНИЕ СЕКУНД / ГОД / УСТ. БУДИЛЬНИКА».

Аналогичным образом устанавливается дата, месяц и год, только вместо кнопки «УСТ. ВРЕМЯ»  нужно нажать и удерживать кнопку «УСТ. ДАТА-МЕСЯЦ-ГОД»

Для установки времени будильника нужно нажать и удерживать кнопку «ОБНУЛЕНИЕ СЕКУНД / ГОД / УСТ. БУДИЛЬНИКА», а кнопками «ЧАСЫ / ДАТА» и «МИНУТЫ / МЕСЯЦ» установить часы и минуты срабатывания будильника.

Показания датчиков меняются на экране каждые пять секунд (время можно изменить в скетче), первоначально выводится дата, месяц, год и температура на улице.

Потом выводятся показания других датчиков: влажность, давление в мм.рт.ст и температуры в помещении.

#include <Wire.h> 
#include <SPI.h>
#include <LiquidCrystal_I2C.h> //Библиотека -  http://forum.rcl-radio.ru/misc.php?action=pan_download&item=45&download=1
#include <DS3231.h>//https://github.com/jarzebski/Arduino-DS3231/archive/master.zip // DS3231.zip
#include <Thinary_AHT10.h> // https://rcl-radio.ru/wp-content/uploads/2020/07/AHT10-master.zip
#include <Adafruit_BMP280.h> // https://rcl-radio.ru/wp-content/uploads/2018/08/Adafruit_BMP280.zip
#include <OneWire.h> // https://rcl-radio.ru/wp-content/uploads/2018/07/OneWire.zip
#include <DallasTemperature.h> // https://rcl-radio.ru/wp-content/uploads/2018/07/DallasTemperature.zip
#include <EEPROM.h> 
 
#define IND 5000 // время смены показаний датчиков
 
      LiquidCrystal_I2C lcd(0x27,20,4);  // Устанавливаем дисплей
      DS3231 clock;RTCDateTime DateTime;AHT10Class AHT10;
      Adafruit_BMP280 bmp(10);
      OneWire oneWire(A0);// вход датчика 18b20
      DallasTemperature temp(&oneWire);
 
      byte v1[8] = {7,7,7,7,7,7,7,7};
      byte v2[8] = {7,7,0, 0, 0, 0, 0, 0};      
      byte v3[8] = { 0, 0, 0, 0, 0,0,31,31};
      byte v4[8] = {31,31, 0, 0, 0, 0,31,31};
      byte v5[8] = { 28, 28, 0, 0, 0, 0, 28, 28};//
      byte v6[8] = {28,28,28,28,28,28,28,28};
      byte v7[8] = { 0, 0, 0, 0, 0, 0,7,7};
      byte v8[8] = { 31, 31,0,0,0,0,0, 0};
      int a[6],hour,minut,secon,h_alarm,m_alarm,memory,alarm,yar,mount,date;
      byte i,d1,d2,d3,d4,d5,d6,e1,e2,e3;
      float temp_hous,h,p,k;
      unsigned long times,times1;
 
   void setup(){ 
    Wire.begin();AHT10.begin();lcd.init();clock.begin();bmp.begin();temp.begin();temp.setResolution(10); 
    ///clock.setDateTime(__DATE__, __TIME__);
    lcd.backlight();// Включаем подсветку дисплея
    lcd.createChar(1, v1);lcd.createChar(2, v2);lcd.createChar(3, v3);lcd.createChar(4, v4);lcd.createChar(5, v5);lcd.createChar(6, v6);lcd.createChar(7, v7);lcd.createChar(8, v8);
    pinMode(2,INPUT_PULLUP);   // УСТ. ВРЕМЯ
    pinMode(7,INPUT_PULLUP);   // УСТ. ДАТА-МЕСЯЦ-ГОД
    pinMode(3,INPUT_PULLUP);   // ЧАСЫ / ДАТА
    pinMode(4,INPUT_PULLUP);   // МИНУТЫ / МЕСЯЦ
    pinMode(5,INPUT_PULLUP);   // ОБНУЛЕНИЕ СЕКУНД / ГОД / УСТ. БУДИЛЬНИКА
    pinMode(6,OUTPUT); // ZZZZZZzzzzzz.....
    h_alarm = EEPROM.read(11);m_alarm = EEPROM.read(12);alarm = EEPROM.read(13);
   }
 
   void loop(){
    if(millis()-times>10000){temp_hous = AHT10.GetTemperature();h = AHT10.GetHumidity(); 
    p = bmp.readPressure()/133.3224;temp.requestTemperatures(); k = temp.getTempCByIndex(0);times = millis();} // ОПРОС ДАТЧИКОВ КАЖДЫЕ 10 СЕК
    if(digitalRead(2)==LOW||digitalRead(3)==LOW||digitalRead(4)==LOW||digitalRead(5)==LOW||digitalRead(7)==LOW){times1=millis();}
 
 
    DateTime=clock.getDateTime();  
    yar = DateTime.year; mount = DateTime.month;date = DateTime.day;hour = DateTime.hour;minut = DateTime.minute;secon = DateTime.second;
    memory = DateTime.hour * 100 + DateTime.minute;
     a[0]=DateTime.hour/10;
     a[1]=DateTime.hour%10;
     a[2]=DateTime.minute/10;
     a[3]=DateTime.minute%10;
     a[4]=DateTime.second/10;
     a[5]=DateTime.second%10;
 
  if(digitalRead(2)==LOW&&digitalRead(3)==LOW){hour++;if(hour>23){hour=0;} clock.setDateTime(yar, mount, date, hour, minut, secon);delay(100);}
  if(digitalRead(2)==LOW&&digitalRead(4)==LOW){minut++;if(minut>59){minut=0;} clock.setDateTime(yar, mount, date, hour, minut, secon);delay(100); }
 
  if(digitalRead(7)==LOW&&digitalRead(3)==LOW){date++;if(date>31){date=1;} clock.setDateTime(yar, mount, date, hour, minut, secon);delay(100);}
  if(digitalRead(7)==LOW&&digitalRead(4)==LOW){mount++;if(mount>12){mount=1;} clock.setDateTime(yar, mount, date, hour, minut, secon);delay(100); }
  if(digitalRead(7)==LOW&&digitalRead(5)==LOW){yar++;if(yar>2050){yar=2015;} clock.setDateTime(yar, mount, date, hour, minut, secon);delay(100); }
 
  if(digitalRead(2)==LOW&&digitalRead(5)==LOW){secon=0; clock.setDateTime(yar, mount, date, hour, minut, secon);delay(100); }
 
 for(i=0;i<6;i++){
      switch(i){
        case 0: e1=0,e2=1,e3=2;break;
        case 1: e1=3,e2=4,e3=5;break;
        case 2: e1=7,e2=8,e3=9;break;
        case 3: e1=10,e2=11,e3=12;break;
        case 4: e1=14,e2=15,e3=16;break;
        case 5: e1=17,e2=18,e3=19;break;
        }
      switch(a[i]){
        case 0: d1=1,d2=8,d3=6,d4=1,d5=3,d6=6;break;
        case 1: d1=32,d2=2,d3=6,d4=32,d5=32,d6=6;break;
        case 2: d1=2,d2=8,d3=6,d4=1,d5=4,d6=5;break;
        case 3: d1=2,d2=4,d3=6,d4=7,d5=3,d6=6;break;
        case 4: d1=1,d2=3,d3=6,d4=32,d5=32,d6=6;break;
        case 5: d1=1,d2=4,d3=5,d4=7,d5=3,d6=6;break;
        case 6: d1=1,d2=4,d3=5,d4=1,d5=3,d6=6;break;
        case 7: d1=1,d2=8,d3=6,d4=32,d5=32,d6=6;break;
        case 8: d1=1,d2=4,d3=6,d4=1,d5=3,d6=6;break;
        case 9: d1=1,d2=4,d3=6,d4=7,d5=3,d6=6;break;
    }
 
      lcd.setCursor(e1,0);lcd.write((uint8_t)d1);lcd.setCursor(e2,0);lcd.write((uint8_t)d2);lcd.setCursor(e3,0);lcd.write((uint8_t)d3);
      lcd.setCursor(e1,1);lcd.write((uint8_t)d4);lcd.setCursor(e2,1);lcd.write((uint8_t)d5);lcd.setCursor(e3,1);lcd.write((uint8_t)d6);
 
 }
   lcd.setCursor(6,0);lcd.print(".");lcd.setCursor(13,0);lcd.print(".");lcd.setCursor(6,1);lcd.print(".");lcd.setCursor(13,1);lcd.print(".");
 
   if(digitalRead(2)==LOW){lcd.setCursor(0,2);lcd.print(" TIME SET  HH:MM:SS ");}
   else if(digitalRead(7)==LOW){lcd.setCursor(0,2);lcd.print(" TIME SET  DD-MM-YY ");}
   else if(digitalRead(2)==HIGH&&digitalRead(7)==HIGH&&digitalRead(5)==LOW){
    if(digitalRead(3)==LOW){h_alarm++; if(h_alarm>23){h_alarm=0;}delay(100);EEPROM.update(11, h_alarm);}
    if(digitalRead(4)==LOW){m_alarm++; if(m_alarm>59){m_alarm=0;}delay(100);EEPROM.update(12, m_alarm);}
    lcd.setCursor(0,2);lcd.print("ALARM CLOCK--");lcd.print(h_alarm/10);lcd.print(h_alarm%10);lcd.print(":");lcd.print(m_alarm/10);lcd.print(m_alarm%10);}
 
   else{lcd.setCursor(0,2);
   if(alarm==0){lcd.print("------ALARM OFF-----");}
   if(alarm==1){lcd.print("------ALARM ON------");}
   }
 
//////////// ZZZZZZZZZzzzzzzzz...... ///////////////////////
   if(digitalRead(3)==LOW&&digitalRead(2)==HIGH&&digitalRead(5)==HIGH&&digitalRead(7)==HIGH){alarm=1;delay(300);EEPROM.update(13, alarm);}
   if(digitalRead(4)==LOW&&digitalRead(2)==HIGH&&digitalRead(5)==HIGH&&digitalRead(7)==HIGH){alarm=0;delay(300);EEPROM.update(13, alarm);}
   if(h_alarm*100+m_alarm==memory&&alarm==1){tone(6,1500,150);}
 
 
 
   if(millis()-times1<IND){
   lcd.setCursor(1,3);lcd.print(DateTime.day/10);lcd.print(DateTime.day%10);lcd.print("-");
   lcd.print(DateTime.month/10);lcd.print(DateTime.month%10);lcd.print("-");lcd.print(DateTime.year);
   lcd.print("  ");lcd.print(temp_hous,1);lcd.print((char)223);lcd.print("C ");}
 
   if(millis()-times1>IND){
   lcd.setCursor(1,3);lcd.print(h,1);lcd.print("% "); lcd.print(p,1);lcd.print(" ");lcd.print(k,1);lcd.print((char)223);lcd.print("C ");
   }
   if(millis()-times1>IND*2){times1=millis();}
 
   }

Форум — http://forum.rcl-radio.ru/viewtopic.php?id=179

Комментарии

Добавить комментарий

Войти с помощью: 

Случайные статьи

  • Удвоитель напряжения на микросхеме NE555

    Описание. Схема простейшего удвоителя напряжения использованием микросхемы NE555 показана на рисунке. Здесь IC NE555 подключен в схеме как нестабильный мультивибратор с частотой генерации около 9KHz. Базы двух транзисторов (Q1 и Q2) подключены напрямую к выходу мультивибратора (контакт 3). При выходе сигнала из мультивибратора в первый момент Q1 будет OFF и …Подробнее...
  • Преобразователь =12В\ 220В

    Преобразователь =12В\ 220В

    Схема преобразователя состоит из 3-х узлов: задающего мультивибратора, двухтактного транзисторного ключевого усилителя и повышающего трансформатора. Мультивибратор выполнен на микросхеме D1(D1.1  D1.2). Его частота зависит от R1 C1. На выходе мультивибратора включен инвертор на D1.4 который создает противофазные сигналы поступающие на базы VT1 VT2. Затем следует двухтактный усилитель на VT3 VT4 …Подробнее...
  • Термопары

    Термопары

    Термопара (термоэлектрический преобразователь) — устройство, применяемое для измерения температуры в промышленности, научных исследованиях, медицине, в системах автоматики. Принцип действия основан на эффекте Зеебека или, иначе, термоэлектрическом эффекте. Между соединёнными проводниками имеется контактная разность потенциалов; если стыки связанных в кольцо проводников находятся при одинаковой температуре, сумма таких разностей потенциалов равна нулю. …Подробнее...
  • TDA7499 — УМЗЧ 2х6 Вт

    TDA7499 — УМЗЧ 2х6 Вт

    TDA7499 — усилитель мощности звуковой частоты (класс АВ), с выходной мощность 6 Вт на канал (стерео). Усилитель относиться к классу Hi-Fi аппаратуры. В усилителе имеются функции STANDBY и MUTE, беззвучное включение и выключение (отсутствие щелчков), защита выхода от КЗ на землю, тепловая защита и защита от перегрузки. ИМС TDA7499 может …Подробнее...
  • Логический пробник для ТТЛ и ТТЛШ

    Схема отличается высокой точностью и возможностью контроля логических уровней «1» и «0», К3 и «Не определено». При неподключенном входе пробника светится светодиод «Не определено». Резисторы R1.R4 желательно применить с допуском 1%. ОУ любые, со своими частотными коррекциями, важно только, чтобы выходной ток был не менее 15 мА и Rвх не …Подробнее...