#include "DHT.h"
#include <ESP32Servo.h>
#include "ThingSpeak.h"
#include <WiFi.h>
#include <HTTPClient.h>
//wifi details
const char* WIFI_NAME = "Wokwi-GUEST";
const char* WIFI_PASS = "";
WiFiClient client;
//thingspeak details
const int myChannelNumber = 2544553;
const char* write_API_Key = "RJVPD5U00E5XJQHL";
const char* server = "api.thingspeak.com";
HTTPClient http;
float humd = 0.0;
float temp = 0.0;
// Déclaration des constantes pour les seuils de luminosité
const int DARK = 200;
const int LIGHT = 500;
const int BRIGHT = 800;
const int VERY_BRIGHT = 1000;
// Déclaration des broches pour les composants
#define PIN_RED 12
#define PIN_GREEN 14
#define PIN_BLUE 27
#define digital_In 34
#define analog_In 35
#define POT_PIN 25
#define SERVO_PIN 32
#define DHT_PIN 13
//Seuil CO2 (Scenario 1)
const int CO2_UNDER_7500 = 45;
const int CO2_UNDER_10000 = 90;
const int CO2_UNDER_15000 = 135;
//Seuil humidité
const int HUMD_UNDER_50 = 45;
const int HUMD_UNDER_60 = 90;
const int HUMD_UNDER_70 = 135;
//Seuil temperature (Scenario 2)
const int SEUIL_TEMP = 23;
// Déclaration des objets
DHT dht(DHT_PIN, DHT22);
Servo servo;
// Déclaration du tableau de broches LED
const int ledCount = 10;
int ledPins[] = {23, 22, 21, 19, 18, 5, 17, 16, 4, 2};
// L'angle d'ouvertures courante du servo
int CURRENT_ANGLE = 0;
//lire valeur du potentiometre
void updateLampControlField5(int value) {
// Construct the URL for updating the ThingSpeak field
String url = "http://" + String(server) + "/update?api_key=" + write_API_Key + "&field5=" + String(value);
// Send HTTP GET request to update the field
http.begin(client, url);
int httpResponseCode = http.GET();
if (httpResponseCode == 200) {
Serial.println("Lamp control field updated successfully");
} else {
Serial.print("Error updating lamp control field. HTTP response code: ");
Serial.println(httpResponseCode);
}
http.end();
}
void updateLampControlField6(int value) {
// Construct the URL for updating the ThingSpeak field
String url = "http://" + String(server) + "/update?api_key=" + write_API_Key + "&field6=" + String(value);
// Send HTTP GET request to update the field
http.begin(client, url);
int httpResponseCode = http.GET();
if (httpResponseCode == 200) {
Serial.println("Lamp control field updated successfully");
} else {
Serial.print("Error updating lamp control field. HTTP response code: ");
Serial.println(httpResponseCode);
}
http.end();
}
void updateLampControlField4(int value) {
// Construct the URL for updating the ThingSpeak field
String url = "http://" + String(server) + "/update?api_key=" + write_API_Key + "&field4=" + String(value);
// Send HTTP GET request to update the field
http.begin(client, url);
int httpResponseCode = http.GET();
if (httpResponseCode == 200) {
Serial.println("Lamp control field updated successfully");
} else {
Serial.print("Error updating lamp control field. HTTP response code: ");
Serial.println(httpResponseCode);
}
http.end();
}
void climatiseur(){
float temp = dht.readTemperature();
if(isnan(temp)){
Serial.println(F("Failed to read Temperature"));
}else{
Serial.print("Current temperature is ");
Serial.print(temp);
Serial.print(" °C, ");
if(temp > SEUIL_TEMP){
Serial.println("bigger then threshold (23 °C) => Cooling");
analogWrite(PIN_RED, 0);
analogWrite(PIN_GREEN, 0);
analogWrite(PIN_BLUE, 255);
}else{
Serial.println("smaller then threshold (23 °C) => Heating");
analogWrite(PIN_RED, 255);
analogWrite(PIN_GREEN, 0);
analogWrite(PIN_BLUE, 0);
}
}
}
void luminosite() {
int analogValue = analogRead(analog_In);
float voltage = analogValue / 4096.0 * 5.0;
float resistance = 2000.0 * voltage / (1.0 - voltage / 5.0);
float lux_a = pow(50.0 * 1000.0 * pow(10.0, 0.7) / resistance, 1.0 / 0.7);
Serial.print("Analog: Lux ");
Serial.println(lux_a);
// Allumer les LED en fonction de la luminosité
if (lux_a <= DARK) {
Serial.println("Dark");
for (int i = 0; i < 4; i++) {
digitalWrite(ledPins[0], HIGH);
digitalWrite(ledPins[1], LOW);
digitalWrite(ledPins[2], LOW);
digitalWrite(ledPins[3], LOW);
}
} else if (lux_a <= LIGHT) {
Serial.println("Light");
for (int i = 0; i < 4; i++) {
digitalWrite(ledPins[0], HIGH);
digitalWrite(ledPins[1], HIGH);
digitalWrite(ledPins[2], LOW);
digitalWrite(ledPins[3], LOW);
}
} else if (lux_a <= BRIGHT) {
Serial.println("Bright");
for (int i = 0; i < 4; i++) {
digitalWrite(ledPins[0], HIGH);
digitalWrite(ledPins[1], HIGH);
digitalWrite(ledPins[2], HIGH);
digitalWrite(ledPins[3], LOW);
}
} else {
Serial.println("Very Bright");
for (int i = 0; i < 4; i++) {
digitalWrite(ledPins[0], HIGH);
digitalWrite(ledPins[1], HIGH);
digitalWrite(ledPins[2], HIGH);
digitalWrite(ledPins[3], HIGH);
}
}
}
int angleFromPot(){
potValue = map(potValue, 0, 4095, 0, 17000);//concentration du CO2 (0ppm - 3000ppm)
//choisir l'angle d'ouverture de la fenetre
int angle = 0;
if(potValue <400){
angle = 0;
Serial.println("CO2 concentration below 400ppm, close window");
}else if(potValue < 7500){
angle = CO2_UNDER_7500;
Serial.print("CO2 concentration below 7500ppm, open window by ");
Serial.println(CO2_UNDER_7500);
}else if(potValue < 10000){
angle = CO2_UNDER_10000;
Serial.print("CO2 concentration below 10000ppm, open window by ");
Serial.println(CO2_UNDER_10000);
}else if(potValue < 15000){
angle = CO2_UNDER_15000;
Serial.print("CO2 concentration below 15000ppm, open window by ");
Serial.println(CO2_UNDER_15000);
}else{
Serial.println("CO2 concentration over 15000ppm, open window fully");
angle = 180;
}
return angle;
}
int angleFromDht(){
float humd = dht.readHumidity();
//choisir l'angle d'ouverture de la fenetre
int angle = 0;
if(humd < 40){
angle = 0;
Serial.println("Humidity below 40%, close window");
}else if(humd < 50){
angle = HUMD_UNDER_50;
Serial.print("Humidity below 50%, open window by ");
Serial.println(HUMD_UNDER_50);
}else if(humd < 60){
angle = HUMD_UNDER_60;
Serial.print("Humidity below 60%, open window by ");
Serial.println(HUMD_UNDER_60);
}else if(humd < 70){
angle = HUMD_UNDER_70;
Serial.print("Humidity below 70%, open window by ");
Serial.println(HUMD_UNDER_70);
}else{
Serial.println("Humidity over 70%, open window fully");
angle = 180;
}
return angle;
}
void fenetre(){
potValue = analogRead(POT_PIN);
potValue = map(potValue, 0, 4095, 0, 17000);
//angle d'ouverture selon concentration CO2
int firstAngle = angleFromPot();
//angle d'ouverture selon l'humidite
int secAngle = angleFromDht();
int angle = max(firstAngle, secAngle);
//changer l'angle d'ouverture du servo
int difference = CURRENT_ANGLE - angle;
if(difference < 0){
ouvrirServo(abs(difference));
}else{
fermerServo(difference);
}
CURRENT_ANGLE = angle;
}
void ouvrirServo(int angle) {
for (int i = 0; i <= angle; i++) {
servo.write(CURRENT_ANGLE + i);
delay(15);
}
}
void fermerServo(int angle) {
for (int i = 0; i <= angle; i++) {
servo.write(CURRENT_ANGLE - i);
delay(15);
}
}
void setup() {
Serial.begin(115200);
dht.begin();
WiFi.begin(WIFI_NAME, WIFI_PASS);
while (WiFi.status() != WL_CONNECTED){
delay(1000);
Serial.println("Wifi not connected");
}
Serial.println("Wifi connected !");
Serial.println("Local IP: " + String(WiFi.localIP()));
WiFi.mode(WIFI_STA);
ThingSpeak.begin(client);
//Initialisation des composants
dht.begin();
servo.attach(SERVO_PIN);
servo.write(0);
//Configuration des entrées et sorties
pinMode(POT_PIN, INPUT);
pinMode(PIN_RED, OUTPUT);
pinMode(PIN_GREEN, OUTPUT);
pinMode(PIN_BLUE, OUTPUT);
pinMode(digital_In, INPUT);
pinMode(analog_In, INPUT);
for (int thisLed = 0; thisLed < ledCount; thisLed++) {
pinMode(ledPins[thisLed], OUTPUT);
}
delay(2000);
}
void loop() {
//2. Scénario : Température
climatiseur();
//3. Scénario : Luminosité
luminosite();
//1. Scénario : CO2 élevé
fenetre();
Serial.println();
//TempAndHumidity data = dhtSensor.getTempAndHumidity();
humd = dht.readHumidity();
temp = dht.readTemperature();
if (isnan(humd) || isnan(temp) || isnan(potValue) ){
Serial.println(F("Failed to read !"));
return;
}
sendDataToThingSpeak();
delay(16000);
}
void sendDataToThingSpeak(){
updateLampControlField6(0);
updateLampControlField5(0);
updateLampControlField4(0);
int analogValue = analogRead(analog_In);
float voltage = analogValue / 4096.0 * 5.0;
float resistance = 2000.0 * voltage / (1.0 - voltage / 5.0);
float lux_a = pow(50.0 * 1000.0 * pow(10.0, 0.7) / resistance, 1.0 / 0.7);
String verybright, light , dark ;
// Determine the color based on lux value
if (lux_a <= DARK) {
dark = "Red"; // Low brightness
Serial.println("brightness : " + dark);
updateLampControlField6(1);
updateLampControlField5(0);
updateLampControlField4(0);
} else if (lux_a <= LIGHT) {
light = "Yellow"; // Medium brightness
Serial.println("brightness :" + light);
updateLampControlField5(1);
updateLampControlField6(0);
updateLampControlField4(0);
} else {
verybright = "Green"; // High brightness
Serial.println("brightness : " + verybright);
updateLampControlField4(1);
updateLampControlField5(0);
updateLampControlField6(0);
}
ThingSpeak.setField(1,temp);
ThingSpeak.setField(2,humd);
ThingSpeak.setField(3, potValue);
ThingSpeak.setField(4, lux_a > BRIGHT ? "Green" : "");
ThingSpeak.setField(5, lux_a > LIGHT && lux_a <= BRIGHT ? "Yellow" : "");
ThingSpeak.setField(6, lux_a <= DARK ? "Red" : "");
int writeResult = ThingSpeak.writeFields(myChannelNumber,write_API_Key);
Serial.println("Temperature: " + String(temp, 2) + "°C");
Serial.println("Humidity: " + String(humd, 1) + "%");
Serial.println("CO2: " + String(potValue) + " ppm");
if(writeResult == 200){
Serial.println("Data pushed successfull");
}else{
Serial.println("Push error" + String(writeResult));
}
Serial.println("---");
delay(500);
}