อยากให้ เซนเซอร์วัดความชื้นดิน ทำงานอัตโนมัติครับ โดยใช้ Blynk ร่วมกับ NodeMCU V3

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

#define BLYNK_PRINT Serial
#define DHTPIN D2
#define DHTTYPE DHT11

#include <SPI.h>
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <SimpleTimer.h>
#include <DHT.h>

int sensorPin = A0;
int sensorValue = 0;
int Relay = D3;
String data = "";
SimpleTimer timer;

DHT dht(DHTPIN, DHTTYPE);
WidgetLCD lcd(V6);

char auth[] = "codeFromYourEmail";
char ssid[] = "SSID";
char pass[] = "Passwords";

BLYNK_CONNECTED() {
  Blynk.syncAll();
  }

BLYNK_WRITE(V4) {
  if (param.asInt() == 1) {
    digitalWrite(Relay,HIGH);
    lcd.clear();
    lcd.print(0,0,"PUMP: ON");
    lcd.print(0,1,"STATS: Manual On");
    delay(500);
  }
  if (param.asInt() == 0) {
    digitalWrite(Relay,LOW);
    lcd.clear();
    lcd.print(0,0,"PUMP: OFF");
    lcd.print(0,1,"STATS: ManualOff");
    delay(500);
  }
}

void sendTemp() {
  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, t);
  Blynk.virtualWrite(V2, h);
}

void sendSoilValue() {
  sensorValue = analogRead(sensorPin);
  sensorValue = map(sensorValue, 0, 1023, 0, 100);
  data = data + sensorValue;
  Blynk.virtualWrite(V5, sensorValue);
}
void setup() {
  pinMode(Relay,OUTPUT);
  pinMode(sensorPin,OUTPUT);
  pinMode(DHTPIN,OUTPUT);
  Serial.begin(9600);
  Blynk.begin(auth, ssid, pass);
  dht.begin();
  lcd.clear();
  lcd.print(4,0,"SMART");
  lcd.print(0,1,"Watering System");
  delay(2000);
  lcd.clear();
  lcd.print(0,0,"Please Wait");
  delay(1000);
  lcd.print(0,0,"Please Wait.");
  delay(1000);
  lcd.print(0,0,"Please Wait..");
  delay(1000);
  lcd.print(0,0,"Please Wait...");
  delay(1000);
  lcd.print(0,0,"Please Wait....");
  delay(1000);
  lcd.clear();
  timer.setInterval(1000L, sendTemp);
  timer.setInterval(1000L, sendSoilValue);
}

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

BLYNK_WRITE(V3) {
  if (param.asInt() == 1) {
    if (analogRead(sensorPin)>300 && analogRead(sensorPin) <1000) {
      digitalWrite(Relay,HIGH);
      lcd.clear();
      lcd.print(0,0,"PUMP: ON");
      lcd.print(0,1,"STATS: Dry Soil");
      delay(500);
    }
    else if (analogRead(sensorPin)<300) {
      digitalWrite(Relay,LOW);
      lcd.clear();
      lcd.print(0,0,"PUMP: OFF");
      lcd.print(0,1,"STATS: Water");
      delay(500);
    }
    else if (analogRead(sensorPin)>1000) {
      digitalWrite(Relay,LOW);
      lcd.clear();
      lcd.print(0,0,"PUMP: OFF");
      lcd.print(0,1,"STATS: Air");
      delay(500);
    }
  }
  if (param.asInt() == 0) {
      digitalWrite(Relay,LOW);
      lcd.clear();
      lcd.print(0,0,"PUMP: OFF");
      lcd.print(0,1,"STATS: AutoOff");
      delay(500);
  }
}

ขอดูหน้าแอพหน่อยครับ

ประมาณนี้เลยครับผม
คือตัววัดอุณหภูมิจะใช้วัดไว้เฉยๆเลยครับ หลักๆมีแค่ตัว Soil Moisture Sensor กับ รีเลย์เท่านั้นครับ

วางเงื่อนไขของการใช้ auto ไว้ยังไงครับ อธิบายหน่อย

คือประมาณว่าเหมือนทำสวิตช์ไว้ใช้อย่างใดอย่างนึงครับ
เวลาเราไม่ว่าง เราเปิด auto ครับ แต่ถ้าเราเห็นว่าสภาพอากาศมันไม่เหมาะสมก็สามารถเปิด manual ด้วยตัวเองครับ รีเลย์ผมใส่ output เป็น pump ไว้ครับ

BLYNK_WRITE(V3) {       // ใช้สวิตช์ V3 เป็นสวิตช์ auto 
  if (param.asInt() == 1) {       //ถ้า V3 สั่งเปิด
    if (analogRead(sensorPin)>300 && analogRead(sensorPin) <1000) {    //ถ้าเซนเซอร์จับค่าได้มากกว่า 300 และน้อยกว่า 1000
      digitalWrite(Relay,HIGH);  // ให้ปั๊มทำงาน
      lcd.clear();
      lcd.print(0,0,"PUMP: ON"); // ให้ LCD ใน Blynk โชว์สถานะเป็นข้อความ
      lcd.print(0,1,"STATS: Dry Soil"); // ให้ LCD ใน Blynk โชว์สถานะดินแห้ง
      delay(500);
    }
    else if (analogRead(sensorPin)<300) { //ถ้าเซนเซอร์จับค่าได้น้อยกว่า 300
      digitalWrite(Relay,LOW);  // ให้ปั๊มหยุดทำงาน
      lcd.clear();
      lcd.print(0,0,"PUMP: OFF"); // ให้ LCD ใน Blynk โชว์สถานะเป็นข้อความ
      lcd.print(0,1,"STATS: Water"); // ให้ LCD ใน Blynk โชว์สถานะเซนเซอร์อยู่ในน้ำ
      delay(500);
    }
    else if (analogRead(sensorPin)>1000) {
      digitalWrite(Relay,LOW);  // ให้ปั้มหยุดทำงาน
      lcd.clear();
      lcd.print(0,0,"PUMP: OFF"); // ให้ LCD ใน Blynk โชว์สถานะเป็นข้อความ
      lcd.print(0,1,"STATS: Air"); // ให้ LCD ใน Blynk โชว์สถานะเซนเซอร์อยู่ในอากาศ
      delay(500);
    }
  }
  if (param.asInt() == 0) {  //ถ้า V3 สั่งปิด
      digitalWrite(Relay,LOW);  // ให้ปั๊มหยุดทำงาน
      lcd.clear();
      lcd.print(0,0,"PUMP: OFF");  // ให้ LCD ใน Blynk โชว์สถานะเป็นข้อความ
      lcd.print(0,1,"STATS: AutoOff");  // ให้ LCD ใน Blynk โชว์สถานะระบบอัตโนมัติปิดการใช้งาน
      delay(500);
  }
}

น่าจะประมาณนี้ครับ ที่แน่ๆผมรู้อยู่แล้วว่าโค๊ดไม่ถูกครับ 5555 :sweat_smile:

1 Likes

คือยังไงนะครับ auto มันทำงานแต่ต้องกด on/off หนึ่งครั้งหรอ

ถ้าดูจาก loop นี้ถ้ากด V3 on auto มันก็ควรจะทำงานนะ

1 Likes

สวิตช์ auto มันเปิดได้ครับ แต่ค่าสถานะใน lcd ยังคงที่ครับ
เหมือนผมเปิดสวิตช์ครั้งนึง มันขึ้นสถานะตามที่วัดได้ แต่เวลาย้ายเซนเซอร์ไปโดนที่อื่น จอมันไม่อัพเดทสถานะและไม่ทำงานตามโค้ดครับ
ผมเอาไปจุ่มน้ำแล้วเปิดสวิตช์ มันก็ขึ้นปกติครับ ขึ้นสถานะว่า Pump off กับ Water
แต่เวลาผมย้ายเซนเซอร์ไปดินแห้ง สวิตช์มันคงเปิดอยู่ แต่สถานะบนจอมันจะไม่คล้องกันกับตัวเซนเซอร์อะครับ ยังคงขึ้นว่า Water เหมือนเดิม เซนเซอร์มันไม่ทำงานด้วย ต้องปิด virtual button แล้วเปิดใหม่อีกรอบ ค่าสถานะจะเป็นปัจจุบันครับ

เช็คตรงนี้ดีๆ ครับ มันต้องเป็น input นะไม่ใช่ output

1 Likes

ถ้าจะเปิด A ก็ต้องกดปิด M ด้วยใช่ป่ะครับ

คิดไว้ว่าอย่างนั่นครับ แต่ในอีกมุมมอง
ผมอยากได้แบบว่าเปิดสวิตช์ A แล้วสวิตช์ M ดับเอง
เปิดสวิตช์ M แล้วสวิตช์ A ดับเอง ครับ พอจะแนะนำได้บ้างไหมครับ

ส่วนนี้แก้ไขใช้งานได้แล้วครับ แต่ on V3 ไว้มันไม่ทำงานอัตโนมัติครับ

ตอนมันไม่ทำงาน M on หรือ off ครับ

จะเปิด auto ปกติจะกดอะไรก่อน ขอสเตปการกดหน่อย

ตอนไม่ทำงาน m ปิดอยู่ครับ
เปิด auto แค่จ่ายไฟเข้าวงจรก็สามารถสั่งเปิดปิดได้เลยครับ

ขอ qr clone มาหน่อยครับ เดียวคงต้องซิมเทสดูก่อน

เอาตรงนี้มาครับ นั้นมันสำหรับแชร์

84183484_507794470140605_8651371036857597952_n
QR Code แบบ Clone สำหรับโครงงานนี้ครับ

#define BLYNK_PRINT Serial
#define DHTPIN D2
#define DHTTYPE DHT11

#include <SPI.h>
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <SimpleTimer.h>
#include <DHT.h>

int sensorPin = A0;
int sensorValue = 0;
int Relay = D3;
SimpleTimer timer;

DHT dht(DHTPIN, DHTTYPE);
WidgetLCD lcd(V6);

char auth[] = "auth";
char ssid[] = "ssid";
char pass[] = "passwords";

BLYNK_CONNECTED() {
  Blynk.syncAll();
  }

BLYNK_WRITE(V4) {
  if (param.asInt() == 1) {
    digitalWrite(Relay,HIGH);
    lcd.clear();
    lcd.print(0,0,"PUMP: ON");
    lcd.print(0,1,"STATS: Manual On");
    delay(500);
    Blynk.virtualWrite(V3,LOW);
  }
  if (param.asInt() == 0) {
    digitalWrite(Relay,LOW);
    lcd.clear();
    lcd.print(0,0,"PUMP: OFF");
    lcd.print(0,1,"STATS: ManualOff");
    delay(500);
  }
}

void sendTemp() {
  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, t);
  Blynk.virtualWrite(V2, h);
}

void sendSoilValue() {
  sensorValue = analogRead(sensorPin);
  sensorValue = map(sensorValue, 0, 1023, 0, 100);
  Blynk.virtualWrite(V5, sensorValue);
}
void setup() {
  pinMode(Relay,OUTPUT);
  pinMode(sensorPin,INPUT);
  pinMode(DHTPIN,INPUT);
  Serial.begin(9600);
  Blynk.begin(auth, ssid, pass);
  dht.begin();
  lcd.clear();
  lcd.print(4,0,"SMART");
  lcd.print(0,1,"Watering System");
  delay(2000);
  lcd.clear();
  lcd.print(0,0,"Please Wait");
  delay(1000);
  lcd.print(0,0,"Please Wait.");
  delay(1000);
  lcd.print(0,0,"Please Wait..");
  delay(1000);
  lcd.print(0,0,"Please Wait...");
  delay(1000);
  lcd.print(0,0,"Please Wait....");
  delay(1000);
  lcd.clear();
  timer.setInterval(1000L, sendTemp);
  timer.setInterval(1000L, sendSoilValue);
}

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

BLYNK_WRITE(V3) {
  sensorValue = analogRead(sensorPin);
  sensorValue = map(sensorValue, 0, 1023, 0, 100);
  if (param.asInt() == 1) {
    if (sensorValue >30 && sensorValue <85) {
      digitalWrite(Relay,HIGH);
      lcd.clear();
      lcd.print(0,0,"PUMP: ON");
      lcd.print(0,1,"STATS: Dry Soil");
      delay(500);
    }
    else if (sensorValue <30) {
      digitalWrite(Relay,LOW);
      lcd.clear();
      lcd.print(0,0,"PUMP: OFF");
      lcd.print(0,1,"STATS: Water");
      delay(500);
    }
    else if (sensorValue >85) {
      digitalWrite(Relay,LOW);
      lcd.clear();
      lcd.print(0,0,"PUMP: OFF");
      lcd.print(0,1,"STATS: Air");
      delay(500);
    }
    Blynk.virtualWrite(V4,LOW);
  }
  if (param.asInt() == 0) {
      digitalWrite(Relay,LOW);
      lcd.clear();
      lcd.print(0,0,"PUMP: OFF");
      lcd.print(0,1,"STATS: AutoOff");
      delay(500);
  }
}

ตอนนี้เหมือนเดิมครับ ยังใช้งานแบบ Auto ไม่ได้ครับ
ผมลองเอาส่วนใน v3 ไปลองใส่ใน void loop แล้ว แต่เวลาอัพลงจะไม่สามารถใช้สวิตช์ Manual ได้ครับ
ผมไม่ทราบว่าจะทำให้ BLYNK_WRITE V3 เป็น loop ได้ต้องทำยังไงครับ

จากโค้ตตอนนี้ติดอะไรครับ

ตอนนี้ติดระบบ Auto อยู่ครับ
ผมไปค้นข้อมูลมาเพิ่มเติมว่า
ต้องใส่ millis ด้วยรึเปล่าอันนี้ผมไม่ทราบเหมือนกันครับ เพราะไม่เคยใช้
มันจะติด delay แล้วมันจะไม่ทำงานอะครับ