ขอคำแนะนำ Blynk หน่อยครับ ยังสับสนเรื่องโค้ดอยู่

พอดีมี Mini Project ขึ้นมาอ่ะครับ แล้วหาโค้ดดูคร่าวๆพอเอามารวมกันก็ error ตลอด พอจะแนะนำได้ไหมครับ ต้องวัด temp humid แล้วให้ควบคุมปั๊มเมื่อความชื้นน้อย ควบคุมไฟเมื่ออุณหภูมิน้อย ประมาณนี้ครับ

อันนี้โค้ดที่ดูมาครับ

#include <ESP8266WiFi.h> 

#include "DHT.h"   // library for DHT sensor                          

/* Comment this out to disable prints and save space */
#define BLYNK_PRINT Serial

/* Fill-in your Template ID (only if using Blynk.Cloud) */
#define BLYNK_TEMPLATE_ID "xxxxxx"
#define BLYNK_TEMPLATE_NAME "xxxxx"
#define BLYNK_AUTH_TOKEN "xxxxxxxxxx"


#include <BlynkSimpleEsp8266.h>

WidgetLED LED_Blynk(V3);

// ----- WiFi configuration --------------
const char* ssid     =  "xxxx";          
const char* password = "xxxxx";      


#define DHTPIN    D4          
#define DHTTYPE   DHT11       // e.g. DHT11, DHT21, DHT22
DHT dht(DHTPIN, DHTTYPE);

#define LED D1
#define SW D2

float humidity = 0;     
float temperature  = 0;     

unsigned long lastDHTRead = 0, newDHTRead=0;
unsigned long lastTimeWriteFeed = 0, newTimeWriteFeed = 0;

char msg[100];
bool lamp_state  = 0;
 

BLYNK_WRITE(V2)
{
  int pin=param.asInt();
  Serial.print("Sw = ");
  Serial.println(pin);

  if (pin == 0){ 
     digitalWrite(LED, LOW); 
     LED_Blynk.on();
  } 
  else 
  {
     digitalWrite(LED, HIGH); 
     LED_Blynk.off();
  }
}


void setup() {
    pinMode(LED, OUTPUT);
    digitalWrite(LED, HIGH);
    
    Serial.begin(115200);
    dht.begin(); // initialize DHT module


    Blynk.begin(BLYNK_AUTH_TOKEN, ssid, password);

    //BlynkEdgent.begin();

      
}

void loop() {
 
        
        newDHTRead = millis();
        if(newDHTRead - lastDHTRead > 2000)  
        {
          humidity = dht.readHumidity();     // read humidity
          temperature  = dht.readTemperature();  // read temperature
          lastDHTRead = newDHTRead;

          // check if data is valid 
          if (isnan(humidity) || isnan(temperature)) 
          {
            humidity=0;
            temperature=0;
            Serial.println("Failed to read from DHT sensor!");
          }
          else
          {

            String data = "{\"data\": {\"humidity\":" + String(humidity) + 
            ", \"temperature\":" + String(temperature) + 
            "}";
            Serial.println(data);


            Blynk.run();
            //BlynkEdgent.run();
            Blynk.virtualWrite(V0, temperature); //แสดงอุณหภูมิบนแอพ Blynk
            Blynk.virtualWrite(V1, humidity); //แสดงความชื้นบนแอพ Blynk
            

          }
    
        }


        if( digitalRead(SW) == LOW)
        {
          delay(100);
          if(lamp_state == 0)
          {
            Serial.println("send (on)");
          }
          else
          {
            Serial.println("send (off)");
          }
          lamp_state = !lamp_state; 
        }

        
    delay(100);
}

อันนี้เป็นโค้ด ปั๊มครับ

#define BLYNK_PRINT Serial    
#include <BlynkSimpleEsp8266.h>
#include <ESP8266WiFi.h> // ดาวน์โหลด ไลบรารี่ที่ https://github.com/blynkkk/blynk-library
#include <SimpleTimer.h> // ดาวน์โหลด ไลบรารี่ ที่ https://github.com/jfturcot/SimpleTimer
#include <DHT.h>
#include <DHT_U.h>

char auth[] = "xxxxxx"; // ใช้ Token ที่คัดลอกจากแอพเรามาวางแทน
char pass[] = "xxxxxx"; // กรอกรหัส WIFI แทนนะครับ
char ssid[] = "xxxxx"; //กรอกชื่อ WIFI ที่ต้องการให้ ESP8266 เชื่อมต่อ

#define BLYNK_TEMPLATE_ID "TMPL6BcozApHy"
#define BLYNK_TEMPLATE_NAME "Pump"
#define BLYNK_AUTH_TOKEN "xxxxxx"

#define DHTPIN 3 //ประกาศตัวแปร DHTPIN ใช้พอร์ต 10
#define DHTTYPE DHT11
#define pump 0 //ประกาศตัวแปร pump ใช้พอร์ต 0

DHT dht(DHTPIN, DHTTYPE);
SimpleTimer timer;

void sendSensor()
{
  float h = dht.readHumidity();
  float t = dht.readTemperature();

  if (isnan(h) || isnan(t)) {
    Serial.println("Failed to read from DHT sensor!");
    return;
  }
  Blynk.virtualWrite(V1, h); // เรียกให้  V5 แสดงค่าจากตัวแปร h บน Blynk
  Blynk.virtualWrite(V0, t); // เรียกให้  V6 แสดงค่าจากตัวแปร t บน Blynk
}

void setup()
{
  Serial.begin(9600);
  Blynk.begin(auth, ssid, pass); 
  dht.begin();
  timer.setInterval(1000L, sendSensor);
  pinMode(pump, OUTPUT);
}

void loop()
{
  Blynk.run();
  timer.run();
}

ตอนนี้ได้ประมาณนี้ครับ แต่ led ไม่ติด

#include <ESP8266WiFi.h> 
#include "DHT.h"   // library for DHT sensor                          

/* Comment this out to disable prints and save space */
#define BLYNK_PRINT Serial

/* Fill-in your Template ID (only if using Blynk.Cloud) */
#define BLYNK_TEMPLATE_ID "TMPL6C2cgP-Ua"
#define BLYNK_TEMPLATE_NAME "Smart farm"
#define BLYNK_AUTH_TOKEN "H6ujfxIoGVEBbck0kXli3oHxNw405HfJ"

#include <BlynkSimpleEsp8266.h>

// ----- WiFi configuration --------------
const char* ssid     =  "RUPDA";          
const char* password = "kimhun1234";      

#define DHTPIN    D3          
#define DHTTYPE   DHT11       // e.g. DHT11, DHT21, DHT22
DHT dht(DHTPIN, DHTTYPE);

#define relay1 D4
#define LEDLight D0
WidgetLED LED_Light(V5);

BlynkTimer timer;

float humidity = 0;     
float temperature  = 0;     

unsigned long lastDHTRead = 0, newDHTRead=0;
unsigned long lastTimeWriteFeed = 0, newTimeWriteFeed = 0;

int ValueOfSlider1;
BLYNK_WRITE(V2){          // V1 ถูกกำหนดให้เป็น Slider
  ValueOfSlider1 = param.asInt();
}
int ValueOfSlider2;
BLYNK_WRITE(V3){          // V1 ถูกกำหนดให้เป็น Slider
  ValueOfSlider2 = param.asInt();
}

   BLYNK_WRITE(V4){ 
if (param.asInt() == 1) {
digitalWrite(relay1, !digitalRead(relay1));
digitalWrite(LEDLight, HIGH);
if (digitalRead(relay1) == LOW) {

}
else {

}
}
if (param.asInt() == 0) {
digitalWrite(relay1, !digitalRead(relay1));
digitalWrite(LEDLight, LOW);
if (digitalRead(relay1) == HIGH) {

}
else {

}
}
}

void setup() {
    pinMode(relay1, OUTPUT);
    pinMode(LEDLight,OUTPUT);
    digitalWrite(relay1, LOW);
    digitalWrite(LEDLight, LOW); 
    
    Serial.begin(115200);
    dht.begin(); // initialize DHT module


    Blynk.begin(BLYNK_AUTH_TOKEN, ssid, password);

    //BlynkEdgent.begin();

      
}

void loop() {
 
        newDHTRead = millis();
        if(newDHTRead - lastDHTRead > 2000)  
        {
          humidity = dht.readHumidity();     // read humidity
          temperature  = dht.readTemperature();  // read temperature
          lastDHTRead = newDHTRead;

          // check if data is valid 
          if (isnan(humidity) || isnan(temperature)) 
          {
            humidity=0;
            temperature=0;
            Serial.println("Failed to read from DHT sensor!");
          }
          else
          {

            String data = "{\"data\": {\"humidity\":" + String(humidity) + 
            ", \"temperature\":" + String(temperature) + 
            "}";
            Serial.println(data);


            Blynk.run();
            //BlynkEdgent.run();
            Blynk.virtualWrite(V0, temperature); //แสดงอุณหภูมิบนแอพ Blynk
            Blynk.virtualWrite(V1, humidity); //แสดงความชื้นบนแอพ Blynk
            Blynk.virtualWrite(V2, ValueOfSlider1);
            Blynk.virtualWrite(V3, ValueOfSlider2);

            timer.run();
          }
    
        }

    delay(100);
}

สวัสดีครับ ผมวิเคราะห์โค้ดของคุณแล้ว พบปัญหาหลายจุดที่ทำให้ LED ไม่ติดและโค้ดทำงานไม่ถูกต้อง มาแก้ไขกันครับ

ปัญหาหลักที่พบ:

1. ตำแหน่ง Blynk.run() ผิด

  • ปัญหาใหญ่สุด: คุณวาง Blynk.run() ไว้ใน if(newDHTRead - lastDHTRead > 2000) ทำให้ Blynk ทำงานแค่ทุก 2 วินาที
  • ต้องย้าย Blynk.run() ออกมาไว้นอก if และรันทุกรอบของ loop()

2. ปัญหา WidgetLED และ Virtual Pin

  • คุณประกาศ WidgetLED LED_Light(V5) แต่ไม่มีการใช้ .on() หรือ .off() ใน BLYNK_WRITE(V4)
  • การควบคุม LED บน Blynk app ต้องใช้ LED_Light.on() และ LED_Light.off()

3. ตรรกะการควบคุม relay และ LED ผิด

  • ใน BLYNK_WRITE(V4) คุณใช้ !digitalRead(relay1) toggle ซ้ำทั้ง if และ else ทำให้สับสน
  • ควรเขียนให้ชัดเจน: เมื่อ param = 1 เปิด, param = 0 ปิด

4. ไม่มี Auto Control

  • คุณต้องการควบคุมอัตโนมัติตามค่า temp/humid แต่ยังไม่มีโค้ดส่วนนี้

โค้ดที่แก้ไขแล้วพร้อมใช้:

#define BLYNK_PRINT Serial
#define BLYNK_TEMPLATE_ID "TMPL6C2cgP-Ua"
#define BLYNK_TEMPLATE_NAME "Smart farm"
#define BLYNK_AUTH_TOKEN "H6ujfxIoGVEBbck0kXli3oHxNw405HfJ"

#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include "DHT.h"

// WiFi credentials
const char* ssid = "RUPDA";
const char* password = "kimhun1234";

// DHT Sensor
#define DHTPIN D3
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);

// Hardware pins
#define RELAY_PUMP D4    // รีเลย์ควบคุมปั๊ม
#define LED_LIGHT D0     // LED แสดงสถานะ

// Blynk Virtual Pins
WidgetLED LED_Status(V5);  // LED indicator บนแอพ

// Variables
float humidity = 0;
float temperature = 0;
int humidityThreshold = 50;   // ค่า threshold ความชื้น (จาก slider V2)
int temperatureThreshold = 25; // ค่า threshold อุณหภูมิ (จาก slider V3)
bool autoMode = true;          // โหมดอัตโนมัติ
bool manualPumpState = false;  // สถานะปั๊มแบบ manual

BlynkTimer timer;

// อ่านค่า slider ความชื้น (V2)
BLYNK_WRITE(V2) {
  humidityThreshold = param.asInt();
  Serial.print("Humidity Threshold: ");
  Serial.println(humidityThreshold);
}

// อ่านค่า slider อุณหภูมิ (V3)
BLYNK_WRITE(V3) {
  temperatureThreshold = param.asInt();
  Serial.print("Temperature Threshold: ");
  Serial.println(temperatureThreshold);
}

// ควบคุมปั๊มแบบ manual จาก switch/button V4
BLYNK_WRITE(V4) {
  int buttonState = param.asInt();
  
  if (buttonState == 1) {
    // เปิดปั๊ม
    digitalWrite(RELAY_PUMP, HIGH);
    digitalWrite(LED_LIGHT, HIGH);
    LED_Status.on();
    manualPumpState = true;
    Serial.println("Pump ON (Manual)");
  } else {
    // ปิดปั๊ม
    digitalWrite(RELAY_PUMP, LOW);
    digitalWrite(LED_LIGHT, LOW);
    LED_Status.off();
    manualPumpState = false;
    Serial.println("Pump OFF (Manual)");
  }
}

// ฟังก์ชันอ่านเซ็นเซอร์และควบคุมอัตโนมัติ
void readSensorAndControl() {
  humidity = dht.readHumidity();
  temperature = dht.readTemperature();
  
  // ตรวจสอบว่าอ่านค่าได้
  if (isnan(humidity) || isnan(temperature)) {
    Serial.println("Failed to read from DHT sensor!");
    return;
  }
  
  // แสดงค่าบน Serial Monitor
  Serial.print("Temp: ");
  Serial.print(temperature);
  Serial.print("°C, Humidity: ");
  Serial.print(humidity);
  Serial.println("%");
  
  // ส่งค่าไปแสดงบน Blynk app
  Blynk.virtualWrite(V0, temperature);
  Blynk.virtualWrite(V1, humidity);
  
  // ควบคุมอัตโนมัติ (ถ้าต้องการ)
  // ถ้าความชื้นน้อยกว่า threshold -> เปิดปั๊ม
  // ถ้าอุณหภูมิต่ำกว่า threshold -> เปิดไฟ (หรือฮีตเตอร์)
  
  if (autoMode) {
    if (humidity < humidityThreshold) {
      digitalWrite(RELAY_PUMP, HIGH);
      digitalWrite(LED_LIGHT, HIGH);
      LED_Status.on();
    } else {
      digitalWrite(RELAY_PUMP, LOW);
      digitalWrite(LED_LIGHT, LOW);
      LED_Status.off();
    }
  }
}

void setup() {
  // กำหนด pinMode
  pinMode(RELAY_PUMP, OUTPUT);
  pinMode(LED_LIGHT, OUTPUT);
  
  // เริ่มต้นให้ปิด
  digitalWrite(RELAY_PUMP, LOW);
  digitalWrite(LED_LIGHT, LOW);
  
  // เริ่ม Serial
  Serial.begin(115200);
  Serial.println("Smart Farm Starting...");
  
  // เริ่ม DHT sensor
  dht.begin();
  
  // เชื่อมต่อ Blynk
  Blynk.begin(BLYNK_AUTH_TOKEN, ssid, password);
  
  // ตั้งเวลาอ่านเซ็นเซอร์ทุก 2 วินาที
  timer.setInterval(2000L, readSensorAndControl);
  
  Serial.println("Connected to Blynk!");
}

void loop() {
  Blynk.run();   // *** ต้องรันทุกรอบ - สำคัญมาก! ***
  timer.run();   // รัน BlynkTimer
}

การตั้งค่าบน Blynk App:

Virtual Pins ที่ต้องสร้าง:

  • V0: Gauge หรือ Value Display - แสดงอุณหภูมิ (°C)
  • V1: Gauge หรือ Value Display - แสดงความชื้น (%)
  • V2: Slider - ตั้งค่า threshold ความชื้น (0-100)
  • V3: Slider - ตั้งค่า threshold อุณหภูมิ (0-50)
  • V4: Button (Switch mode) - ควบคุมปั๊มแบบ manual
  • V5: LED - แสดงสถานะปั๊ม (เปิด/ปิด)

การต่อสายไฟ:

ESP8266 NodeMCU:
- D3 (GPIO0) → DHT11 Data pin
- D4 (GPIO2) → Relay Module IN (สำหรับปั๊ม)
- D0 (GPIO16) → LED + 220Ω resistor → GND
- 3.3V → DHT11 VCC
- GND → DHT11 GND และ LED cathode

วิธี Debug:

  1. เปิด Serial Monitor (115200 baud) - ดูว่าต่อ WiFi ได้หรือไม่
  2. ตรวจสอบค่าเซ็นเซอร์ - ดูว่าอ่าน temp/humid ได้หรือไม่
  3. ทดสอบบน Blynk app - กดปุ่ม V4 ดูว่า LED ติด/ดับตามหรือไม่
  4. ตรวจสอบ D0 pin - บาง ESP8266 D0 ใช้งานยาก ให้ลองเปลี่ยนเป็น D1, D2 หรือ D5

เพิ่มเติม - Auto Control Logic:

ถ้าต้องการให้ระบบทำงานอัตโนมัติทั้งหมด เพิ่มโค้ดนี้:

if (humidity < humidityThreshold && temperature < temperatureThreshold) {
  // เปิดทั้งปั๊มและไฟ
  digitalWrite(RELAY_PUMP, HIGH);
  digitalWrite(LED_LIGHT, HIGH);
} else if (humidity < humidityThreshold) {
  // เปิดแค่ปั๊ม
  digitalWrite(RELAY_PUMP, HIGH);
  digitalWrite(LED_LIGHT, LOW);
} else if (temperature < temperatureThreshold) {
  // เปิดแค่ไฟ
  digitalWrite(RELAY_PUMP, LOW);
  digitalWrite(LED_LIGHT, HIGH);
} else {
  // ปิดทั้งหมด
  digitalWrite(RELAY_PUMP, LOW);
  digitalWrite(LED_LIGHT, LOW);
}

ลองโค้ดนี้ดูครับ ถ้ายังมีปัญหาบอกได้เลยครับ :+1: