Last version 29.10.2026
parent
80b24807ea
commit
9ef2374cd5
|
|
@ -0,0 +1,156 @@
|
|||
#include <LiquidCrystal.h>
|
||||
#include <dht_nonblocking.h>
|
||||
#include <SoftwareSerial.h>
|
||||
#include <WiFiEsp.h>
|
||||
|
||||
// Wifi (Hotspot)
|
||||
const char wifiSSID[] = "FreeWifi";
|
||||
const char wifiPASS[] = "temppassword";
|
||||
|
||||
// ESP8266 (Wifi module, AT firmware)
|
||||
SoftwareSerial wifiSerial(2, 3); // RX = 2, TX = 3
|
||||
WiFiEspClient client;
|
||||
|
||||
// LCD Display
|
||||
#define DHT_SENSOR_TYPE DHT_TYPE_11
|
||||
static const int DHT_SENSOR_PIN = A1;
|
||||
DHT_nonblocking dht_sensor(DHT_SENSxOR_PIN, DHT_SENSOR_TYPE);
|
||||
|
||||
LiquidCrystal lcd(7, 8, 9, 10, 11, 12); // RS, EN, D4, D5, D6, D7
|
||||
|
||||
// Light sensor and LEDs
|
||||
int lightPin = A0; // LDR
|
||||
int dataPin = 4; // DS
|
||||
int latchPin = 5; // ST_CP
|
||||
int clockPin = 6; // SH_CP
|
||||
int leds = 0;
|
||||
|
||||
// API
|
||||
const float NO_TEMP = -999.0;
|
||||
const unsigned long API_INTERVAL = 600000UL; // 10m
|
||||
const unsigned long RETRY_INTERVAL = 30000UL; // 30s
|
||||
unsigned long lastApiFetch = 0;
|
||||
unsigned long fetchInterval = API_INTERVAL;
|
||||
float outdoorTemp = NO_TEMP;
|
||||
|
||||
// Connect to hotspot if not connected, then fetch the current temperature
|
||||
float fetchOutdoorTemp() {
|
||||
if (WiFi.status() != WL_CONNECTED) {
|
||||
WiFi.begin(wifiSSID, wifiPASS);
|
||||
if (WiFi.status() != WL_CONNECTED) return NO_TEMP;
|
||||
}
|
||||
|
||||
client.setTimeout(5000);
|
||||
if (!client.connect("api.open-meteo.com", 80)) return NO_TEMP;
|
||||
|
||||
client.print(F("GET /v1/forecast?latitude=49.46998&longitude=8.4819¤t=temperature_2m HTTP/1.1\r\n"
|
||||
"Host: api.open-meteo.com\r\n"
|
||||
"Connection: close\r\n"
|
||||
"\r\n"));
|
||||
|
||||
// Skip ahead to the number in {"current":{..."temperature_2m":12.3}}
|
||||
float t = NO_TEMP;
|
||||
if (client.find("\"current\":") && client.find("\"temperature_2m\":")) {
|
||||
t = client.parseFloat();
|
||||
}
|
||||
client.stop();
|
||||
return t;
|
||||
}
|
||||
|
||||
// Write to LCD display
|
||||
void lcdLine(uint8_t row, const char *text) {
|
||||
lcd.setCursor(0, row);
|
||||
uint8_t i = 0;
|
||||
for (; text[i] != '\0' && i < 16; i++) lcd.write(text[i]);
|
||||
for (; i < 16; i++) lcd.write(' ');
|
||||
}
|
||||
|
||||
// LEDs for light sensor
|
||||
void updateShiftRegister() {
|
||||
digitalWrite(latchPin, LOW);
|
||||
shiftOut(dataPin, clockPin, LSBFIRST, leds);
|
||||
digitalWrite(latchPin, HIGH);
|
||||
}
|
||||
|
||||
// Measure temperature and humidity
|
||||
static bool measure_environment(float *temp, float *hum) {
|
||||
static unsigned long timestamp = millis();
|
||||
|
||||
if (millis() - timestamp > 3000ul) {
|
||||
if (dht_sensor.measure(temp, hum) == true) {
|
||||
timestamp = millis();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void setup() {
|
||||
pinMode(latchPin, OUTPUT);
|
||||
pinMode(dataPin, OUTPUT);
|
||||
pinMode(clockPin, OUTPUT);
|
||||
|
||||
Serial.begin(115200);
|
||||
lcd.begin(16, 2);
|
||||
lcdLine(0, "Connecting WiFi");
|
||||
lcdLine(1, "");
|
||||
|
||||
wifiSerial.begin(9600);
|
||||
WiFi.init(&wifiSerial);
|
||||
|
||||
if (WiFi.status() == WL_NO_SHIELD) {
|
||||
lcdLine(0, "ESP not found");
|
||||
delay(2000);
|
||||
}
|
||||
|
||||
outdoorTemp = fetchOutdoorTemp();
|
||||
lastApiFetch = millis();
|
||||
fetchInterval = (outdoorTemp == NO_TEMP) ? RETRY_INTERVAL : API_INTERVAL;
|
||||
lcd.clear();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
float indoorTemp;
|
||||
float indoorHum;
|
||||
|
||||
if (measure_environment(&indoorTemp, &indoorHum) == true) {
|
||||
char tempStr[10];
|
||||
dtostrf(indoorTemp, 4, 1, tempStr);
|
||||
char line0[20];
|
||||
snprintf(line0, sizeof(line0), "In: %s C", tempStr);
|
||||
lcdLine(0, line0);
|
||||
}
|
||||
|
||||
if (millis() - lastApiFetch >= fetchInterval) {
|
||||
float t = fetchOutdoorTemp();
|
||||
lastApiFetch = millis();
|
||||
if (t != NO_TEMP) {
|
||||
outdoorTemp = t;
|
||||
fetchInterval = API_INTERVAL;
|
||||
} else {
|
||||
fetchInterval = RETRY_INTERVAL;
|
||||
}
|
||||
}
|
||||
|
||||
if (outdoorTemp != NO_TEMP) {
|
||||
char outStr[10];
|
||||
dtostrf(outdoorTemp, 4, 1, outStr);
|
||||
char line1[20];
|
||||
snprintf(line1, sizeof(line1), "Out: %s C", outStr);
|
||||
lcdLine(1, line1);
|
||||
} else {
|
||||
lcdLine(1, "Out: API Error");
|
||||
}
|
||||
|
||||
int reading = analogRead(lightPin);
|
||||
int numLEDSLit = reading / 57;
|
||||
|
||||
if (numLEDSLit > 8) numLEDSLit = 8;
|
||||
leds = 0;
|
||||
for (int i = 0; i < numLEDSLit; i++) {
|
||||
leds = leds + (1 << i);
|
||||
}
|
||||
updateShiftRegister();
|
||||
|
||||
delay(100);
|
||||
}
|
||||
Loading…
Reference in New Issue