//#define BLYNK_TEMPLATE_ID "TMPL2wOU4LVmb"
//#define BLYNK_TEMPLATE_NAME "TR UNITE5"
//#define BLYNK_AUTH_TOKEN "iKA9LE_7PlppDg7O841IzZ82jZ6CaTuF"
//#define BLYNK_TEMPLATE_ID "TMPL2efkRieKb"
//#define BLYNK_TEMPLATE_NAME "TRE ON 01"
//#define BLYNK_AUTH_TOKEN "i8GPQdIA2DQZuYl1n_FGnomiGikCWJoV"
#define BLYNK_TEMPLATE_ID "TMPL2O1HIaAQI"
#define BLYNK_TEMPLATE_NAME "USER FURE 02"
#define BLYNK_AUTH_TOKEN "X0-iwmvMjoKca076YPJSHP-YjTa6UG0g"
char auth[] = BLYNK_AUTH_TOKEN;
#include <WiFi.h>
#include <BlynkSimpleEsp32.h>
#include <DHT.h>
#include <DHT_U.h>
// Blynk Authentication Token
//char ssid[] = "not working";
//char pass[] = "FETTAH2018"; // Your WiFi password
char ssid[] = "Fibre_MarocTelecom-8DE1";
char pass[] = "e72AYe95SX";
//char ssid[] = "Wokwi-GUEST";
//char pass[] = "";
// Pins
const int ledPins[] = {1, 2, 5, 6, 7, 15, 16, 17, 18, 8, 3, 46, 9, 10, 11, 12, 13, 14, 19, 20}; // 20 LEDs
const int ledCount = sizeof(ledPins) / sizeof(ledPins[0]);
const int ledControlPin = 0; // One LED on/off
const int buttonTogglePin = 35;
const int buttonUpPin = 36;
const int buttonDownPin = 37;
const int trigUp = 21;
const int echoUp = 47;
const int trigDown = 48;
const int echoDown = 45;
#define ENA 38
#define IN1 39
#define IN2 40
// Debounce
unsigned long debounceDelay = 100;
unsigned long lastToggleTime = 0;
unsigned long lastUpTime = 0;
unsigned long lastDownTime = 0;
// States
bool ledState = false;
bool isAnimating = false;
bool directionUp = true;
bool fetch_blynk_state = true; //true or false
int currentLed = 0;
unsigned long lastStepTime = 0;
unsigned long stepDelay = 300;
unsigned long holdTime = 2000;
enum State { IDLE, ON, HOLD, OFF };
State state = IDLE;
int motorSpeed = 0; // Initial motor speed
int motorDirection = 1;
float temperatureThreshold = 25.0;
// DHT Sensor
#define DHTPIN 4
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
// Blynk
WidgetLCD lcd(V0);
bool blynkUp = false;
bool blynkDown = false;
bool blynkLedControl = false;
int wifiFlag = 0;
BlynkTimer timer;
BLYNK_WRITE(V1) { blynkUp = param.asInt(); }
BLYNK_WRITE(V2) { blynkDown = param.asInt(); }
BLYNK_WRITE(V3) {
blynkLedControl = param.asInt();
digitalWrite(ledControlPin, blynkLedControl ? HIGH : LOW);
//Blynk.virtualWrite(V3)
}
void checkBlynkStatus()
{ // called every 3 seconds by SimpleTimer
bool isconnected = Blynk.connected();
if (isconnected == false)
{
wifiFlag = 1;
Serial.println("Blynk Not Connected");
//digitalWrite(wifiLed, LOW);
}
if (isconnected == true)
{
wifiFlag = 0;
if (!fetch_blynk_state)
{
Blynk.virtualWrite(ledControlPin,ledState);
}
//digitalWrite(wifiLed, HIGH);
Serial.println("Blynk Connected");
}
}
BLYNK_CONNECTED()
{
// Request the latest state from the server
if (fetch_blynk_state)
{
Blynk.syncVirtual(buttonTogglePin);
}
}
void readTemperature() {
float temperature = dht.readTemperature();
if (isnan(temperature)) {
Serial.println("Failed to read from DHT sensor!");
return;
}
Serial.print("Temperature: ");
Serial.print(temperature);
Serial.println(" *C");
// Adjust motor speed based on temperature
if (temperature <= temperatureThreshold) {
motorSpeed = 0; // If temperature is below or equal to 20°C, stop the motor
} else if (temperature > 20 && temperature <= 35) {
motorSpeed = map(temperature, 20, 35, 60, 255); // Map temperature range to motor speed range (1V to 9V)
} else {
motorSpeed = 255; // If temperature exceeds 35°C, set motor speed to maximum (9V)
}
// Set motor direction
if (motorDirection == 1) {
digitalWrite(IN1, LOW);
digitalWrite(IN2, HIGH);
} else {
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW);
}
// Set motor speed
analogWrite(ENA, motorSpeed);
}
void setup() {
Serial.begin(115200);
//Blynk.begin(auth, ssid, pass);
for (int i = 0; i < ledCount; i++) {
pinMode(ledPins[i], OUTPUT);
digitalWrite(ledPins[i], LOW);
}
pinMode(ledControlPin, OUTPUT);
digitalWrite(ledControlPin, LOW);
pinMode(buttonTogglePin, INPUT_PULLUP);
pinMode(buttonUpPin, INPUT_PULLUP);
pinMode(buttonDownPin, INPUT_PULLUP);
pinMode(IN1, OUTPUT);
pinMode(IN2, OUTPUT);
pinMode(ENA, OUTPUT);
pinMode(trigUp, OUTPUT);
pinMode(echoUp, INPUT);
pinMode(trigDown, OUTPUT);
pinMode(echoDown, INPUT);
lcd.clear();
lcd.print(0, 0, "Staircase Ready");
WiFi.begin(ssid, pass);
timer.setInterval(2000L, checkBlynkStatus); // check if Blynk server is connected every 2 seconds
Blynk.config(auth);
dht.begin();
timer.setInterval(100L, updateLCD);
timer.setInterval(200L, readTemperature);
}
long readDistanceCM(int trig, int echo) {
digitalWrite(trig, LOW); delayMicroseconds(2);
digitalWrite(trig, HIGH); delayMicroseconds(10);
digitalWrite(trig, LOW);
long duration = pulseIn(echo, HIGH, 30000);
return duration * 0.034 / 2;
}
void toggleMainLED() {
ledState = !ledState;
digitalWrite(ledControlPin, ledState ? HIGH : LOW);
Blynk.virtualWrite(V3 ,ledState);
}
void triggerSequence(bool up) {
directionUp = up;
currentLed = up ? 0 : ledCount - 1;
state = ON;
isAnimating = true;
lastStepTime = millis();
lcd.clear();
lcd.print(0, 0, up ? "UP Animation" : "DOWN Animation");
}
void handleButtons() {
unsigned long now = millis();
// Button DOWN Handling (Debounce)
if (digitalRead(buttonTogglePin) == LOW && millis() - lastToggleTime > debounceDelay) {
lastToggleTime = now;
toggleMainLED();
while (digitalRead(buttonTogglePin) == LOW); // Wait for release
Blynk.virtualWrite(V3, ledState);
}
// Button DOWN Handling (Debounce)
if (digitalRead(buttonUpPin) == LOW && millis() - lastUpTime > debounceDelay) {
lastUpTime = now;
triggerSequence(true);
while (digitalRead(buttonUpPin) == LOW); // Wait for release
Blynk.virtualWrite(V1, 1);
}
// Button DOWN Handling (Debounce)
if (digitalRead(buttonDownPin) == LOW && millis() - lastDownTime > debounceDelay) {
lastDownTime = now;
triggerSequence(false);
while (digitalRead(buttonDownPin) == LOW); // Wait for release
Blynk.virtualWrite(V2, 2);
}
}
void handleUltrasonic() {
unsigned long now = millis();
if (readDistanceCM(trigUp, echoUp) < 60 && now - lastUpTime > debounceDelay && state == IDLE) {
lastUpTime = now;
triggerSequence(true);
Blynk.virtualWrite(V1, 1);
}
if (readDistanceCM(trigDown, echoDown) < 60 && now - lastDownTime > debounceDelay && state == IDLE) {
lastDownTime = now;
triggerSequence(false);
Blynk.virtualWrite(V2, 2);
}
}
void handleBlynkTriggers() {
if (blynkUp && state == IDLE) {
blynkUp = false;
triggerSequence(true);
}
if (blynkDown && state == IDLE) {
blynkDown = false;
triggerSequence(false);
}
}
void runLedAnimation() {
unsigned long now = millis();
if (state == ON && now - lastStepTime > stepDelay) {
digitalWrite(ledPins[currentLed], HIGH);
lastStepTime = now;
if (directionUp) {
currentLed++;
if (currentLed >= ledCount) {
state = HOLD;
lastStepTime = now;
}
} else {
currentLed--;
if (currentLed < 0) {
state = HOLD;
lastStepTime = now;
}
}
}
if (state == HOLD && now - lastStepTime > holdTime) {
state = OFF;
currentLed = directionUp ? 0 : ledCount - 1;
lastStepTime = now;
}
if (state == OFF && now - lastStepTime > stepDelay) {
digitalWrite(ledPins[currentLed], LOW);
lastStepTime = now;
if (directionUp) {
currentLed++;
if (currentLed >= ledCount) {
state = IDLE;
isAnimating = false;
Blynk.virtualWrite(V1, 0);
lcd.clear();
lcd.print(0, 0, "Staircase Ready");
}
} else {
currentLed--;
if (currentLed < 0) {
state = IDLE;
isAnimating = false;
Blynk.virtualWrite(V2, 0);
lcd.clear();
lcd.print(0, 0, "Staircase Ready");
}
}
}
}
void loop() {
Blynk.run();
timer.run();
handleButtons();
handleUltrasonic();
handleBlynkTriggers();
if (isAnimating) runLedAnimation();
}
void updateLCD() {
float temperature = dht.readTemperature();
if (isnan(temperature)) {
lcd.print(0, 1, "T:Err");
} else {
lcd.print(0, 1, "T:" + String(temperature) + "C");
}
lcd.print(8, 1, "R:" + String(temperatureThreshold) + "C");
if (temperature <= temperatureThreshold) {
lcd.print(13, 0,"M:f");
} else if (temperature > 20 && temperature <= 30) {
lcd.print(13, 0, "M:n");
} else {
lcd.print(13, 0, "M:n");
}
}