| Ваш IP: 3.230.1.126 | Online(15) - гости: 13, боты: 2 | Загрузка сервера: 1.39 ::::::::::::


Погодная станция + часы + будильник (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

Комментарии

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

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

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

  • Генератор на LM566

    Генератор на LM566

    Управляемый напряжением генератор на ИМС LM566 фирмы National Semiconductor относится к классу функциональных генераторов и обладает возможностью генерации сигнала прямоугольной формы (меандр) и треугольной формы (линейнонарастающего и спадающего напряжения). Отличительной особенностью микросхемы является высокая линейность регулировочной характеристики и минимальное количество внешних элементов. LM566 может работать при питании от однополярного и …Подробнее...
  • Микрофонные усилители на ОУ

    Микрофонные усилители на ОУ

    Ниже показана схема микрофонного усилителя на ОУ которая имеет следующие параметры: Номинальное входное напряжение Номинальное выходное напряжение Отношение сигнал\шум Рабочий диапазон частот Коэффициент гармоник Максимальное выходное напряжение Входное сопротивление Минимальное сопротивление нагрузки 1мВ 100мВ 56дБ 30…30000Гц 0,05% 7В 1кОм 10кОм   ОУ включен по схеме инвертирующего усилителя. Коэффициент усиления определяется …Подробнее...
  • STM32 + TM1637 (Arduino)

    STM32 + TM1637 (Arduino)

    Модуль TM1637 представляет собой 4-х разрядный семисегментный дисплей на базе драйвера TM1637. Дисплей имеет десятичные точки в разрядах. Для подключения используется всего 2 цифровых контакта (помимо питания от 3.3 до 5 В) отладочной платы на STM32 (базе микроконтроллера STM32F103C8T6). Для работы с дисплеем TM1637 можно использовать простую в применении библиотеку …Подробнее...
  • Двух-полярный источник питания от напряжения 9В

    Двух-полярный источник питания от напряжения 9В

    При  питании уст-в от элементов питания иногда возникает необходимость в двух полярном источнике напряжения. Можно конечно применить два элемента питания, но так же можно сделать простой преобразователь одно полярного напряжения в двух полярное. Предложенная схема позволяет от одного элемента напряжением 9 В (Крона) получить отрицательное напряжение -9 В. Схема преобразователя …Подробнее...
  • Датчик температуры на 1N4148 (Arduino)

    Датчик температуры на 1N4148 (Arduino)

      Кремниевый диод в прямом включении — это практически линейный температурный датчик, падение напряжения на кремниевом диоде линейно зависит от температуры, причем температурный коэффициент практически одинаков для любых типов диодов и составляет около −2 мВ/°С (т. е. с ростом температуры напряжение уменьшается). Диапазон измерения температуры при помощи кремниевого диода может …Подробнее...