#define BLYNK_PRINT Serial
#define BLYNK_TEMPLATE_ID "TMPL6Paeb2Es8"
#define BLYNK_TEMPLATE_NAME "LEDtest11800"
#define BLYNK_AUTH_TOKEN "CsxYybEwvhwv9dETAQ1N0T4lLaGxs7O1"
#include <LiquidCrystal_I2C.h>
#include "DHTesp.h"
#include <WiFi.h>
#include <WiFiClient.h>
#include <BlynkSimpleEsp32.h>
// ================== LED ==================
int pinLED1 = 2;
int pinLED2 = 4;
// ================== Stepper Motor with A4988 ==================
#define STEP_LEFT 25
#define DIR_LEFT 26
#define STEP_RIGHT 32
#define DIR_RIGHT 33
int stepDelay = 800; // microseconds (ยิ่งน้อยยิ่งเร็ว)
enum MoveState { STOP, FORWARD, BACKWARD, LEFT, RIGHT };
MoveState moveState = STOP;
unsigned long lastStepTime = 0;
// ================== WiFi ==================
char ssid[] = "Wokwi-GUEST";
char pass[] = "";
// ================== LCD & DHT ==================
LiquidCrystal_I2C lcd(0x27, 16, 2);
const int DHT_PIN = 13;
DHTesp dhtSensor;
// ================== Ultrasonic ==================
const int trigPin = 5;
const int echoPin = 18;
// ================== LCD Screen Switch ==================
unsigned long lastSwitchTime = 0;
bool showTemp = true;
// ----------------------------------------------------------------
void setup() {
Serial.begin(115200);
Blynk.begin(BLYNK_AUTH_TOKEN, ssid, pass);
pinMode(pinLED1, OUTPUT);
pinMode(pinLED2, OUTPUT);
lcd.init();
lcd.backlight();
lcd.setCursor(0,0);
lcd.print("Natchanon");
lcd.setCursor(0,1);
lcd.print("Ini essay no 4");
delay(2000);
dhtSensor.setup(DHT_PIN, DHTesp::DHT22);
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
// Stepper pins
pinMode(STEP_LEFT, OUTPUT);
pinMode(DIR_LEFT, OUTPUT);
pinMode(STEP_RIGHT, OUTPUT);
pinMode(DIR_RIGHT, OUTPUT);
Serial.println("System Ready");
}
// ----------------------------------------------------------------
float readDistanceCM() {
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
long duration = pulseIn(echoPin, HIGH);
float distance = duration * 0.034 / 2;
return distance;
}
// ----------------------------------------------------------------
void loop() {
Blynk.run();
// อ่านค่าจาก DHT
TempAndHumidity data = dhtSensor.getTempAndHumidity();
// อ่านค่าจาก Ultrasonic
float distance = readDistanceCM();
// ส่งค่าขึ้น Blynk
Blynk.virtualWrite(V2, data.temperature); // อุณหภูมิ
Blynk.virtualWrite(V3, data.humidity); // ความชื้น
Blynk.virtualWrite(V6, distance); // ระยะทาง
// สลับหน้าจอทุก 3 วินาที
if (millis() - lastSwitchTime >= 3000) {
showTemp = !showTemp;
lastSwitchTime = millis();
}
lcd.clear();
if (showTemp) {
lcd.setCursor(0,0);
lcd.print("Tem:" + String(data.temperature, 0) + "C ");
lcd.print("Hum:" + String(data.humidity, 0) + "%");
lcd.setCursor(0,1);
lcd.print("By: Suwan Buscom");
} else {
lcd.setCursor(0,0);
lcd.print("Distance:");
lcd.setCursor(0,1);
lcd.print(String(distance, 1) + " cm");
}
// -------- Stepper Motor Control --------
unsigned long now = micros();
if (now - lastStepTime >= stepDelay) {
lastStepTime = now;
switch (moveState) {
case FORWARD:
digitalWrite(DIR_LEFT, HIGH);
digitalWrite(DIR_RIGHT, HIGH);
stepPulse();
break;
case BACKWARD:
digitalWrite(DIR_LEFT, LOW);
digitalWrite(DIR_RIGHT, LOW);
stepPulse();
break;
case LEFT:
digitalWrite(DIR_LEFT, LOW);
digitalWrite(DIR_RIGHT, HIGH);
stepPulse();
break;
case RIGHT:
digitalWrite(DIR_LEFT, HIGH);
digitalWrite(DIR_RIGHT, LOW);
stepPulse();
break;
case STOP:
// ไม่ทำอะไร
break;
}
}
delay(100);
}
// ----------------------------------------------------------------
// ฟังก์ชันสร้าง pulse ให้ทั้งสองมอเตอร์
void stepPulse() {
digitalWrite(STEP_LEFT, HIGH);
digitalWrite(STEP_RIGHT, HIGH);
delayMicroseconds(5); // pulse width
digitalWrite(STEP_LEFT, LOW);
digitalWrite(STEP_RIGHT, LOW);
}
// ----------------------------------------------------------------
// LED Control
BLYNK_WRITE(V0) {
int ledState = param.asInt();
digitalWrite(pinLED1, ledState ? HIGH : LOW);
}
BLYNK_WRITE(V1) {
int ledState = param.asInt();
digitalWrite(pinLED2, ledState ? HIGH : LOW);
}
// ----------------------------------------------------------------
// Stepper Control via Blynk
// เดินหน้า
BLYNK_WRITE(V8) {
int state = param.asInt();
moveState = state ? FORWARD : STOP;
}
// ถอยหลัง
BLYNK_WRITE(V9) {
int state = param.asInt();
moveState = state ? BACKWARD : STOP;
}
// เลี้ยวซ้าย
BLYNK_WRITE(V10) {
int state = param.asInt();
moveState = state ? LEFT : STOP;
}
// เลี้ยวขวา
BLYNK_WRITE(V11) {
int state = param.asInt();
moveState = state ? RIGHT : STOP;
}