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

#define BLYNK_PRINT Serial
#include <ESP8266WiFi.h> //เรียกใช้ไลเบอรี่
#include <BlynkSimpleEsp8266.h>
#include <DHT.h>
#include <SimpleTimer.h>
#define DHTPIN D4   // กำหนดช่องพินของเซนเชอร์
#define DHTTYPE DHT11   // DHT 11  ชื่อ ของเซ็นเชอร์ที่ใช้
#define BLYNK_PRINT DebugSerial
int sensorPin = A0;
  
char auth[] = "11111111111111111111111";  // token blynk
char ssid[] = "KKKKK";  // ชื่อ Wifi  
char pass[] = "12345678";   // พาสเวิด

BlynkTimer timer;
DHT dht(DHTPIN, DHTTYPE);
void myTimerEvent()
{
  float h = dht.readHumidity();
  float t = dht.readTemperature();

  if (isnan(h) || isnan(t)) 
  {
    Serial.println("Failed to read from DHT sensor!");
    return;
  }
  else
  {
    Serial.print("Humidity: ");
    Serial.print(h);
    Serial.print(" %\t");
    Serial.print("Temperature: ");
    Serial.println(t);
    Blynk.virtualWrite(V1, h); 
    Blynk.virtualWrite(V2, t);
    
 
  }
}
void setup()
{
  pinMode(4, OUTPUT);  //ตั้งค่าขา 4 เป็น output
  pinMode(5, OUTPUT);  //ตั้งค่าขา 5 เป็น output
  Serial.begin(115200); // เริ่มตั้นการสื่อสารที่ 115200
  dht.begin();
  Blynk.begin(auth, ssid, pass);
  timer.setInterval(2000L, myTimerEvent);
 
  
}

int sensorValue;
void loop()
{
  sensorValue = analogRead(sensorPin);
  sensorValue = map(sensorValue, 0, 1023, 0, 100);
  Serial.print("Soil moisture: ");
  Serial.print(sensorValue);
  Serial.println(" %");
  Blynk.run();
  timer.run(); // Initiates BlynkTimer
  delay(500); //wait for half a second, so it is easier to read
     
      if(sensorValue <80)
      {
   digitalWrite(5,HIGH);
   Blynk.virtualWrite(V3,1);
  }else{
    digitalWrite(5,LOW);
    Blynk.virtualWrite(V3,0);
  }
 
}

BLYNK_WRITE(V3)
{
  if(param.asInt()==1){

    digitalWrite(5,LOW);

  }else{

digitalWrite(5,HIGH);

  }
}

ขออนุญาต สอบถามอีกหน่อยคะ
ตอนนี้ มันทำงาน auto แล้ว แต่เมื่อกดสั่งปิด แล้ว มันยังทำงาน อยู่ใน loop

if(sensorValue <80)
      {
   digitalWrite(5,HIGH);
   Blynk.virtualWrite(V3,1);
  }else{
    digitalWrite(5,LOW);
    Blynk.virtualWrite(V3,0);
  }
*****************

มันต้องแก้ยังไงคะ ให้สามารถสั่งการได้ คือสั่งให้ปิด เปิด ได้ด้ด้วยอะคะ

อธิบายการทำงานตรงนี้ให้ผมหน่อยครับว่าเข้าใจว่าอย่างไร ผิดถูกไม่ว่ากันครับ จะได้ปรับให้ถูกและเข้าใจตรงกันก่อน

ขอโทษครับ ผมลืมอัพรูปโถ่ววว

คือตอนนี้ ระบบมันรับค่าความชื้น เปิด-ปิด แบบ auto ได้แล้วค่ะ ที่กำหนดให้รับค่า < 80 นั้นแหละ
แต่อยากจะทำให้ปุ่มใน blynk สามารถสั่งให้มันเปิด-ปิด ได้จากตัวผู้ใช้เองด้วยค่ะ

อธิบายการทำงานตรงนี้ก่อนครับ งั้นไปต่อไม่ได้ครับ

      if(sensorValue <80) //ถ้าค่าความชื่นในดิน มากกว่า 80
      {
   digitalWrite(5,HIGH); // ให้ pinMode 5 ทำการเปิด
   Blynk.virtualWrite(V3,1); // ให้ BLYNK เขียนให้ V3 เปิด
  }else{    
    digitalWrite(5,LOW); // ถ้าค่าน้อยกว่า 80 ให้ pinMode 5 ทำการปิด
    Blynk.virtualWrite(V3,0); // ให้ BLYNK เขียนให้ V3 ปิด
  }

โจทย์นี้ต้องการให้ ค่า ความชื้นในดิน

  1. มากกว่า Relay On
    หรือ
  2. น้อยกว่า Relay On หรอครับ

มากกว่า ให้ Relay On ค่ะ

ถ้าอย่างนั้นเครื่องหมายของตัวดำเนินการตรงนี้ก็ผิดครับ มันสลับกันอยู่ ที่เราใช้อยู่คือ ถ้าค่าความชื้นในดิน น้อยกว่า(<) 80 ให้ Relay On ครับ

ด้วยคำสั่งนี้ digitalWrite(5,HIGH);

ถ้าบอร์ดต่อ แบบ active high รีเลย์จะ On
แต่ถ้าต่อแบบ active low รีเลย์มันจะ Off

จุดนี้ได้แล้วค่ะ แต่ถ้าเวลา Relay On แบบ auto แล้วเราอยากจะสั่งปิดด้วยตัวเอง
แต่เมื่อกดปิดแล้ว มันก็กลับมาออนเหมือนเดิม

ถ้าการทำงานเป็นจริงอย่างที่น้องว่ามา ดังนั้น
ปัญหาคือชุดนี้มันทำงานตลอดครับ

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

ตัวอย่างการแก้ไข

ไม่ทราบว่าทำได้หรือยังครับ ผมติดตรงนี้เหมือนกัน

ผมลองทำตามคำแนะนำแล้ว คุณ @Remy_Martin ยังไม่ได้ครับ ยัง งงๆ กลับ Code อยู่ :sweat_smile::sweat_smile::sweat_smile::sweat_smile:

ตอนนี้ผลลัพธ์การทำงานเป็นอย่างไรครับ

ตามนี้เลยครับ

ขอดูโค้ตที่ใช้อยู่หน่อยครับ

ขอโทษที่ตอบช้านะครับ


#include <ESP8266WiFi.h>
#include <Blynk.h>
#include <DHT.h>
#include <BlynkSimpleEsp8266.h>
#define BLYNK_PRINT 

char auth[] = ""; //Blynk auth token
char ssid[] = ""; //WiFi SSID
char pass[] = "";  //WiFi password

BlynkTimer timer;

//SOIL SENSOR
  const int Relay1 = 14; //pin D3
  const int SoilPin = A0; //พินที่ใช้รับค่า
  int sensorValue = 0; // ตัวแปรค่า Analog
  int outputValue = 0; // ตัวแปรสำหรับ Map เพื่อคิด %
  int soil;

//ควบคุม PUMP จาก BLYNK //ตรงนี้ยังไม่ถูกนะครับ ยังมั่วอยู่5555
BLYNK_WRITE(V1){
  if(param.asInt()== 0){
    digitalWrite(Relay1, HIGH);
  }else{
    digitalWrite(Relay1, LOW);
  }
}

void sendSensor(){ 
//SOIL
  Blynk.virtualWrite(V2, soil);
}

void setup() {
  Serial.begin(115200);
  Blynk.begin(auth, ssid, pass);
//SOIL
  pinMode(SoilPin, INPUT);
  pinMode(Relay1, OUTPUT);
timer.setInterval(2000L, sendSensor);
}

void loop() {

Blynk.run();
  timer.run();

//soil
   sensorValue = analogRead(SoilPin);
   outputValue = map(sensorValue, 0, 1023, 0, 100);
   Serial.print("Soil moisture: ");
   Serial.print(outputValue);
   Serial.println(" %");
   delay(2000);
   soil = outputValue;
//SOIL AUTO     
   if(soil > 60) { 
      digitalWrite(Relay1, LOW);
      Blynk.virtualWrite(V1,0);
   }
   else{
      digitalWrite(Relay1, HIGH);
      Blynk.virtualWrite(V1,1);
   }
}

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

image

ตรงนี้มันเข้าเงื่อนไขตลอดครับ ถึงจะกดปิด มันก็จะเปิด อะครับ
มันต้องเพิ่มเงื่อนไข เข้าไป ใช่มั้ยครับ

//SOIL AUTO     
   if(soil > 60) { 
      digitalWrite(Relay1, LOW);
      Blynk.virtualWrite(V1,0);
   }
   else{
      digitalWrite(Relay1, HIGH);
      Blynk.virtualWrite(V1,1);
   }
}

ถูกต้องครับเพราะว่ามันวิ่งผ่าน

digitalWrite(Relay1, HIGH);
Blynk.virtualWrite(V1,1);

ตลอดต่อให้ไปกดปิดที่ปุ่มก็ตาม ทีนี้ลองคิดเงื่อนในง่ายๆ อย่าง

if() {
/////
}

อะไรให้มันทำงานคำสั่งนี้แค่ครั้งเดียวอ่ะครับ