Files
Arduino/ESP32/TempHumLoggerHomeKit/TempHumLoggerHomeKit.ino
2025-02-21 22:58:13 +01:00

482 lines
12 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include "DHT.h"
#include "RTClib.h"
//file system
#include "FS.h"
#include "SD.h"
#include "SPI.h"
#define Version "0.11"
#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];
String formatNumber(float number, int decimalPlaces = 1 ) {
String str = String(number, decimalPlaces);
str.replace('.', ',');
return str;
}
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 );
rtc.now();
DateTime now = rtc.now();
years = now.year();
months = now.month();
dayss = now.day();
hourss = now.hour();
mins = now.minute();
secs = now.second();
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);
if (SD.exists("/TempHumLog.txt")) {
} else {
File file = SD.open("/TempHumLog.txt", FILE_APPEND);
file.println("Data; Godzina; Temp; Humi; Feel");
file.close();
}
sprintf(dateString, "%02d/%02d/%4d %02d:%02d:%02d", now.day(), now.month(), now.year(), now.hour(), now.minute(), now.second());
if (SD.exists("/GeneralLog.txt")) {
} else {
File file = SD.open("/GeneralLog.txt", FILE_APPEND);
file.print("Utworzono: ");
file.print(dateString);
file.print(" Wersja: ");
file.println(Version);
file.close();
}
File file = SD.open("/GeneralLog.txt", FILE_APPEND);
file.print("Uruchomienie: ");
file.print(dateString);
file.print(" Wersja: ");
file.println(Version);
file.close();
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 (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");
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;
}
}
adcVoltValue = analogRead(VOLT_IN); // Odczyt wartości ADC z GPIO36
measuredVoltage = (adcVoltValue * adcMaxVoltage) / adcResolution;
batteryVoltage = (measuredVoltage * voltageDividerFactor)+0.1;
// Log napiećia docelowoe procent baterii
// kiedy zaden przycisk nie jest wcisniety
if (mins % 1 == 0 && secs == 0) {
File file = SD.open("/GeneralLog.txt", FILE_APPEND);
if (file) {
display.fillRect(0, 0, 124, 64, SSD1306_WHITE);
file.print(dateString);
file.print(" Battery V: ");
file.println(formatNumber(batteryVoltage, 2));
file.close();
}
}
//zapis na SD:
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(leadZero(dayss));
file.print("/");
file.print(leadZero(months));
file.print("/");
file.print(years);
file.print("; ");
file.print(hourss);
file.print(":");
file.print(leadZero(mins));
file.print("; ");
file.print(formatNumber(temp));
file.print("; ");
file.print(formatNumber(hum));
file.print("; ");
file.println(formatNumber(heat_idx));
file.close();
delay(1000);
}
}
display.display();
delay(150);
yield();
}
String leadZero(float number) {
String str = String(int(number));
str.trim();
if (number < 10) {
str = "0" + str;
}
return str;
}
//
//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