//https://www.youtube.com/watch?v=VOUOs_sTHUw <--- Multitasking
#include <Wire.h>
#include <hd44780.h>
#include <hd44780ioClass/hd44780_I2Cexp.h>
hd44780_I2Cexp lcd;
#include <WiFi.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>
#include <TM1637Display.h>
const int CLK = 14;
const int DIO = 12;
const int MOTION_PIN = 27;
const char* ssid = "Wokwi-GUEST";
const char* password = "";
int mode = 0;
int pirState = LOW;
int val = 0;
#define NTP_SERVER "pool.ntp.org"
#define UTC_OFFSET 0
#define UTC_OFFSET_DST 0
#define LOCATION_API "https://geocoding-api.open-meteo.com/v1/search?name=Lingen&count=1&language=en&format=json"
#define WEATHER_API "https://api.open-meteo.com/v1/forecast?latitude=%f&longitude=%f&hourly=temperature_2m¤t_weather=true"
TM1637Display display(CLK, DIO);
struct GeoLocation {
float longitude;
float latitude;
};
struct CurrentWeather {
float temperature;
};
bool processHttpRequest(String url, DynamicJsonDocument& doc) {
HTTPClient http;
http.useHTTP10(true);
http.begin(url);
http.GET();
String result = http.getString();
DeserializationError error = deserializeJson(doc, result);
if (error) {
Serial.println("Couldn't process http request.");
return false;
}
return true;
}
GeoLocation getGeoLocation() {
DynamicJsonDocument doc(2048);
processHttpRequest(LOCATION_API, doc);
float longitude = doc["results"][0]["longitude"].as<float>();
float latitude = doc["results"][0]["latitude"].as<float>();
return {longitude, latitude};
};
CurrentWeather getWeather() {
const GeoLocation location = getGeoLocation();
char url[200];
sprintf(url, "https://api.open-meteo.com/v1/forecast?latitude=%f&longitude=%f&hourly=temperature_2m¤t_weather=true", location.latitude, location.longitude);
DynamicJsonDocument doc(2048);
processHttpRequest(url, doc);
float currentTemperature = doc["current_weather"]["temperature"].as<float>();
return {currentTemperature};
};
void setup() {
lcd.begin(16, 2);
lcd.begin(16, 2);
lcd.begin(16, 2);
lcd.begin(16, 2);
lcd.begin(16, 2);
lcd.begin(16, 2);
Serial.begin(9600);
pinMode(MOTION_PIN, INPUT); // declare sensor as input
display.setBrightness(0x0a);
WiFi.begin(ssid, password, 6);
while (WiFi.status() != WL_CONNECTED) {
delay(100);
display.showNumberDec(1111);
}
setenv("TZ","CET-1CEST,M3.5.0,M10.5.0/3",1);
tzset();
configTime(UTC_OFFSET, UTC_OFFSET_DST, NTP_SERVER);
}
void detectMotion() {
val = digitalRead(MOTION_PIN);
if (val == HIGH) {
if (pirState == LOW) {
Serial.println("Motion detected!");
display.setBrightness(9, true);
pirState = HIGH;
}
} else {
if (pirState == HIGH) {
Serial.println("Motion ended!");
display.setBrightness(3, true);
pirState = LOW;
}
}
}
void loop() {
detectMotion();
struct tm timeinfo;
if(!getLocalTime(&timeinfo)){
display.showNumberDec(6666);
return;
}
const CurrentWeather weather = getWeather();
char curTemp[200];
char timeString[200];
sprintf(curTemp, "%.1f C in Lingen", weather.temperature);
sprintf(timeString, "%02d:%02d:%02d", timeinfo.tm_hour, timeinfo.tm_min, timeinfo.tm_sec);
// lcd.setCursor(0, 0);
lcd.print(curTemp);
// lcd.setCursor(0, 1);
lcd.print(timeString);
switch(mode) {
case 0:
display.showNumberDec(timeinfo.tm_hour * 100 + timeinfo.tm_min);
break;
case 1:
display.showNumberDec(timeinfo.tm_mday * 100 + timeinfo.tm_mon + 1);
break;
case 2:
display.showNumberDec(1900 + timeinfo.tm_year);
break;
case 3:
{
display.showNumberDec(weather.temperature);
}
break;
}
if(mode + 1 > 3) {
mode = 0;
} else {
mode = mode + 1;
}
//delay(1000);
}