В домашней метеостанции будут использоваться следующие компоненты:
- Arduino Nano
- модуль DS3231 — часы реального времени
- модуль BMP280 — датчик атмосферного давления и температуры (измерение атмосферного давления в мм.рт.ст и температуры в комнате)
- модуль 18B20 — цифровой датчик температуры (измерение температуры на улице)
- модуль DHT11 — датчик влажности
- LCD 1602 на базе контроллера HD44780
BMP280 | DHT11 | DS3231 | 18B20 |
Так же Вам понадобятся следующие библиотеки:
В первой строке LCD 1602 выводятся показания времени, даты и месяца, во второй с периодичностью 10 секунд будут меняться показания температуры, атмосферного давления и влажности.
#include <Wire.h> #include <SPI.h> #include <DHT.h> #include <LiquidCrystal.h> #include <OneWire.h> #include <DallasTemperature.h> #include <DS3231.h> #include <Adafruit_Sensor.h> #include <Adafruit_BMP280.h> DHT dht(2, DHT11); // выход DATA подключен к цыфровому входу 2 LiquidCrystal lcd(7, 8, 9, 10, 11, 12);// RS,E,D4,D5,D6,D7 Adafruit_BMP280 bmp; // I2C OneWire oneWire(A1);// А1 вход датчика 18b20 DallasTemperature t(&oneWire); DS3231 clock;RTCDateTime DateTime; void setup() { Serial.begin(9600); bmp.begin(); dht.begin(); lcd.begin(16,2);// LCD 16X2 t.begin(); t.setResolution(10);// 10 bit 18b20 clock.begin(); // clock.setDateTime(__DATE__, __TIME__);// установка времени DS3231, раскомментировать и залить скетч, далее закомментировать и залить скетч повторно } void loop() { t.requestTemperatures(); DateTime=clock.getDateTime(); // Считываем c часов текущие значения даты и времени в сущность DateTime lcd.setCursor(0,0); // lcd.print(clock.dateFormat("H:i:s ",DateTime));// выводим часы и минуты // lcd.print(clock.dateFormat("d M", DateTime));// выводим дату и месяц if(DateTime.hour<10){lcd.print("0");}lcd.print(DateTime.hour);lcd.print(":"); if(DateTime.minute<10){lcd.print("0");}lcd.print(DateTime.minute);lcd.print(":"); if(DateTime.second<10){lcd.print("0");}lcd.print(DateTime.second);lcd.print(" "); if(DateTime.day<10){lcd.print("0");}lcd.print(DateTime.day);lcd.print("-"); if(DateTime.month<10){lcd.print("0");}lcd.print(DateTime.month); lcd.setCursor(0,1); if((DateTime.second/10)%2==0){ // каждые нечетные 10 секунд показвать температуру lcd.setCursor(1,1); lcd.print(bmp.readTemperature(),1); lcd.print(char(223)); lcd.print("C "); t.requestTemperatures();// опрос 18b20 lcd.print(t.getTempCByIndex(0),1); // вывод температуры 18b20 lcd.print(char(223)); lcd.print("C"); } else{ lcd.setCursor(1,1);lcd.print("P "); lcd.print(bmp.readPressure()/133.3224,1);// давление в мм.рт.ст lcd.print(" H "); lcd.print(dht.readHumidity(),0);// влажность lcd.print("%");} }
Если у Вас не работает датчик BMP280 после загрузки скетча, то вероятней всего адрес уст-ва не соответствует указанному в файле библиотеки Adafruit_BMP280.h, необходимо узнать адрес уст-ва, но так как на шине i2c подключены еще часы реального времени ds3132, то их необходимо временно из схемы убрать.
Для определения адреса используйте следующий скетч (сканер i2c):
#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); }
Как видно на скриншоте адрес уст-ва определился как 0х76. Далее откройте файл Adafruit_BMP280.h библиотеки и сравните адрес уст-ва с указанным в файле, если адрес отличается, то укажите свой.
Часы реального времени нуждаются в установке времени если это не было сделано ранее, установить время можно по времени компиляции, для этого раскомментируйте строчку:
clock.setDateTime(__DATE__, __TIME__);
Залейте скетч, далее закомментируйте строчу и залейте скетч повторно.
Следующая версия домашней метеостанции аналогична первой, только вместо дисплея LCD 1602 применен индикатор на базе драйвера TM1637 (модуль TM1637).
Домашняя метеостанция работает в следующих режимах (при нажатии на кнопку SA):
- SA0 — основной режим, установлен по умолчанию, показывает время в течении 20 секунд, далее с интервалом в 10 секунд выводит поочередно температуру дома (BMP280), температуру на улице (18B20), давление и влажность.
- SA1 — показывает только время
- SA2 — температура дома
- SA3 — температура на улице
- SA4 — атмосферное давление в мм.рт.ст
- SA5 — влажность в %
- следующее нажатии кнопки SA активирует основной режим SA0
#include <Wire.h> #include <SPI.h> #include <DHT.h> #include <OneWire.h> #include <DallasTemperature.h> #include <TM1637Display.h> #include <DS3231.h> #include <Adafruit_Sensor.h> #include <Adafruit_BMP280.h> DHT dht(2, DHT11); // выход DATA подключен к цыфровому входу 2 Adafruit_BMP280 bmp; // I2C OneWire oneWire(A1);// А1 вход датчика 18b20 DallasTemperature t(&oneWire); DS3231 clock;RTCDateTime DateTime;//ds3132 A4,A5 (SDA,SCL) TM1637Display display(12, 11);// CLK,DIO void setup() { pinMode(4,INPUT);pinMode(10,INPUT); bmp.begin(); dht.begin(); t.begin(); clock.begin(); t.setResolution(9);// 9 bit 18b20 display.setBrightness(2);// яркость TM1637 0-7 // clock.setDateTime(__DATE__, __TIME__);// установка времени DS3231, раскомментировать и залить скетч, далее закомментировать и залить скетч повторно } int k,x,z,kn,sec; uint8_t date_t1[]{0x78,0x10,0,0};// t1 uint8_t date_t2[]{0x78,0,0,0};// t2 uint8_t date_p[]{0x73,0,0,0};// p uint8_t date_h[]{0x76,0,0,0};// h uint8_t date_kn[]{0x6d,0x77,0,0};// h void loop() { DateTime = clock.getDateTime(); // ОПРОС ВРЕМЕНИ if(digitalRead(10)==HIGH){kn++;if(kn>5){kn=0;}z=1; date_kn[3] = display.encodeDigit(kn); display.setSegments(date_kn);delay(500);} switch(kn){case 0: sec=DateTime.second;break;// all case 1: sec=10;break;// time case 2: sec=25;break;//t1 case 3: sec=35;break;//t2 case 4: sec=45;break;//p case 5: sec=55;break;}//h if(sec>=0&&sec<=20){z=0; k = DateTime.hour*100+DateTime.minute;} // ВРЕМЯ КАК ЧИСЛО ННММ if(digitalRead(4) == HIGH){x = 0x40;}else{x = 0x00;} // МИГАНИЕ ДВОЕТОЧИЯ if(sec>20&&sec<=30){z=1;t.requestTemperatures();k=bmp.readTemperature();// вывод температуры дома t1 date_t1[2] = display.encodeDigit((k/10)%10); date_t1[3] = display.encodeDigit((k%10)%10); display.setSegments(date_t1);} if(sec>30&&sec<=40){z=1;k=abs(t.getTempCByIndex(0));// вывод температуры на улице t2 date_t2[2] = display.encodeDigit((k/10)%10); date_t2[3] = display.encodeDigit((k%10)%10); if(t.getTempCByIndex(0)<0){date_t2[1]=0x15;}else{date_t2[1]=0x14;} display.setSegments(date_t2);} if(sec>40&&sec<=50){z=1;k=bmp.readPressure()/133.3224;// вывод атмосферного давления date_p[1] = display.encodeDigit(k/100); date_p[2] = display.encodeDigit((k/10)%10); date_p[3] = display.encodeDigit((k%10)%10); display.setSegments(date_p);} if(sec>50&&sec<=59){z=1;k=dht.readHumidity();// вывод влажности date_h[2] = display.encodeDigit((k/10)%10); date_h[3] = display.encodeDigit((k%10)%10); display.setSegments(date_h);} if(z==0){ display.showNumberDecEx(k,x,false);} }
Здравствуйте! Подскажите пжл метеостанция с LCD 16 часы не показывают , а остальное работает.
Найдите в библиотеке DS3231 файл DS3231.cpp
Далее найдите строчки
char* DS3231::dateFormat(const char* dateFormat, RTCDateTime dt)
{
char buffer[255];
замените на
char* DS3231::dateFormat(const char* dateFormat, RTCDateTime dt)
{
static char buffer[255];
Должно помочь, или загрузите скетч в старой версии Arduino IDE 1,0,1
Здравствуйте! Помогите пожалуйста вывести дату на дисплей, вроде часы вывел работают хотелось и дату . заменил строчку lcd.print(clock.dateFormat(«H:i:s»,DateTime));// выводим часы, минуты на эту lcd.print(DateTime.hour/10);lcd.print(DateTime.hour%10);lcd.print(«:»);
lcd.print(DateTime.minute/10);lcd.print(DateTime.minute%10);lcd.print(«:»);
lcd.print(DateTime.second/10);lcd.print(DateTime.second%10);
Используйте:
uint16_t year, uint8_t month, uint8_t day
пример:
DateTime.day
И так сойдёт всё ровно не понимаю.
Здравствуйте! Выведи Пожалуста дату на lcd1602
Я поправил скетч. (не тестировал)
ошибку даёт
Скопируйте обновленный скетч со страницы (по картинке вижу что это не он)
Залил скетч с правкой дата есть 13-07 высвечивает
Год добавить? Я не знаю есть ли на экране место вывести год.
надо добавить:
lcd.print("-");lcd.print(DateTime.year);
место не хватит Я думаю. 2 сигмента с краю толька слитно будет
нулью место нет ,выпадает
Спасибо !