#include #include #include #include #include "DHT.h" #include "RTClib.h" //file system #include "FS.h" #include "SD.h" #include "SPI.h" #define Version "0.1" #define WIRE Wire #define DHTTYPE DHT22 #define DHTPIN 4 #define SD_CS 5 #define BTN_UP 33 #define BTN_ENTER 34 #define BTN_DOWN 35 #define VOLT_IN 36 const float voltageDividerFactor = 1.51;//1.56; const float adcMaxVoltage = 3.3; const int adcResolution = 4095; Adafruit_SSD1306 display = Adafruit_SSD1306(128, 32, &WIRE); DHT dht(DHTPIN, DHTTYPE); RTC_DS3231 rtc; // Obiekt dla DS3231 int menuL0 = 10; int menuL1 = 10; int menuL2 = 10; float hum; float temp; float heat_idx; int secs; int mins; int hourss; int dayss; int months; int years; int minsToSet = -1; int hoursToSet = -1; int adcVoltValue; float measuredVoltage = 0; float batteryVoltage = 0; int batteryBarWidth = 0; char dateString[21]; void setup() { Serial.begin(115200); Wire.begin(21, 22); analogSetAttenuation(ADC_11db); if (!rtc.begin()) { Serial.println("Nie znaleziono DS3231 RTC!"); while (1); // Zatrzymaj program, jeśli RTC nie jest dostępny } display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // Address 0x3C for 128x32 display.setTextSize(1); display.setTextColor(SSD1306_WHITE); display.clearDisplay(); display.println("Version:"); display.setCursor(0, 8); display.println(Version); display.setCursor(0, 16); display.println("DHT22"); display.setCursor(32, 16); display.println("RTC: DS3231"); display.setCursor(0, 24); display.println("Battery: 18h"); display.display(); delay(500); dht.begin(); pinMode(BTN_UP, INPUT_PULLDOWN ); pinMode(BTN_ENTER, INPUT_PULLDOWN ); pinMode(BTN_DOWN, INPUT_PULLDOWN ); display.clearDisplay(); display.setCursor(0,0); if (!SD.begin(SD_CS)) { display.println("Blad inicjaliz SD!"); display.display(); delay(1000); }else { Serial.println("Karta SD wykryta!"); } display.setCursor(0,16); // Tworzenie pliku File file = SD.open("/TempHumLog.txt", FILE_APPEND); if (file) { file.println("Dane zapisane z ESP32! V2"); file.println(Version); file.println("DataCzas; Temp; Humi; Feel"); file.close(); display.println("Plik utworzony!"); } else { display.println("Blad zapisu pliku!"); display.display(); delay(1000); } display.display(); delay(500); //setup END //###################### } void loop() { display.clearDisplay(); ////DIAGNOSTIC menu nr diag // display.setCursor(75, 16); // display.println(menuL0); // display.setCursor(90, 16); // display.println(menuL1); // display.setCursor(105, 16); // display.println(menuL2); hum = dht.readHumidity(); temp = dht.readTemperature(); // Compute heat index in Celsius (isFahreheit = false) heat_idx = dht.computeHeatIndex(temp, hum, false); //DATE DateTime now = rtc.now(); years = now.year(); months = now.month(); dayss = now.day(); hourss = now.hour(); mins = now.minute(); secs = now.second(); sprintf(dateString, "%02d/%02d/%4d %02d:%02d:%02d", now.day(), now.month(), now.year(), now.hour(), now.minute(), now.second()); if (mins % 1 == 0 && secs == 0) { File file = SD.open("/TempHumLog.txt", FILE_APPEND); if (file) { display.fillRect(0, 0, 124, 64, SSD1306_WHITE); file.print(dateString); file.print("; "); file.print(temp, 1); file.print("; "); file.print(hum, 1); file.print("; "); file.println(heat_idx, 1); file.close(); delay(1000); } } //zapis na SD: if (menuL0 == 10 ) { // ############# MENU TEMP display.setCursor(0, 0); display.println(dateString); //HUM&TEMP //######################################### display.setCursor(0, 8); display.println("Wilgotnosc:"); display.setCursor(85, 8); display.println(hum); display.setCursor(120, 8); display.println("%"); display.setCursor(0, 16); display.println("Temperatura:"); display.setCursor(85, 16); display.println(temp); display.setCursor(120,16); display.println("C"); display.setCursor(0, 24); display.println("Odczuwalna:"); display.setCursor(85, 24); display.println(heat_idx); display.setCursor(120,24); display.println("C"); } //dla indexu: Caution: > 27*C // Extreme Caution: > 32 *C // Danger: > 40 *C // Extreme Danger: > 52 *C //######################################### if (menuL0 == 9 ) { if (digitalRead(BTN_ENTER) == HIGH and menuL1 == 10) { menuL1 = 9; } display.setCursor(0, 0); sprintf(dateString, "%02d/%02d/%4d %02d:%02d:%02d", now.day(), now.month(), now.year(), now.hour(), now.minute(), now.second()); display.println(dateString); if (menuL1 == 10) { display.setCursor(0, 8); display.print("Enter edycja czasu"); } if (menuL1 == 9) { display.setCursor(0, 8); delay(100); display.print("Ustaw godziny"); delay(150); if (digitalRead(BTN_ENTER) == HIGH and menuL2 == 10) { menuL2 = 9; } if (menuL2 == 9){ display.setCursor(0,16); display.print("Godzina:"); display.setCursor(45,16); if (hoursToSet == -1){ hoursToSet = now.hour(); } display.print(hoursToSet); delay(100); if (digitalRead(BTN_ENTER) == HIGH) { // tu ustawianie czasu menuL2 = 10; rtc.adjust(DateTime(now.year(), now.month(), now.day(), hoursToSet, now.minute(), now.second())); hoursToSet = -1; } } } if (menuL1 == 8) { display.setCursor(0, 8); display.print("Ustaw minuty"); if (digitalRead(BTN_ENTER) == HIGH and menuL2 == 10) { menuL2 = 9; } if (menuL2 == 9){ display.setCursor(0,16); display.print("Minuta:"); display.setCursor(45,16); if (minsToSet == -1){ minsToSet = now.minute(); } display.print(minsToSet); delay(250); if (digitalRead(BTN_ENTER) == HIGH) { // tu ustawianie czasu menuL2 = 10; rtc.adjust(DateTime(now.year(), now.month(), now.day(), now.hour(), minsToSet, now.second())); minsToSet = -1; } } if (menuL2 == 6){ display.setCursor(0,24); display.print("Wyjdz"); if (digitalRead(BTN_ENTER) == HIGH) { menuL2 = 10; } } } if (menuL1 == 7 ) { display.setCursor(0, 8); display.print("Ustaw sekundy na 0"); if (digitalRead(BTN_ENTER) == HIGH and menuL2 == 10) { menuL2 = 9; } if (menuL2 == 9){ display.setCursor(0,16); display.print("Sekundy = 0"); delay(250); if (digitalRead(BTN_ENTER) == HIGH) { menuL2 = 10; rtc.adjust(DateTime(now.year(), now.month(), now.day(), now.hour(), now.minute(),0)); minsToSet = -1; } } } if (menuL1 == 6) { display.setCursor(0, 8); display.print("Wyjdz"); if (digitalRead(BTN_ENTER) == HIGH) { menuL1 = 10; } } } if (menuL0 == 8 ) { display.setCursor(0, 0); display.print("MENU TECH"); adcVoltValue = analogRead(VOLT_IN); // Odczyt wartości ADC z GPIO36 measuredVoltage = (adcVoltValue * adcMaxVoltage) / adcResolution; batteryVoltage = (measuredVoltage * voltageDividerFactor)+0.1; display.setCursor(70,0); display.print("V:"); display.setCursor(85, 0); display.print(batteryVoltage); display.drawRect(0, 9, 124, 7, SSD1306_WHITE); display.fillRect(124, 10, 5, 5, SSD1306_WHITE); batteryBarWidth = (((batteryVoltage-3)/1.2)*122); if (batteryBarWidth >122){ batteryBarWidth = 122; } display.fillRect(1, 10, batteryBarWidth, 5, SSD1306_WHITE); if (batteryVoltage < 2 ){ display.setCursor(60,8); display.print("xxx"); } if (digitalRead(BTN_UP) == HIGH) { display.setCursor(0, 24); display.print("UP"); } if (digitalRead(BTN_ENTER) == HIGH) { display.setCursor(30, 24); display.print("ENTER"); } if (digitalRead(BTN_DOWN) == HIGH) { display.setCursor(60, 24); display.print("DOWN"); } } if (digitalRead(BTN_UP) == HIGH and menuL0 <10 ) { if ( menuL0 < 10 && menuL1 == 10 ) { menuL0 = menuL0 + 1; } if (menuL1 < 9 && menuL2 == 10) { menuL1 = menuL1 + 1; } if (menuL2 < 9 and menuL0 != 10 and menuL1 != 10) { menuL2 = menuL2 + 1; } if (menuL2 == 9 and minsToSet <59) { minsToSet = minsToSet + 1; } if (menuL2 == 9 and hoursToSet < 23) { hoursToSet = hoursToSet + 1; } } if (digitalRead(BTN_DOWN) == HIGH and menuL0 >= 8) { if (menuL0 > 8 && menuL1 == 10 ) { menuL0 = menuL0 - 1; } if (menuL1 > 6 and menuL1 <= 9 && menuL2 == 10) { menuL1 = menuL1 - 1; } if (menuL2 > 6 and menuL2 < 9 and menuL0 != 10 and menuL1 != 10 ) { menuL2 = menuL2 - 1; } if (menuL2 == 9 and minsToSet > 1) { minsToSet = minsToSet - 1; } if (menuL2 == 9 and hoursToSet > 1) { hoursToSet = hoursToSet - 1; } } display.display(); delay(150); yield(); } // //float interpolate(float x, float x0, float x1, float y0, float y1) { // return y0 + (x - x0) * (y1 - y0) / (x1 - x0); //} // //// Funkcja przeliczająca zmierzone napięcie na procent naładowania //float voltageToPercentage(float voltage) { // // Jeśli napięcie jest poniżej minimalnego punktu – bateria uznajemy za rozładowaną // if (voltage <= voltagePoints[0]) // return percentPoints[0]; // // Jeśli napięcie przekracza najwyższy punkt – bateria jest pełna // if (voltage >= voltagePoints[numPoints - 1]) // return percentPoints[numPoints - 1]; // // // Szukamy przedziału, w którym mieści się zmierzone napięcie, i stosujemy interpolację // for (int i = 0; i < numPoints - 1; i++) { // if (voltage >= voltagePoints[i] && voltage < voltagePoints[i+1]) { // return interpolate(voltage, voltagePoints[i], voltagePoints[i+1], percentPoints[i], percentPoints[i+1]); // } // } // return 0; //} //Main feature: // RTC z możliwością ustawienia godziny // odczyt wilgotności, temperatury i temperatury odcuwalnej // zasilanie bateryjne // menu //2DO zapis na karcie SD