Przeszukaj forum
Pokazywanie wyników dla tagów 'DHT22'.
Znaleziono 2 wyniki
-
Witajcie Chciałbym przedstawić Wam mój pierwszy projekt na ESP32. Buduję smart home i potrzebowałem pomiaru temperatury i wilgotności w pokojach z możliwością ustawiania częstotliwości wysyłania tych danych np. co minutę lub 5 minut, oraz aby te dane nie przechodziły przez chmurę tak jak np. tuya, sonoff, aqara. Są dostępne gotowe urządzenia ale nie spełniały tych założeń , dlatego zrobiłem swoje a przy okazji zacząłem przygodę z esp32 i drukiem 3D. Tak wygląda już gotowe urządzenie Założenia: maksymalnie prosty układ z gotowych części, aby cenowo był tańszy niż już gotowe urządzenia (bo takich urządzeń będę potrzebował x5) komunikacja przez WiFi wysyłka danych co 5min do serwera Home Assistant wyświetlanie danych na ekranie urządzenia gdy by padł serwer z Home Assistant zasilanie z usb C, ponieważ nie chce zmieniać baterii Wykorzystane części: esp32 wroom czujnik temperatury i wilgotności - dht22 oled 128x32 np. ten SPI/I2C - czarno-biały Zaczynam od połączenia wszystkiego na płytce i przetestowaniu programu. Założenia programu są takie żeby na początku na ekranie wyświetlił adres IP pod którym można się zalogować , ponieważ esp32 działa w trybie AP, na ekranie możemy ustawić dane sieci WiFi, częstotliwość wysyłki danych temperatura i wilgotność do HA (w sekundach), logi i hasło do klienta MQTT, oraz adresy wysyłki temperatury i wilgotności do HA. Dodatkowo tryb AP działa przez pierwsze 90s, gdy nie podłączymy się pod WiFi to na ekranie wyświetli się temperatura i wilgotność. Gdy będziemy chcieli zmienić siec to wystarczy wcisnąć wbudowany przycisk resetu, który czeka przez pierwsze 3s od momentu włączenia zasilania , wtedy zresetowana zostaje pamięć i można wprowadzić dane ponownie. Obudowę przygotowałem w programie FreeCAD i jesto to moja pierwsza w życiu obudowa i projekt 3D, ale wciągneło mnie do tego stopnia że już pracuję nad kolejnymi projektami, które wykorzystam w Home Assistant. Przygotowuję kod według założeń, korzystam z programu Arduino IDE. #include <WiFiManager.h> #include <PubSubClient.h> #include <Wire.h> #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> #include <Adafruit_Sensor.h> #include <DHT.h> #include <Preferences.h> // Definicje pinów i rozdzielczości OLED #define BOOT_BUTTON_PIN 0 // Przycisk BOOT (GPIO0) #define DHTPIN 4 // Pin danych czujnika DHT22 #define DHTTYPE DHT22 // Typ czujnika #define SCREEN_WIDTH 126 // Szerokość OLED #define SCREEN_HEIGHT 32 // Wysokość OLED #define OLED_RESET -1 // Brak dedykowanego pinu reset Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); DHT dht(DHTPIN, DHTTYPE); unsigned long lastMQTTAttempt = 0; bool wifiFailed = false; Preferences preferences; WiFiManager wm; WiFiClient espClient; PubSubClient client(espClient); // Domyślne ustawienia MQTT i interwału (w sekundach) char mqtt_server[40] = "192.168.1.104"; int mqtt_port = 1883; int send_interval = 30; char mqtt_user[40] = "mqtt_user"; char mqtt_password[40] = "mqtt_password"; char temp_topic[100] = "homeassistant/sensor/esp32/temperature"; char hum_topic[100] = "homeassistant/sensor/esp32/humidity"; // Czas ostatniej publikacji MQTT unsigned long lastSendTime = 0; void displayWiFiInfo() { WiFi.softAP("ESP32_Config"); IPAddress apIP = WiFi.softAPIP(); display.clearDisplay(); display.setTextSize(1); display.setTextColor(SSD1306_WHITE); display.setCursor(0, 0); display.println("Konfiguracja WiFi"); display.print("S: "); display.println("ESP32_Config"); display.print("IP: "); display.println(apIP); display.display(); Serial.println("Tryb AP: ESP32_Config"); Serial.print("Adres konfiguracyjny: "); Serial.println(apIP); } void updateDisplay() { float temperature = dht.readTemperature(); float humidity = dht.readHumidity(); display.clearDisplay(); display.setTextSize(1); display.setTextColor(SSD1306_WHITE); if (isnan(temperature) || isnan(humidity)) { Serial.println("Błąd odczytu DHT!"); display.setCursor(0, 10); display.println("DHT ERROR"); } else { String tempStr = "Temp: " + String(temperature,1) + " C"; String humStr = "Wilg: " + String(humidity,1) + " %"; // Wyśrodkowanie tekstu - obliczamy szerokość tekstu int16_t x1, y1; uint16_t w, h; display.getTextBounds(tempStr.c_str(), 0, 0, &x1, &y1, &w, &h); int xTemp = (SCREEN_WIDTH - w) / 2; int yTemp = (SCREEN_HEIGHT / 2) - h; display.setCursor(xTemp, yTemp); display.println(tempStr); display.getTextBounds(humStr.c_str(), 0, 0, &x1, &y1, &w, &h); int xHum = (SCREEN_WIDTH - w) / 2; int yHum = (SCREEN_HEIGHT / 2) + 2; display.setCursor(xHum, yHum); display.println(humStr); } display.display(); } void publishSensorData() { float temperature = dht.readTemperature(); float humidity = dht.readHumidity(); if (isnan(temperature) || isnan(humidity)) { Serial.println("Błąd odczytu DHT!"); return; } client.publish(temp_topic, String(temperature).c_str()); client.publish(hum_topic, String(humidity).c_str()); Serial.print("Publikacja: T: "); Serial.print(temperature); Serial.print("C, H: "); Serial.print(humidity); Serial.println("%"); } void reconnectMQTT() { if (!client.connected() && (millis() - lastMQTTAttempt >= 15000UL)) { lastMQTTAttempt = millis(); Serial.print("Łączenie z MQTT..."); if (client.connect("ESP32Client", mqtt_user, mqtt_password)) { Serial.println("Połączono z MQTT!"); } else { Serial.print("Błąd, rc="); Serial.print(client.state()); Serial.println(" Nie udało się połączyć."); } } } void setup() { Serial.begin(115200); pinMode(BOOT_BUTTON_PIN, INPUT_PULLUP); delay(100); bool resetSettings = false; unsigned long startTime = millis(); while (millis() - startTime < 3000) { if (digitalRead(BOOT_BUTTON_PIN) == LOW) { resetSettings = true; break; } } if (resetSettings) { Serial.println("Przycisk BOOT wciśnięty - resetowanie ustawień..."); preferences.begin("config", false); preferences.clear(); preferences.end(); wm.resetSettings(); if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { Serial.println("Błąd OLED!"); while (true); } display.clearDisplay(); display.setTextSize(1); display.setTextColor(SSD1306_WHITE); display.setCursor(0, 10); display.print("Reset ustawien!"); display.display(); delay(5000); } if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { Serial.println("Błąd OLED!"); while (true); } display.clearDisplay(); display.setTextSize(1); display.setTextColor(SSD1306_WHITE); display.setCursor(0, 10); display.print("Uruchamianie ..."); display.display(); preferences.begin("config", false); String storedServer = preferences.getString("mqtt_server", "192.168.1.100"); storedServer.toCharArray(mqtt_server, sizeof(mqtt_server)); mqtt_port = preferences.getInt("mqtt_port", 1883); send_interval = preferences.getInt("interval", 300); String storedUser = preferences.getString("mqtt_user", "mqtt_user"); storedUser.toCharArray(mqtt_user, sizeof(mqtt_user)); String storedPass = preferences.getString("mqtt_password", "mqtt_password"); storedPass.toCharArray(mqtt_password, sizeof(mqtt_password)); String storedTempTopic = preferences.getString("temp_topic", "homeassistant/sensor/esp32/temperature"); storedTempTopic.toCharArray(temp_topic, sizeof(temp_topic)); String storedHumTopic = preferences.getString("hum_topic", "homeassistant/sensor/esp32/humidity"); storedHumTopic.toCharArray(hum_topic, sizeof(hum_topic)); preferences.end(); WiFiManagerParameter paramInterval("interval", "Co ile sekund wysyłać dane do HA?", String(send_interval).c_str(), 6); WiFiManagerParameter paramMQTTServer("mqtt_server", "MQTT serwer IP", mqtt_server, 40); WiFiManagerParameter paramMQTTPort("mqtt_port", "MQTT port", String(mqtt_port).c_str(), 6); WiFiManagerParameter paramMQTTUser("mqtt_user", "MQTT użytkownik", mqtt_user, 40); WiFiManagerParameter paramMQTTPassword("mqtt_password", "MQTT hasło", mqtt_password, 40); WiFiManagerParameter paramTempTopic("temp_topic", "MQTT Temat Temperatury", temp_topic, 100); WiFiManagerParameter paramHumTopic("hum_topic", "MQTT Temat Wilgotności", hum_topic, 100); wm.addParameter(¶mInterval); wm.addParameter(¶mMQTTServer); wm.addParameter(¶mMQTTPort); wm.addParameter(¶mMQTTUser); wm.addParameter(¶mMQTTPassword); wm.addParameter(¶mTempTopic); wm.addParameter(¶mHumTopic); displayWiFiInfo(); // Ustaw timeout, aby portal AP był aktywny przez 90 sekund (1 min i 30sec) wm.setTimeout(90); if (!wm.autoConnect("ESP32_Config")) { Serial.println("Brak połączenia z WiFi! Tryb AP."); WiFi.mode(WIFI_OFF); wifiFailed = true; } Serial.println("Połączono z WiFi!"); send_interval = String(paramInterval.getValue()).toInt(); strncpy(mqtt_server, paramMQTTServer.getValue(), sizeof(mqtt_server)); mqtt_port = String(paramMQTTPort.getValue()).toInt(); strncpy(mqtt_user, paramMQTTUser.getValue(), sizeof(mqtt_user)); strncpy(mqtt_password, paramMQTTPassword.getValue(), sizeof(mqtt_password)); strncpy(temp_topic, paramTempTopic.getValue(), sizeof(temp_topic)); strncpy(hum_topic, paramHumTopic.getValue(), sizeof(hum_topic)); preferences.begin("config", false); preferences.putString("mqtt_server", mqtt_server); preferences.putInt("mqtt_port", mqtt_port); preferences.putInt("interval", send_interval); preferences.putString("mqtt_user", mqtt_user); preferences.putString("mqtt_password", mqtt_password); preferences.putString("temp_topic", temp_topic); preferences.putString("hum_topic", hum_topic); preferences.end(); dht.begin(); client.setServer(mqtt_server, mqtt_port); } void loop() { if (!client.connected()) { reconnectMQTT(); } client.loop(); updateDisplay(); if (millis() - lastSendTime >= (send_interval * 1000UL)) { publishSensorData(); lastSendTime = millis(); } delay(1000); } Gdy wszystko pasowało zmontowałem w jedną całość i rozpocząłem kondigurację z Home Assistant aby odbierać dane temperatura i wilgotność. Całość gotowa i działa. Dane są odbierane w Home Assistant z dwóch encji. Dzięki temu mogę wykorzystać to do uruchamiania klimatyzacji, nawilżacza powietrza lub ogrzewania. Całość działą lokalnie dzięki temu wyeliminowałem chmure i chińskie serwery i całkowicie odszedłem od LocalTuya i Sonoff. Obecnie takich termometrów mam 5, testuje różne kolory wydruku 3D i wszystkie działają w Home Assistant. Projekt pewnie dla wielu z Was jest prosty ale bardzo mi pomógł w działamiu smart home i zrodził kolejne pomysły na następne urządzenia które są już w trakcie budowy. Dziękuję za uwagę.
-
Witam niedawno chwaliłem się tu prototypem ,,Stacji Pogodowej DHT11". Trochę popracowałem nad tym i teraz mogę się pochwalić Stacją pogodową DHT22: Komponenty które tutaj użyłem: Attiny85 - Mikrokontroler a tutaj serce całej stacji pogodowej DHT22 - Czujnik wilgotności i temperatury LCD 2x16 z konwerterem I2C - Wyświetlacz pełniący rolę twarzy stacji Koszyk oraz baterie - Czyli zasilanie całego projektu (3x AA w koszyku) Nie będę powyżej wymieniał takich rzeczy jak płytka uniwersalna, czy szczypce boczne które mi się przydały przy obcinaniu podpór wydruku Celem całego projektu było ciche i małe urządzenie które można postawić na biurku i obserwować wilgotność i temperaturę. Najcięższą rzeczą w tym wszystkim było zrobienie samej obudowy, robiłem ją w programie TINKERCAD. Najpierw musiałem zrobić wydruki które pomogły mi dopasować otwory do komponentów: Dopiero jak wszystko było dopasowane to zacząłem robić obudowę która finalnie wyszła tak: I wiem, powiedziałem ,,ciche i małe urządzenie" a obudowa nie wyszła jakoś bardzo mała, tylko że zdałem sobie z tego sprawę podczas jej drukowania. Wszystko mogło by wyjść mniejsze i oszczędniejsze gdyby przełożyć miejsce na koszyk (z tyłu obudowy na jej spód). Wspomniałem o oszczędności bo jak na moje wydruki które miały od 3-10g to ten był dość spory, bo miał ok. 75g. Okej teraz zajrzyjmy do kodu: #include "DHT.h" #include <Wire.h> #include <LiquidCrystal_I2C.h> LiquidCrystal_I2C lcd(0x27,16,2); DHT dht; byte znak_stopnia[8] = { B00111, B00101, B00111, B00000, B00000, B00000, B00000, B00000 }; byte znak_wilg[8] = { B00000, B00100, B00110, B01110, B11101, B11111, B11111, B01110 }; byte znak_temp[8] = { B00100, B00110, B00100, B00110, B00100, B01110, B01110, B01110 }; int w; int t; int tx; int wx; void setup(){ dht.setup(4); lcd.init(); lcd.backlight(); lcd.setCursor(0,0); lcd.print("Temp ="); lcd.setCursor(0,1); lcd.print("Wilg ="); lcd.createChar(1, znak_temp); lcd.createChar(2, znak_wilg); lcd.setCursor(5,0); lcd.write(1); lcd.setCursor(5,1); lcd.write(2); } void loop(){ if(t < 10 && t > -1){ tx = 10; } if(t > 9){ tx = 11; } if(t < 0 && t > -10){ tx = 11; } if(t < -9){ tx = 12; } w = dht.getHumidity(); t = dht.getTemperature(); lcd.setCursor(9,0); lcd.print(t); lcd.setCursor(9,1); lcd.print(w); lcd.createChar(3, znak_stopnia); lcd.setCursor(tx,0); lcd.write(3); lcd.print("C "); lcd.setCursor(11,1); lcd.print("% "); delay(dht.getMinimumSamplingPeriod()); } Nie ma co tu opisywać każdej linijki, zaznaczę tylko kilka ważnych linijek Poprzednim razem w mojej stacji nie było nic nadzwyczajnego, tutaj postanowiłem dodać znaki które dodają trochę wyglądu (w kodzie: funkcja byte napisana 3 razy) Przydała mi się tu bardzo ta strona: https://maxpromer.github.io/LCD-Character-Creator/ Kilka pętli if pojawiło się w kodzie żeby zapobiec błędom w wyświetlaniu znaków Reszta kodu to funkcje wyświetlające napisy/znaki oraz funkcje pobierania temperatury/wilgotności Podczas drukowania obudowy napotkałem bardzo duży problem, mam na myśli odklejanie się rogów wydruku. To było coś nad czym siedziałem prawie pełne 2 dni, co znacznie opóźniło ukończenie projektu. Problem rozwiązała zmiana temperatury stołu, dowiedziałem się że dla filamentu PLA stół powinien mieć temperaturę ok 55°C gdzie mój do tej pory miał 35°C. Pomogło mi jeszcze wymycie płyty roboczej oraz nałożenie na nią zwykłego kleju biurowego. Finalnie wydruk wyszedł bardzo ładnie: Na koniec zostało mi jeszcze przełożenie komponentów z płytki stykowej na płytkę uniwersalną: I upchanie wszystkiego do obudowy. Według mnie wszystko wyszło bardzo ładnie. Nie jest to finalna wersja stacji, bo ma ona wciąż bardzo dużo błędów. W następnej stacji pogodowej planuję zrobić: Lepiej zorganizować wnętrze. (uporządkować elektronikę w środku) Poprawić zatrzaski. (ciężko otworzyć teraz obudowę przez to że źle zrobiłem zatrzaski) Lepiej wymierzyć otwory na komponenty. (żeby wszystko się trzymało musiałem używać taśmy dwustronnej ) Zrobić coś w rodzaju siatki aby czujnik nie był odsłonięty. Zasłonić baterie, ale w taki sposób żeby dało się je w każdej chwili wymienić bez rozbierania obudowy. (bo nie są zasłonięte): To tyle z mojej strony, mam nadzieję że projekt się podobał. Ja z siebie sam jestem bardzo dumny bo jeszcze nigdy nie zrobiłem praktycznego urządzenia w ładnej obudowie. Nie wiem czy na tym forum jest to w zwyczaju, ale na koniec chciałbym podziękować kilku użytkownikom. Bardzo dziękuje użytkownikowi @AntekBezak za pomoc w podłączeniu wszystkiego oraz pomoc w napisaniu kodu. Za pomoc w napisaniu kodu dziękuje jeszcze @ethanak, @_LM_ oraz @KatzePL. Bez was nigdy bym sobie z tym nie poradził! Dziękuje też Tobie za przeczytanie całego DIY. Pozdrawiam!
