Nodemcu-เลี้ยงไก่-ปลูกผักกินเอง(ตอน4)

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

image

18กย65
ผมได้มาปรับปรุง โปรเจค แรกที่สุดคือ เรื่อง รดน้ำต้นทุเรียน ตั้งแต่มค65 เรื่มในเว๊บอื่น และผมจะมาต่อในเว็บeleceasy ต่อ
พอทำโปรเจคเลี้ยงไก่ ทำให้โปรเจคนี้หยุดการดูแลไป


ต้นทุเรียน ตอนแรก2 ต้น พอไม่ได้ดูแล เหลือต้นเดียว 555
xxxxx
โปรเจตนี้ มี nodemcu8266 1 อัน ควบคุม วาล์วเปิดน้ำ 1 อัน โดยมี เซ็นเซอร์วัดความชื้นในดิน 1 ตัว เพื่อเช็คดินที่ต้นทุเรียน

xxxx
เริ่มแรก ใช้เซ็นเซอร์นี้

xxxxx
ใช้ไม่ถึง30 วัน
เซ็นเซอร์กร่อน


xxx
เลยใช้ลวดสแตนเลสแทนส่วนที่ผุกร่อน

xxx
ใช้ไป 2 เดือน ลวดสแตนเลสผุกร่อน จนขาด อีก

xxx
เปลี่ยน​อิเลกโทรด จากลวดสแตนเลส​เป็นเหล็กกล่องกัลวาไนซ์​ขนาด​4หุน​ยาว40ซม. 2เส้นตอกลงดิน ให้ห่างกัน3ซม.
ปลายบนสูงจากพื้นดิน5ซม.
จากนั้น เอาสายไฟของเดิม มาบัดกรีที่ปลายเหล็ก

xxxx
และใช้พลาสติกกาวร้อนยิงหุ้มที่บัดกรี และหุ้มท่อหดอีกชั้น

และ ผมต้องการขยาย ปลูกผักด้วย ซึ่งจะมี ระบบต่างหากคือ วาล์วรดน้ำผัก เซ็นเซอร์วัดความชื้นในดิน 1 ตัว ใช้กับnode เดียวกัน
สำหรับเซ็นเซอร์ดินตัวที่ 2สำหรับผัก นั้น ผมจะ DIY ดูว่า มันจะเวอร์กไหม
โดย IC4051 เพื่อขยาย port analog เพื่อรับค่า เซ็นเซอร์เดิมตัวแรกที่ใช้เหล็กกล่องเป็นอิเล็กโทรด วันดินปลูกทุเรียน กับ เซ็นเซอร์ตัวที่2 สำหรับตรวจดินผัก
ผมจะลองประดิษฐ์ดู โดยใช้ ไฟจาก Vin 5 Volt ต่อกับ ตัวต้านทาน 4.5 k ohm และจุ่มลงดิน เป็นขั้วที่ 1 และขั๊วที่2 จะเป็นสายไฟที่ต่อจากดิน เข้าขา analog (ผ่าน ic4051 ) แล้วดูว่า จะรับค่าได้ไหม

19กย65


code

int analogPin = A0; //ประกาศตัวแปร ให้ analogPin แทนขา analog ขาที่5
int vegetable_soil_dryness = 0;
void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);

}

void loop() {
  // put your main code here, to run repeatedly:
  vegetable_soil_dryness = analogRead(analogPin); //Value of the sensor connected Option 1 pin of Mux
   Serial.print("vegetable_soil_dryness   =   ");
     Serial.println(vegetable_soil_dryness);
   delay(5000);

}

ผล
ขณะยังไม่แตะกัน ระหว่าง A0 กับ ปลายอีกด้านของ 4.7K ohm (วงสีเหลือง)

11:05:59.116 -> vegetable_soil_dryness   =   3
11:06:04.118 -> vegetable_soil_dryness   =   7
11:06:09.119 -> vegetable_soil_dryness   =   4
11:06:14.114 -> vegetable_soil_dryness   =   4
11:06:19.111 -> vegetable_soil_dryness   =   7
11:06:24.111 -> vegetable_soil_dryness   =   9
11:06:29.141 -> vegetable_soil_dryness   =   7
11:06:34.143 -> vegetable_soil_dryness   =   7
11:06:39.145 -> vegetable_soil_dryness   =   7
11:06:44.133 -> vegetable_soil_dryness   =   6
11:06:49.138 -> vegetable_soil_dryness   =   7
11:06:54.143 -> vegetable_soil_dryness   =   8
11:06:59.114 -> vegetable_soil_dryness   =   10
11:07:04.137 -> vegetable_soil_dryness   =   9
11:07:09.112 -> vegetable_soil_dryness   =   28

ถ้าแตะกัน ผลจะได้

11:07:54.147 -> vegetable_soil_dryness   =   1024
11:07:59.142 -> vegetable_soil_dryness   =   1024
11:08:04.141 -> vegetable_soil_dryness   =   1024
11:08:09.125 -> vegetable_soil_dryness   =   1024
11:08:14.121 -> vegetable_soil_dryness   =   1024
11:08:19.117 -> vegetable_soil_dryness   =   1024
11:08:24.149 -> vegetable_soil_dryness   =   1024
11:08:29.126 -> vegetable_soil_dryness   =   1024
11:08:34.129 -> vegetable_soil_dryness   =   1024
11:08:39.131 -> vegetable_soil_dryness   =   1024
11:08:44.115 -> vegetable_soil_dryness   =   1024
11:08:49.150 -> vegetable_soil_dryness   =   1024
11:08:54.116 -> vegetable_soil_dryness   =   1024
11:08:59.153 -> vegetable_soil_dryness   =   1024
11:09:04.142 -> vegetable_soil_dryness   =   1024

ผมลองปักในดินชื้น
ผลดังนี้


11:24:49.201 -> vegetable_soil_dryness   =   7
11:24:54.215 -> vegetable_soil_dryness   =   7
11:24:59.214 -> vegetable_soil_dryness   =   8
11:25:04.208 -> vegetable_soil_dryness   =   7
11:25:09.190 -> vegetable_soil_dryness   =   8
11:25:14.218 -> vegetable_soil_dryness   =   72
11:25:19.196 -> vegetable_soil_dryness   =   19
11:25:24.186 -> vegetable_soil_dryness   =   213
11:25:29.211 -> vegetable_soil_dryness   =   365
11:25:34.188 -> vegetable_soil_dryness   =   627
11:25:39.228 -> vegetable_soil_dryness   =   285
11:25:44.223 -> vegetable_soil_dryness   =   498
11:25:49.209 -> vegetable_soil_dryness   =   472
11:25:54.202 -> vegetable_soil_dryness   =   456
11:25:59.221 -> vegetable_soil_dryness   =   525
11:26:04.200 -> vegetable_soil_dryness   =   518
11:26:09.228 -> vegetable_soil_dryness   =   560
11:26:14.213 -> vegetable_soil_dryness   =   565

จะเห็นว่า ตอนไม่แตะกัน (ก่อนปัก)ค่าที่ได้ไม่เกิน 20
พอผมปักในดินแล้ว ค่ากระโดด เป็น 500
฿฿฿฿฿

ลองปักในดินที่แห้ง ผล ไม่เกิน 15

11:38:54.280 -> vegetable_soil_dryness   =   10
11:38:59.264 -> vegetable_soil_dryness   =   8
11:39:04.263 -> vegetable_soil_dryness   =   8
11:39:09.243 -> vegetable_soil_dryness   =   6
11:39:14.266 -> vegetable_soil_dryness   =   6
11:39:19.261 -> vegetable_soil_dryness   =   8
11:39:24.274 -> vegetable_soil_dryness   =   9
11:39:29.261 -> vegetable_soil_dryness   =   13
11:39:34.285 -> vegetable_soil_dryness   =   13
11:39:39.282 -> vegetable_soil_dryness   =   13
11:39:44.253 -> vegetable_soil_dryness   =   12
11:39:49.288 -> vegetable_soil_dryness   =   9
11:39:54.281 -> vegetable_soil_dryness   =   9
11:39:59.257 -> vegetable_soil_dryness   =   9


ผมเทน้ำให้เปียก
ค่าที่ได้ขึ้น 1024 เลยครับ

11:41:44.275 -> vegetable_soil_dryness   =   7
11:41:49.268 -> vegetable_soil_dryness   =   16
11:41:54.266 -> vegetable_soil_dryness   =   1024
11:41:59.262 -> vegetable_soil_dryness   =   7
11:42:04.256 -> vegetable_soil_dryness   =   1024
11:42:09.289 -> vegetable_soil_dryness   =   1024
11:42:14.291 -> vegetable_soil_dryness   =   1024
11:42:19.284 -> vegetable_soil_dryness   =   1024
11:42:24.282 -> vegetable_soil_dryness   =   1024
11:42:29.270 -> vegetable_soil_dryness   =   1024
11:42:34.269 -> vegetable_soil_dryness   =   1024
11:42:39.302 -> vegetable_soil_dryness   =   1024

ผมลองวัด ความต่างศักย์​ ระหว่างขั้วทั้ง2 ที่จุ่มลงดิน =3.12V
วัดกระแสที่ไหลผ่านเต็มที่ แค่ 11 microAmp. ไม่ถึง 1 milliAmp ถือว่าน้อยมาก
การประยุกต์ใช้
ผมจะใช้ หล็กกัลวาไนส์ 4หุน 1 คู่ ปักดินแทน
และสามารถใช้เป็นเซ็นเซอร์ตรวจสอบระดับน้ำในถังเก็บน้ำได้ด้วย
ค่าใช้จ่ายสำหรับเซ็นเซอร์นี้ 10สตางค์ สำหรับ รีซิสเตอร์
20 - 60 บาท สำหรับเหล็กกล่อง แล้วแต่ความยาว
อายุการใช้งาน ผมคาดคะเน เซ็นเซอร์นี้ ไม่น้อยกว่า 2 ปีครับ
20กย65

kkkkkkk

21กย65


ได้ปักลงดินแล้ว
**ต้นถั่วฝักยาว

  • อายุ7วัน(นับจากเอาเมล็ดหยอดลงดิน)
    -24ชั่วโมง​ หลังจากย้ายจากที่ร่มมากลางแจ้ง

    -จากกราฟ
    เส้นสีน้ำเงิน เป็นค่าที่วัดจากดินที่โคนต้นทุเรียน​ มีค่า 169 จากเซ็นเซอร์​ที่ซื้อมาและดัดแปลงส่วนที่จุ่มลงดิน
    (0=เปียกสุดๆ,1024=แห้งสุดๆ)
    เส้นสีแดง เป็นค่าที่วัดจากดินที่โคนต้นถั่วฝัก​ยาว​ มีค่า 512 จากเซ็นเซอร์​ที่ประดิษฐ์​เอง
    (0=แห้งสุดๆ,1024=เปียกสุดๆ)
    -​จากกราฟ 2เส้น แต่แสดงผลตรงกันข้ามกัน
    รอการแก้ไขครับ จะใช้ ฟังชั่น​ map()

mmmmm
อื่นๆ


ใช้รางไข่ เพาะเมล็ดถั่วฝักยาว ตั้งในที่ร่มก่อน3วัน
mmmm

ปุ๋ยหมักทำเอง จากเศษอาหาร, เศษผัก, เศษปลา, ไก่ ที่เหลือจากทำอาหาร
มาแบ่งใส่10ถังแล้วใส่น้ำเยอะๆ ปล่อยไว้2-3วันเอาไปรดผัก,ต้นไม้ปลูกอื่นๆ
mmmmm

1 Likes

20กย.65
โค้ดที่ผมงงมาก แต่มันเวิร์กสำหรับผม
ผมทำสวิทช์ใน blynk แบบ auto และ แมนวล
V1 คือ button switch เพื่อ กำหนดว่า auto หรือ แมนวล
V2 คือ button switch เพื่อปิดเปิดวาล์ว แต่ถ้า V1 เป็น autoอยู่ เวลากด V2 ให้มันเด้งกลับ ไม่ให้ทำงานต่อได้

//ทั่วไป
//wifi
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
const char *ssid     = "xxxx";
const char *password = "xxxx";
int a=0;

///////////////////////////////////////////
//Blynk
#include <BlynkSimpleEsp8266.h>

char auth[]="xxxxxxxxx";
BlynkTimer timer;
#define BLYNK_PRINT Serial;
////////////////////////////////////////
WidgetLED solenoid_vegetable_led_blynk_v3(V3);
int auto_vegetable_valve_V1=0;
///////////////////////////////////////



void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
     WiFi.mode(WIFI_STA); //เชื่อมต่อ Wifi
     WiFi.begin(ssid, password);
   delay(500);
     Serial.println("\nConnecting to WiFi");
     while ((WiFi.status() != WL_CONNECTED)&&(a<10)) {
           Serial.print("*");
           a=a+1;
           delay(500);
      }
    Blynk.begin(auth, ssid, password, "oasiskit.com", 8080);  
    delay(500);
    Blynk.syncVirtual(V1);

}

/////////////////
BLYNK_WRITE(V1) //auto_vegetable_valve_V10
{//BLYNK_WRITE(V10) //Vbutton auto/manual วาล์วทุเรียน,auto_durian_valve_V6
  if (param.asInt()==1)//1=ทำงาน
  {//if (param.asInt()==1)//1=ทำงาน
    Blynk.virtualWrite(V2,"offBackColor");//งงมากๆๆ
       solenoid_vegetable_led_blynk_v3.off();
       Blynk.virtualWrite(V0,"string_close");
       auto_vegetable_valve_V1=1;
  }//if (param.asInt()==1)//1=ทำงาน
  else//if (param.asInt()==1)//1=ทำงาน
  {//else if (param.asInt()==1)//1=ทำงาน
    auto_vegetable_valve_V1=0;
  //     Blynk.syncVirtual(V0, V1, V2);
    
  }//else if (param.asInt()==1)//1=ทำงาน
  
}//BLYNK_WRITE(V10) //Vbutton auto/manual วาล์วทุเรียน,auto_durian_valve_V10
/////////////////

BLYNK_WRITE(V2) //(สวิทช์ปิด-เปิดโซลินอยด์ผัก
{//BLYNK_WRITE(V11) //(สวิทช์ปิด-เปิดโซลินอยด์ผัก
  if (auto_vegetable_valve_V1==0)
  {//if (auto_vegetable_valve_V10==0)
      if (param.asInt()==1)//1=ทำงาน
      {//if (param.asInt()==1)//1=ทำงาน
       solenoid_vegetable_led_blynk_v3.on();
       Blynk.virtualWrite(V0,"string_open");
       Blynk.setProperty(V2,"onLabel","กำลัง เปิด");
      }//if (param.asInt()==1)//1=ทำงาน
      else//if (param.asInt()==1)//1=ทำงาน
      {//else if (param.asInt()==1)//1=ทำงาน
    Blynk.virtualWrite(V2,"offBackColor");//งงมากๆๆ
       solenoid_vegetable_led_blynk_v3.off();
       Blynk.virtualWrite(V0,"string_close");
      }//else if (param.asInt()==1)//1=ทำงาน

  }//if (auto_vegetable_valve_V10==0)
  else//if (auto_vegetable_valve_V10==0)
  {//else if (auto_vegetable_valve_V10==0)
   //แจ้งในlog ว่า ตอนนี้เป็นออโต้ ให้เปลี่ยนเป็นแมนวลก่อน
   Blynk.virtualWrite(V0,"ตอนนี้เป็นออโต้ ให้เปลี่ยนเป็นแมนวลก่อน");
    Blynk.virtualWrite(V2,"offBackColor");//งงมากๆๆ
  }//else if (auto_vegetable_valve_V10==0)
}//BLYNK_WRITE(V2) //(สวิทช์ปิด-เปิดโซลินอยด์ผัก

/////////////////

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

}

คือคำสั่ง Blynk.virtualWrite(V2,“offBackColor”); แทนที่จะใช้ Blynk.setProperty(V2,“offBackColor”,“#FFFFFF”);

21กย65
ถ้าใช้ Blynk.setProperty(V2,“onBackColor”) จะคอมไพล์ ERROR
ถ้าBlynk.virtualWrite(V2,“onBackColor”) ไม่ ERROR แต่ Blynk LED widget ทำงานเพี้ยน
สรุป ไม่ต้องใช้ onBackColor ในขณะเปิด มันจะแสดงสีทึบ และ ข้อความ"ON"เอง
แต่ถ้า ช่วง OFF ต้องระบุ Blynk.virtualWrite(V2,“offBackColor”) มันจะให้ไม่ทึบเอง และเรียกข้อความ OFFเองด้วยครับ
ทดสอบใหม่
ผมใช้ Blynk.virtualWrite(V2,“offBackColor”); ในตำแหน่งที่ให้มันอยู่ใน mode off มันจะเรียก label มาเอง
ตำแหน่งที่ไม่มี offBackColor จะทำให้ Button นั้น ไปที่ ON ได้
ณ ตอนนี้ ใช้คำสั่ง Blynk.virtualWrite(V2,“offBackColor”); อย่างเดียวเพียงพอแล้ว

/////////////////
BLYNK_WRITE(V1) //auto_vegetable_valve_V10
{//BLYNK_WRITE(V10) //Vbutton auto/manual วาล์วทุเรียน,auto_durian_valve_V6
  if (param.asInt()==1)//1=ทำงาน
  {//if (param.asInt()==1)//1=ทำงาน
    Blynk.virtualWrite(V2,"offBackColor");//งงมากๆๆ
       solenoid_vegetable_led_blynk_v3.off();
       Blynk.virtualWrite(V0,"string_close");
       auto_vegetable_valve_V1=1;
  }//if (param.asInt()==1)//1=ทำงาน
  else//if (param.asInt()==1)//1=ทำงาน
  {//else if (param.asInt()==1)//1=ทำงาน
    auto_vegetable_valve_V1=0;
    
  }//else if (param.asInt()==1)//1=ทำงาน
  
}//BLYNK_WRITE(V10) //Vbutton auto/manual วาล์วทุเรียน,auto_durian_valve_V10
/////////////////

BLYNK_WRITE(V2) //(สวิทช์ปิด-เปิดโซลินอยด์ผัก
{//BLYNK_WRITE(V11) //(สวิทช์ปิด-เปิดโซลินอยด์ผัก
  if (auto_vegetable_valve_V1==0)
  {//if (auto_vegetable_valve_V10==0)
      if (param.asInt()==1)//1=ทำงาน
      {//if (param.asInt()==1)//1=ทำงาน
       solenoid_vegetable_led_blynk_v3.on();
       Blynk.virtualWrite(V0,"string_open");
      }//if (param.asInt()==1)//1=ทำงาน
      else//if (param.asInt()==1)//1=ทำงาน
      {//else if (param.asInt()==1)//1=ทำงาน
       Blynk.virtualWrite(V2,"offBackColor");//งงมากๆๆ
       solenoid_vegetable_led_blynk_v3.off();
//       Blynk.setProperty(V2,"offLabel","กำลัง OFF");
       Blynk.virtualWrite(V0,"string_close");
      }//else if (param.asInt()==1)//1=ทำงาน

  }//if (auto_vegetable_valve_V10==0)
  else//if (auto_vegetable_valve_V10==0)
  {//else if (auto_vegetable_valve_V10==0)
   //แจ้งในlog ว่า ตอนนี้เป็นออโต้ ให้เปลี่ยนเป็นแมนวลก่อน
   Blynk.virtualWrite(V0,"ตอนนี้เป็นออโต้ ให้เปลี่ยนเป็นแมนวลก่อน");
    Blynk.virtualWrite(V2,"offBackColor");//งงมากๆๆ
  }//else if (auto_vegetable_valve_V10==0)
}//BLYNK_WRITE(V2) //(สวิทช์ปิด-เปิดโซลินอยด์ผัก

/////////////////

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

22กย65
ผมได้ทำ void test1 สำหรับเปลี่ยนสี ของ offBackcolor หรือ onBackcolor ของ widget Button ได้เลย โดยใช้โค้ด
setProperty หรือ virtualWrite โดยผ่าน timer.setinterval อีกทีครับ

//ทั่วไป
//wifi
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
const char *ssid     = "xxxx";
const char *password = "xxxxx";
int a=0;

#define BLYNK_GREEN     "#23C48E"
    #define BLYNK_BLUE      "#04C0F8"
    #define BLYNK_YELLOW    "#ED9D00"
    #define BLYNK_RED       "#D3435C"
    #define BLYNK_DARK_BLUE "#5F7CD8"

///////////////////////////////////////////
//Blynk
#include <BlynkSimpleEsp8266.h>
char auth[]="xxx";
BlynkTimer timer;
#define BLYNK_PRINT Serial;
////////////////////////////////////////
WidgetLED solenoid_vegetable_led_blynk_v3(V3);
WidgetLED button_V2(V2);
int auto_vegetable_valve_V1=0;
///////////////////////////////////////



void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
     WiFi.mode(WIFI_STA); //เชื่อมต่อ Wifi
     WiFi.begin(ssid, password);
   delay(500);
     Serial.println("\nConnecting to WiFi");
     while ((WiFi.status() != WL_CONNECTED)&&(a<10)) {
           Serial.print("*");
           a=a+1;
           delay(500);
      }
    Blynk.begin(auth, ssid, password, "oasiskit.com", 8080);  
    delay(500);
   timer.setInterval(1000L,test1);
    
    Blynk.syncVirtual(V1);

}

/////////////////
BLYNK_WRITE(V1) //auto_vegetable_valve_V10
{//BLYNK_WRITE(V10) //Vbutton auto/manual วาล์วทุเรียน,auto_durian_valve_V6
  if (param.asInt()==1)//1=ทำงาน
  {//if (param.asInt()==1)//1=ทำงาน
    Blynk.virtualWrite(V2,"offBackColor");
       solenoid_vegetable_led_blynk_v3.off();
       Blynk.virtualWrite(V0,"string_close");
       auto_vegetable_valve_V1=1;
  }//if (param.asInt()==1)//1=ทำงาน
  else//if (param.asInt()==1)//1=ทำงาน
  {//else if (param.asInt()==1)//1=ทำงาน
    auto_vegetable_valve_V1=0;
    
  }//else if (param.asInt()==1)//1=ทำงาน
  
}//BLYNK_WRITE(V10) //Vbutton auto/manual วาล์วทุเรียน,auto_durian_valve_V10
/////////////////

BLYNK_WRITE(V2) //(สวิทช์ปิด-เปิดโซลินอยด์ผัก
{//BLYNK_WRITE(V11) //(สวิทช์ปิด-เปิดโซลินอยด์ผัก
  if (auto_vegetable_valve_V1==0)
  {//if (auto_vegetable_valve_V10==0)
      if (param.asInt()==1)//1=ทำงาน
      {//if (param.asInt()==1)//1=ทำงาน
       solenoid_vegetable_led_blynk_v3.on();
       Blynk.virtualWrite(V0,"string_open");
      }//if (param.asInt()==1)//1=ทำงาน
      else//if (param.asInt()==1)//1=ทำงาน
      {//else if (param.asInt()==1)//1=ทำงาน
       Blynk.virtualWrite(V2,"offBackColor");
       solenoid_vegetable_led_blynk_v3.off();
//       Blynk.setProperty(V2,"offLabel","กำลัง OFF");
       Blynk.virtualWrite(V0,"string_close");
      }//else if (param.asInt()==1)//1=ทำงาน

  }//if (auto_vegetable_valve_V10==0)
  else//if (auto_vegetable_valve_V10==0)
  {//else if (auto_vegetable_valve_V10==0)
   //แจ้งในlog ว่า ตอนนี้เป็นออโต้ ให้เปลี่ยนเป็นแมนวลก่อน
   Blynk.virtualWrite(V0,"ตอนนี้เป็นออโต้ ให้เปลี่ยนเป็นแมนวลก่อน");
    Blynk.virtualWrite(V2,"offBackColor");
  }//else if (auto_vegetable_valve_V10==0)
}//BLYNK_WRITE(V2) //(สวิทช์ปิด-เปิดโซลินอยด์ผัก

/////////////////
void test1()
{
       solenoid_vegetable_led_blynk_v3.on();
//       Blynk.virtualWrite(V0,"string_open");
 //      button_V2.on();
       Blynk.virtualWrite(V2,"color","#23C48E");
       Blynk.virtualWrite(V2,"onLabel","กำลัง เปิด");
       delay(5000);
       solenoid_vegetable_led_blynk_v3.off();
       Blynk.virtualWrite(V2,"color","##04C0F8");
       Blynk.virtualWrite(V2,"offLabel","กำลัง ปิด");
  //     button_V2.off();
       delay(5000);
  
}
/////////////////
void loop() {
     Blynk.run();
     timer.run();

}

ปรากฎว่า void test1 นี้ไม่สามารถเปลี่ยนสี button ได้ นอกจาก เรากดปุ่ม button ในแอพ blynk โดยตรง
ใครทำได้บ้างครับ ถ้าได้ช่วยบอกเทคนิคหน่อยครับ

1 Likes

เปลี่ยนจาก

Blynk.virtualWrite(V2,"color","#23C48E");

เป็น

Blynk.setProperty(V2,"color","#23C48E");

ครับ

ลองแล้วครับ ไม่เปลี่ยนสีครับ V2 เป็น widget button ,

ผมก็ใช้เปลี่ยนสีบ่อยนะครับดูสีด้วยว่ารองรับรึป่าว

รบกวน
ขอโค้ด ที่เปลี่ยน สี button ที่สั่งจาก void ด้วย ครับ
ผมลองแล้วไม่ได้จริงๆ
เอาแบบสั้นๆและได้จริงก็ได้ครับ
ขอบคุณครับ
ตอนนี้ ที่ผมทำได้ แค่ Blynk.virtualWrite(V2,1หรือ 0) V2 คือ button widget ,ที่สามารถสั่งจาก void ได้ โดยไม่แตะที่ปุ่ม blynk ( ไม่ใช้ Blynk_Write)

01ตค65
มีความคิดอยากขยายปลูกผักหลายๆชนิด ซึ่งการใช้น้ำก็ไม่เท่ากัน เพราะอายุการปลูกที่ต่างกัน ชนิดต่างกัน
เลยต้องมี เซ็นเซอร์วัดความชื้น และโซลินอยด์แยกตามด้วย
ทีนี้ เมื่อ nodemcu8266 ที่ใช้อยู่ 1 อัน ไม่เพียงพอ ต้องเพิ่มnodemcu8266 อีกอันครับ
ทีนี้ ผมอยากให้ใช้ Blynk ที่ต่อกับnodemcuตัวแรก ดังนั้นปัญหาการเชื่อมต่อ 2 nodeก็บังเกิดขึ้น เพราะไม่มีเคยทำมาก่อน เคยทำแบบ stand alone เท่านั้น
ผมใช้เวลาในการศึกษาการเชื่อมต่อระหว่าง2 node ด้วย json และ serial communication โดยใช้ RX,TX เสิร์ชหาตามเน็ด 2 วันเต็มๆ
ได้ข้อสรุป (ที่ผมรู้ อาจผิดได้)

  1. json ไม่ใช่เครื่องมือ การให้ nodemcu ติดต่อกัน
    2.json สามารถใช้ร่วมกับ espnowได้
    3.arduinojson.h มีหลาย version ,แต่ละversion จะใช้คำสั่งแตกต่างกันบ้าง ดังนั้นการเอาตย.ที่มีโค้ด json ควรดูว่า ใช้ library version เดียวกัน
    4.การต่อสายสื่อสารแบบ RX,TX ของ8266 2อัน ต้องต่อไขว้กัน คือ
    RXของnode Aต่อTX ของnode B,
    TXของnode A ต่อกับ RX ของnodeB
    Gndของnode A ต่อกับ Gnd ของnodeB
    5.SoftwareSerial.h ที่ใช้กำหนดขาเพื่อทำหน้าที่ RX,TX อาจไม่เหมาะที่จะใช้กับ nodeMCU ผลออกมาไม่แน่นอน
    6.การส่งทาง ข้อความ json ทาง serial ต้องระบุด้วย คำสั่ง เช่น serializeJson(doc_from_espnow, Serial2);
    7.การส่งค่าตัวแปร จากnode1 ไป node 2 ต้องส่งรูป json เพื่อจะเอาไปใช้งานต่อได้
    แต่ถ้าให้แสดงค่าในserial monitor ของ node2 เฉยๆ จาก node1 ไม่ต้องใช้ json
    ตย.
    ตัวส่ง(node1)
float sp = 0;
float heart = 0;

void setup() {
  Serial.begin(115200);
}
void loop()
{
  sp = 5 + random(5);
  heart = 100 + random(40);
  Serial.print(sp);
  Serial.print(",");
  Serial.println(heart);
  delay(1000);
}

ตัวรับ(node2)

void setup()
{
Serial.begin(115200);
}

void loop() {   
if (Serial.available() > 0) 
{
  String data = Serial.readStringUntil('\n');
  Serial.println(data);
}
}

xxxxxxxxxxxxxxxxxx

เปิด serial monitor ใน node2
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
ใน node1 ผมเพิ่ม dht ส่ง อุณหภูมิ และ ความชื้น และ string json ไปทาง serial ด้วย

#include <ArduinoJson.h>
StaticJsonDocument<256> doc_to_node2; // JSON Doc for Transmitting data to node2
String dht11_jsondata;               // create JSON string
///////////////////////////////////////////////////
float temperature;
float humidity;
#include <DHT.h>
#define DHTTYPE11 DHT11   // DHT 11
DHT dht(D4, DHTTYPE11);;

float sp = 0;
float heart = 0;

void setup() {
  Serial.begin(115200);
  dht.begin(); // initialize the DHT sensor
}
void loop()
{
//  float h = dht.readHumidity();
//  float t = dht.readTemperature();
  // Values we want to transmit
  long timestamp = millis();
   humidity = dht.readHumidity(); // ดึงค่าความชื้น
   temperature = dht.readTemperature(); // ดึงค่าอุณหภูมิ


  // Print the values on the "debug" serial port
  Serial.print("timestamp = ");
  Serial.println(timestamp);
  Serial.print("ความชื้น=");
  Serial.println(humidity, 1);
  Serial.print("อุณหภูมิ=");
  Serial.println(temperature, 1);
  sp = 5 + random(5);
  heart = 100 + random(40);
  Serial.print(sp);
  Serial.print(",");
  Serial.println(heart);
  doc_to_node2["v1"] = timestamp;  // Creating JSON data. Here { v1 : 28.55 }
  doc_to_node2["v2"] = temperature;  // Creating JSON data. Here { v1 : 28.55 }
  doc_to_node2["v3"] = humidity;   // Creating JSON data. Here { v2 : 34.35 }
  serializeJson(doc_to_node2, dht11_jsondata);
Serial.println(dht11_jsondata); 
dht11_jsondata = "";
  delay(1000);
}

xxxxxxxxxxxxxxxxxxxxx
สำหรับ node2 ไม่แก้ไขไดๆ


ผลใน terminal ของ node2
xxxxxxxxxxxxxxxxxxxxxxxxxxxxx

ต่อไป ผมใช้ json ใน node 2 เพื่อถอดข้อความจาก node1 (deserialize)
และปรับโค้ดใน node1 นิดหน่อย

โค้ด node1

#include <ArduinoJson.h>
StaticJsonDocument<256> doc_to_node2; // JSON Doc for Transmitting data to node2
String dht11_jsondata;               // create JSON string
///////////////////////////////////////////////////
float temperature;
float humidity;
#include <DHT.h>
#define DHTTYPE11 DHT11   // DHT 11
DHT dht(D4, DHTTYPE11);;

float sp = 0;
float heart = 0;

void setup() {
  Serial.begin(115200);
  dht.begin(); // initialize the DHT sensor
}
void loop()
{
//  float h = dht.readHumidity();
//  float t = dht.readTemperature();
  // Values we want to transmit
  long timestamp = millis();
   humidity = dht.readHumidity(); // ดึงค่าความชื้น
   temperature = dht.readTemperature(); // ดึงค่าอุณหภูมิ


  // Print the values on the "debug" serial port
  //Serial.print("timestamp = ");
//  Serial.println(timestamp);
//  Serial.print("ความชื้น=");
//  Serial.println(humidity, 1);
//  Serial.print("อุณหภูมิ=");
//  Serial.println(temperature, 1);
//  sp = 5 + random(5);
//  heart = 100 + random(40);
//  Serial.print(sp);
//  Serial.print(",");
//  Serial.println(heart);
  doc_to_node2["v1"] = timestamp;  // Creating JSON data. Here { v1 : 28.55 }
  doc_to_node2["v2"] = temperature;  // Creating JSON data. Here { v1 : 28.55 }
  doc_to_node2["v3"] = humidity;   // Creating JSON data. Here { v2 : 34.35 }
  serializeJson(doc_to_node2, dht11_jsondata);
  Serial.println(dht11_jsondata); 
dht11_jsondata = "";
  delay(5000);
}

โค้ด node2

#include <ArduinoJson.h> //https://github.com/bblanchon/ArduinoJson
StaticJsonDocument<256> doc_from_node1; // JSON Doc 
String dht11_jsondata_from_node1;
int timestamp;
int temperature = 0;
int humidity = 0;
void setup()
{
Serial.begin(115200);
}

void loop() {   
if (Serial.available() > 0) 
{
  dht11_jsondata_from_node1 = Serial.readStringUntil('\n');
 // Serial.println(dht11_jsondata_from_node1);
DeserializationError error = deserializeJson(doc_from_node1, dht11_jsondata_from_node1);
  if (!error) {
    Serial.print("from node1 : ");
    Serial.println(dht11_jsondata_from_node1);
    timestamp  = doc_from_node1["v1"];                 // Storing Temperature Data
    temperature  = doc_from_node1["v2"];                 // Storing Temperature Data
    humidity  = doc_from_node1["v3"];                 // Storing Humidity Data
    Serial.print(timestamp);
    Serial.print(",");
    Serial.print(temperature);
    Serial.print(",");
    Serial.println(humidity);
  }

  else
  {
    Serial.print(F("deserializeJson() failed: "));
    Serial.println(error.f_str());
    return;
  }
}
 delay(00); 

}

ผลดังรูปนี้


คงจะเพียงพอที่ผมจะเอาไปใช้งานได้แล้วครับ
ความฝันใกล้เป็นจริงแล้ว
xxxxxxxxxxxxxxxxxxxxxxxxxx
ขั้นตอนต่อไป ได้เพิ่มโค้ดสำหรับ node2 เพื่อแสดงใน Blynk ด้วย

โค้ดnode2

#include <ArduinoJson.h> //https://github.com/bblanchon/ArduinoJson
StaticJsonDocument<256> doc_from_node1; // JSON Doc 
String dht11_jsondata_from_node1;
int timestamp;
int temperature = 0;
int humidity = 0;
#include <ArduinoJson.h>
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
const char *ssid     = "xxxx";
const char *password = "xxxx";
int a=0;
//Blynk
#include <BlynkSimpleEsp8266.h>
// Auth Token :xxxx-Blynkเดิม
char auth[]="xxxx";
BlynkTimer timer;
#define BLYNK_PRINT Serial;
////////////////////////////////////////

void setup()
{
Serial.begin(115200);
     WiFi.mode(WIFI_STA); //เชื่อมต่อ Wifi
     WiFi.begin(ssid, password);
   delay(500);
     Serial.println("\nConnecting to WiFi");
     while ((WiFi.status() != WL_CONNECTED)&&(a<10)) {
           Serial.print("*");
           a=a+1;
           delay(500);
      }
    Blynk.begin(auth, ssid, password, "oasiskit.com", 8080);  
    delay(500);
}

void loop() {   
if (Serial.available() > 0) 
{
  dht11_jsondata_from_node1 = Serial.readStringUntil('\n');
 // Serial.println(dht11_jsondata_from_node1);
DeserializationError error = deserializeJson(doc_from_node1, dht11_jsondata_from_node1);
  if (!error) {
    Serial.print("from node1 : ");
    Serial.println(dht11_jsondata_from_node1);
    timestamp  = doc_from_node1["v1"];                 // Storing Temperature Data
    temperature  = doc_from_node1["v2"];                 // Storing Temperature Data
    humidity  = doc_from_node1["v3"];                 // Storing Humidity Data
    Serial.print(timestamp);
    Serial.print(",");
    Serial.print(temperature);
    Serial.print(",");
    Serial.println(humidity);
      Blynk.virtualWrite(V4,timestamp);
      Blynk.virtualWrite(V5,temperature);
      Blynk.virtualWrite(V6,humidity);
  }

  else
  {
    Serial.print(("deserializeJson() failed: "));
    Serial.println(error.f_str());
    return;
  }
}
       Blynk.run();
     timer.run();

}

และสามารถแสดงใน Blynk ได้แล้วครับ…
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
2ตค65
ต่อไป สั่งทางblynk ของnode2เพื่อให้ node1 เปิดไฟ led โดยผ่าน RX,TX และ json
โค้ดnode1

#include <ArduinoJson.h>
StaticJsonDocument<256> doc_to_node2; // JSON Doc for Transmitting data to node2
StaticJsonDocument<256> doc_from_node2; // JSON Doc 
String dht11_jsondata;               // create JSON string
String order_jsondata_from_node2;               // create JSON string
///////////////////////////////////////////////////
float temperature;
float humidity;
#include <DHT.h>
#define DHTTYPE11 DHT11   // DHT 11
DHT dht(D4, DHTTYPE11);;

float sp = 0;
float heart = 0;
int LEDD3 = D3; // ขา D3
void setup() {
pinMode(LEDD3, OUTPUT);
digitalWrite(LEDD3, LOW);
Serial.begin(115200);
  dht.begin(); // initialize the DHT sensor
}
void loop()
{
//  float h = dht.readHumidity();
//  float t = dht.readTemperature();
  // Values we want to transmit
  long timestamp = millis();
   humidity = dht.readHumidity(); // ดึงค่าความชื้น
   temperature = dht.readTemperature(); // ดึงค่าอุณหภูมิ
 //  delay(3000);

  // Print the values on the "debug" serial port
  //Serial.print("timestamp = ");
//  Serial.println(timestamp);
//  Serial.print("ความชื้น=");
//  Serial.println(humidity, 1);
//  Serial.print("อุณหภูมิ=");
//  Serial.println(temperature, 1);
//  sp = 5 + random(5);
//  heart = 100 + random(40);
//  Serial.print(sp);
//  Serial.print(",");
//  Serial.println(heart);
  doc_to_node2["v1"] = timestamp;  // Creating JSON data. Here { v1 : 28.55 }
  doc_to_node2["v2"] = temperature;  // Creating JSON data. Here { v1 : 28.55 }
  doc_to_node2["v3"] = humidity;   // Creating JSON data. Here { v2 : 34.35 }
  serializeJson(doc_to_node2, dht11_jsondata);
  Serial.println(dht11_jsondata); 
  dht11_jsondata = "";
 
if (Serial.available() > 0) 
{
  order_jsondata_from_node2 = Serial.readStringUntil('\n');
  DeserializationError error = deserializeJson(doc_from_node2, order_jsondata_from_node2);
  if (!error) {
   String led_status   = doc_from_node2["v0"]; //values are 1 or 0
    Serial.print("led status : ");Serial.println(led_status);
    if(led_status=="v0_on")
    digitalWrite(LEDD3,HIGH);
    else if(led_status=="v0_off")
    digitalWrite(LEDD3,LOW);
    else
    Serial.println(led_status);
  }

  else
  {
    Serial.print(("deserializeJson() failed: "));
    Serial.println(error.f_str());
    return;
  }  
}
 delay(5000);
}

trick ตำแหน่ง delay(5000); วางตรงนี้ เวิร์คสุด

xxxxxxxxxxxxxxxxxxxxxx
โค้ดnode2

#include <ArduinoJson.h> //https://github.com/bblanchon/ArduinoJson
StaticJsonDocument<256> doc_from_node1; // JSON Doc 
StaticJsonDocument<256> doc_from_node2; // JSON Doc 
String dht11_jsondata_from_node1;
String order_jsondata_from_node2;
int timestamp;
int temperature = 0;
int humidity = 0;
#include <ArduinoJson.h>
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
const char *ssid     = "xxx";
const char *password = "xxxx";
int a=0;
//Blynk
#include <BlynkSimpleEsp8266.h>
// Auth Token : xxx-Blynkเดิม
char auth[]="xxxx";
BlynkTimer timer;
#define BLYNK_PRINT Serial;
////////////////////////////////////////

void setup()
{
Serial.begin(115200);
     WiFi.mode(WIFI_STA); //เชื่อมต่อ Wifi
     WiFi.begin(ssid, password);
   delay(500);
     Serial.println("\nConnecting to WiFi");
     while ((WiFi.status() != WL_CONNECTED)&&(a<10)) {
           Serial.print("*");
           a=a+1;
           delay(500);
      }
    Blynk.begin(auth, ssid, password, "oasiskit.com", 8080);  
    delay(500);
}

void loop() {   
if (Serial.available() > 0) 
{
  dht11_jsondata_from_node1 = Serial.readStringUntil('\n');
 // Serial.println(dht11_jsondata_from_node1);
DeserializationError error = deserializeJson(doc_from_node1, dht11_jsondata_from_node1);
  if (!error) {
    Serial.print("from node1 : ");
    Serial.println(dht11_jsondata_from_node1);
    timestamp  = doc_from_node1["v1"];                 // Storing Temperature Data
    temperature  = doc_from_node1["v2"];                 // Storing Temperature Data
    humidity  = doc_from_node1["v3"];                 // Storing Humidity Data
    Serial.print(timestamp);
    Serial.print(",");
    Serial.print(temperature);
    Serial.print(",");
    Serial.println(humidity);
      Blynk.virtualWrite(V4,timestamp);
      Blynk.virtualWrite(V5,temperature);
      Blynk.virtualWrite(V6,humidity);
  }

  else
  {
    Serial.print(("deserializeJson() failed: "));
    Serial.println(error.f_str());
    return;
  }
}
       Blynk.run();
     timer.run();

}
BLYNK_WRITE(V2)                                 // Read from Virtual pin V4
{

  bool s0 = param.asInt();                    // parameter as int
  if (s0 == HIGH)
  {
    doc_from_node2["v0"] = "v0_on";                // Writing { "v4" : 1 } on Serial2
    serializeJson(doc_from_node2, order_jsondata_from_node2);
     Serial.println(order_jsondata_from_node2);
     order_jsondata_from_node2="";
   delay(500);
  }
  else if (s0 == LOW)
  {
    doc_from_node2["v0"] = "v0_off";                // Writing { "v4" : 1 } on Serial2
    serializeJson(doc_from_node2, order_jsondata_from_node2);
     Serial.println(order_jsondata_from_node2);
     order_jsondata_from_node2="";
   delay(500);
  }
}

xxxxxxxxxx


serial monitor ของ node1
จะแสดงค่า string ที่รับผ่าน json จาก node2
xxxxxxxxxxxxxxx

ไฟ LED สว่างแล้วครับ
แต่ต้องใช้เวลารอประมาณ 3 วินาที
xxxxxxxxx
ใช้ได้แล้วครับ

1 Likes

6ตค65
ในการใช้ฟังก์ชั่น Blink_Write
ผมเจอ trick หรือ ข้อยกเว้น สำหรับผมเองคือ
การใช้ LOW,HIGH ในการกำหนดใน digitalWrite(pinx,LOWหรือ HIGH) จะไม่เวิอร์คเท่า ใช้ 0หรือ1
คือ ถ้าใช้ LOW,HIGH มันไม่ยอมทำตามครับ
เช่นโค้ด

/////////////////
BLYNK_WRITE(V8) //(สวิทช์ปิด-เปิดโซลินอยด์ทุเรียน
{//BLYNK_WRITE(V8) //(สวิทช์ปิด-เปิดโซลินอยด์ทุเรียน
  if (auto_durian_valve_V6==0)
  {//if (auto_durian_valve_V6==0)
      if (param.asInt()==1)//1=ทำงาน
      {//if (param.asInt()==1)//1=ทำงาน
       digitalWrite(durian_valve_D3, LOW);//active low
       durian_valve_D3_state=0;
       Serial.println("เปิดวาล์วน้ำ");
       solenoid_durian_led_blynk_v7.on();
       Blynk.virtualWrite(V9,string_open);
       Blynk.setProperty(V8,"onLabel","กำลัง เปิด");
        
      }//if (param.asInt()==1)//1=ทำงาน
      else//if (param.asInt()==1)//1=ทำงาน
      {//else if (param.asInt()==1)//1=ทำงาน
       digitalWrite(durian_valve_D3, HIGH);//active low
       Serial.println("ปิดวาล์วน้ำ");
       solenoid_durian_led_blynk_v7.off();
       Blynk.virtualWrite(V9,string_close);
       Blynk.virtualWrite(V8,"offBackColor");
       durian_valve_D3_state=1;
        
      }//else if (param.asInt()==1)//1=ทำงาน

  }//if (auto_durian_valve_V6==0)
  else//if (auto_durian_valve_V6==0)
  {//else if (auto_durian_valve_V6==0)
   //แจ้งในlog ว่า ตอนนี้เป็นออโต้ ให้เปลี่ยนเป็นแมนวลก่อน
   Blynk.virtualWrite(V9,"ตอนนี้เป็นออโต้ ให้เปลี่ยนเป็นแมนวลก่อน");
   Blynk.virtualWrite(V8,"offBackColor");

  }//else if (auto_durian_valve_V6==0)
}//BLYNK_WRITE(V8) //(สวิทช์ปิด-เปิดโซลินอยด์ทุเรียน

ลองแล้งไม่ทำงานตามที่กดปุ่มใน blynk
พอเปลี่ยนเจาก LOWเป็น 0,และจาก HIGH เป็น 1 เช่น

/////////////////
BLYNK_WRITE(V8) //(สวิทช์ปิด-เปิดโซลินอยด์ทุเรียน
{//BLYNK_WRITE(V8) //(สวิทช์ปิด-เปิดโซลินอยด์ทุเรียน
  if (auto_durian_valve_V6==0)
  {//if (auto_durian_valve_V6==0)
      if (param.asInt()==1)//1=ทำงาน
      {//if (param.asInt()==1)//1=ทำงาน
       digitalWrite(durian_valve_D3, 0);//active low
       durian_valve_D3_state=0;
       Serial.println("เปิดวาล์วน้ำ");
       solenoid_durian_led_blynk_v7.on();
       Blynk.virtualWrite(V9,string_open);
       Blynk.setProperty(V8,"onLabel","กำลัง เปิด");
        
      }//if (param.asInt()==1)//1=ทำงาน
      else//if (param.asInt()==1)//1=ทำงาน
      {//else if (param.asInt()==1)//1=ทำงาน
       digitalWrite(durian_valve_D3, 1);//active low
       Serial.println("ปิดวาล์วน้ำ");
       solenoid_durian_led_blynk_v7.off();
       Blynk.virtualWrite(V9,string_close);
       Blynk.virtualWrite(V8,"offBackColor");
       durian_valve_D3_state=1;
        
      }//else if (param.asInt()==1)//1=ทำงาน

  }//if (auto_durian_valve_V6==0)
  else//if (auto_durian_valve_V6==0)
  {//else if (auto_durian_valve_V6==0)
   //แจ้งในlog ว่า ตอนนี้เป็นออโต้ ให้เปลี่ยนเป็นแมนวลก่อน
   Blynk.virtualWrite(V9,"ตอนนี้เป็นออโต้ ให้เปลี่ยนเป็นแมนวลก่อน");
   Blynk.virtualWrite(V8,"offBackColor");

  }//else if (auto_durian_valve_V6==0)
}//BLYNK_WRITE(V8) //(สวิทช์ปิด-เปิดโซลินอยด์ทุเรียน

มันทำงานได้ปกติ ไม่ทราบเป็นเพราะอะไรครับ

xxxxxxxxxxxxxxxxxxx
สภาพในตู้ควบคุม การรดต้นทุเรียน/ผัก



**LCD ไม่ได้ใช้แล้ว เพราะขาไม่พอ เลยเอา LCD ออกจะได้ขาเพิ่มอีก2 pin
ใช้ดูข้อมูลผ่าน Blynk เป็นหลัก
**ตอนเที่ยงแดดร้อน ทำให้อุณหภูมิในตู้ร้อนมาก เลยต้องเพิ่ม พัดลม 2 ตัว (ให้ลมเข้าและดูดลมออก)
xxxxxxxxxxxxxxxxxx
Trick(ผมคิดเอง) อีกข้อเกี่ยวกับ Blynk คือ ต้องการให้ Blynk อ่านค่า ตั้งต้น เกี่ยวกับปุ่ม แมนวล / ออโต้ ทุกครั้ง
ผมกำหนดให้อ่าน เป็นช่วงๆเช่น

   timer.setInterval(2100L,V6_sync);
   timer.setInterval(2300L,V10_sync);
   timer.setInterval(2200L,V16_sync);

///////
void V6_sync()
{
  Blynk.syncVirtual(V6);
}
///////

///////
void V10_sync()
{
  Blynk.syncVirtual(V10);
}
///////

///////
void V16_sync()
{
  Blynk.syncVirtual(V16);
}
///////
ช่วยให้ Blynk ทำงานได้ดีขึ้นเยอะ
1 Likes

อันนี้ปกติมันต้องใช้ได้นะครับ โค้ตหลักเกือบทุกโค้ตผมก็ใช้ HIGH,LOW ตลอด ไม่เคยเจอว่า มันไม่ทำงานเคสนี้เลย

image

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

สวนอยู่แถวไหนครับนี้

แถวปัตตานีครับ ยังเป็นต้นแบบอยู่เลย 555 ตอนนี้เริ่ม stable จะขยายเป็น ปลูกแยกผักแต่ละชนิด แบบว่า
ปลูกเสร็จ แล้วลืมเลยครับ…

1 Likes

ใช่ครับ ผมเจอสาเหตุแล้ว คือ ใส่โค้ดผิดพลาดเอง จริงๆ ต้อง HIGH แต่เขียน LOW(ลืมแก้)

เคยทำsync ใน setup จำไม่ได้ว่าผลเป็นอย่างไร แต่ความรู้สึกว่า แยกเป็น setinterval จะเวอร์กกว่าครับ(ความรู้สึกล้วนๆ)

เยี่ยมครับ เดียวผมช่วยดัน 555

7-8 ตค.65
elecScreenshot 2022-10-08 171211
เอามาใส่ใน EDRAW ซะเลย แต่เสียเวลามากครับ
เพิ่มเติม item ใหม่
1.วงจรเช็คไฟ 12 โวลต์ โดยใช้ analog input โดยผ่าน voltage divider ใช้ resister 2 ตัว และไดโอด 1 ตัว ผ่าน ic4051 แล้วเข้า node A
2.เพิ่มวงจรรดน้ำพร้อมเซ็นเซอร์วัดความชื้นในดิน อีก 4 ชุด

โดยที่ เซ็นเซอร์ความชื้นในดิน จะส่งผ่านIC4051 เข้า node8266ตัวA ,โซลินอยด์เปิดปิดน้ำ 4 ตัวนี้จะต่อมาจาก node B,
จากนั้น Node A จะสั่งเปิดปิดน้ำ จาก A ไปยัง node8266 ตัวB ผ่าน RX,TX ใช้ json
3.Node A จะทำหน้าที่ติดต่อ Blynk

9-10ตค65
โค้ด Node1 (part1/3)
อยากให้เพื่อนช่วยชี้แนะว่าควรปรับปรุงตรงไหนบ้างครับ
ยังไม่อัพโหลดอีกครับ
ถ้าอัพโหลดแล้ว เจอปัญหาอะไรจะมาเล่าอีกทีครับ

//ขาที่ใช้แล้วได้แก่ 
//D0(vegetable_valve_D0);D1(fan_D1),D2(),D3(durian_valve_D3,ปล่อยน้ำรดต้นไม้),D4(dht),D5(MUX_A),D6(MUX_B),D7(MUX_C)
//D8(ใช้แล้ว uploadไม่ได้)
//A0(analogPin-ตรวจความชื้นต้นทุเรียน),
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//V0(gauge=temperature),V1(humidity),V2(ค่าความแห้งของดิน-durian_soil_wetness_percent ),V3(start_thisApp_V3),
//V4(currentDate),V5(formattedTime),V6(button auto/manual วาล์วทุเรียน,auto_durian_valve_V6),V7(LED รดน้ำต้นไม้,on=กำลังรดน้ำ-solenoid_durian_led_blynk_v7)
//V8(สวิทช์ปิด-เปิดโซลินอยด์ทุเรียน),V9(terminal-log ปิด-เปิดวาล์ว),V10(button auto/manual วาล์วผัก,auto_vegetable_valve_V10),
//V11(button สวิทช์ปิด-เปิดวาล์วผัก),V12(LED ปิด-เปิดวาล์วผัก ),V13(terminal-log ปิด-เปิดวาล์วผัก),V14(value display-vegetable_soil_wetness_percent)
//V15(LED ปิด-เปิดพัดลม ),V16(แมนวล/ออโต้พัดลม),V17(สวิทช์ปิดเปิดพัดลม),V18(log พัดลม),V19(transformer_status_v19)
//V20(volt_12_transformer_raw),V21(volt_12_transformer_map),//V22(water_spinach1_solenoid_led_blynk_v22)
//V23(autowater_spinach1_valve_V23),V24(manual_water_spinach1_valve_V24),V25(valveผักบุ้ง1=ปิดค่าเท่ากับ10 เปิดค่าเท่ากับ20เพื่อแสดงในsuperchart)
//V26(ค่าเปอร์เซนต์ดินผักบุ้ง1-water_spinach1_soil_wetness_percent).V27(log ผักบุ้งและผักกาด),V28(lettuce1_solenoid_led_blynk_v28)
//V29(auto_lettuce1_valve_V29),V30(manual_lettuce1_valve_V30),V31(valveผักกาด1=ปิดค่าเท่ากับ10 เปิดค่าเท่ากับ20เพื่อแสดงในsuperchart)
//V32(ค่าเปอร์เซนต์ดินผักกาด1-lettuce1_soil_wetness_percent),//V33(water_spinach2_solenoid_led_blynk_V33)//V34(auto_water_spinach2_valve_V34)
//V35(manual_water_spinach2_valve_V35),//V36(valveผักบุ้ง2=ปิดค่าเท่ากับ10 เปิดค่าเท่ากับ20เพื่อแสดงในsuperchart)//V37(ค่าเปอร์เซนต์ดินผักบุ้ง2-water_spinach2_soil_wetness_percent)
//V38();//V39(lettuce2_solenoid_led_blynk_v39)//V40(auto_lettuce2_valve_V40)
//V41(manual_lettuce2_valve_V41),//V42(valveผักกาด2=ปิดค่าเท่ากับ10 เปิดค่าเท่ากับ20เพื่อแสดงในsuperchart)////V43(ค่าเปอร์เซนต์ดินผักกาด2-lettuce2_soil_wetness_percent),
//////////////////////////////////////////////////////////////////////////////////////////////////
//ic4051
// timer.setInterval(1250L, ic4051_task);
#define MUX_A D5
#define MUX_B D6
#define MUX_C D7
/*
 ESP8266 4051 Multiplexer by Brian Lough
 
 An example showing how to use a 4051 multiplexer with an esp8266
 to connect up to 8 analog sensors.
 Wiring:
 Wemos ->  4051
 ---------------
 D5    ->   S0 (A)
 D6    ->   S1 (B)
 D7    ->   S2 (C)
 A0    ->   Common
 3.3v  ->   VCC
 G     ->   GND
 G     ->   Inhibit
 G     ->   VEE  
 
 4051 Option pins are then wired to whatever Analog sensors required
 One thing to note: say for example if you only require 2 analog sensors,
 You can just wire up S0(A) and connect S1 & S2 to GND and you will be 
 able to switch between option 1 and option 2 pins.
 Same goes for up to 4 pins (just use S0 & S1)
*/
//ทั่วไป
//V4(currentDate),V5(formattedTime),V3(start_thisApp_V3),
//timer.setInterval(2000L,check_time_task);
//wifi

#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
const char *ssid     = "xxxxx";
const char *password = "xxxxxx";
int a=0;
///////////////////////////////////////////
//Blynk
#include <BlynkSimpleEsp8266.h>
// Auth Token : xxxxxxxx-Blynkเดิม
char auth[]="xxxxxxxxxxxxxxxxxx";//blynkใหม่ eleceasy
BlynkTimer timer;
#define BLYNK_PRINT Serial;
////////////////////////////////////////
//0.ดึงเวลาจากเน็ตมาใช้
#include <NTPClient.h>
#include <time.h>
// String formattedTime;
 String currentDate;
 int monthDay;
 int currentMonth;
// unsigned long epochTime;
WiFiUDP ntpUDP;
const long offsetTime = 25200;       // หน่วยเป็นวินาที จะได้ 7*60*60 = 25200
NTPClient timeClient(ntpUDP, "pool.ntp.org");
int timezone = 7 * 3600; //ตั้งค่า TimeZone ตามเวลาประเทศไทย
int dst = 0; //กำหนดค่า Date Swing Time
int currentHour = 0;
int currentMinute=0 ;
// กำหนดค่า offset time เนื่องจากเวลาของเซิฟเวอร์นี้เป็นเวลา UTC เราต้องทำให้เป็นเวลาของประเทศไทย
// เวลาของประเทศไทย = UTC+7 ชั่วโมง ต้องกำหนด offset time = 7 ชั่วโมง

//Week Days
String weekDays[7]={"อาทิตย์", "จันทร์", "อังคาร", "พุธ", "พฤหัส", "ศุกร์", "เสาร์"};

//Month names
String months[12]={"มกราคม", "กุมภาพันธ์", "มีนาคม", "เมษายน", "พฤษภาคม", "มิถุนายน", "กรกฎาคม", "สิงหาคม", "กันยายน", "ตุลาคม", "พฤศจิกายน", "ธันวาคม"};
String currentMonthName;
String string_close;
 String string_open;
//const long offsetTime = 25200;       // หน่วยเป็นวินาที จะได้ 7*60*60 = 25200
//long currentMillisMove=millis(); 
unsigned long start_ms_thisApp=0;//ตัวแปรสำหรับนับเวลาที่ได้ทำงานหลังรีสตาร์ตครั้งล่าสุด
int start_thisApp_V3=0;//ตัวแปรสำหรับนับเวลาที่ได้ทำงานหลังรีสตาร์ตครั้งล่าสุด
///////////////////////////////////////////////////

#include <Wire.h>
///////////////////////////////////////////////
//0  ตรวจสอบอุณหภูมิ
//V0(gauge=temperature),V1(humidity)
float maxtemp = -9999; // init with absurdly low value
float mintemp = 9999; // init with absurdly high value
float temperature;
float humidity;
#include <DHT.h>
#define DHTTYPE11 DHT11   // DHT 11
DHT dht(D4, DHTTYPE11);;
///////////////////////////////////////////
//3 ปล่อยน้ำรดต้นทุเรียน
//V2(ค่าความแห้งของดิน-durian_soil_wetness_percent )
//V6(button auto/manual วาล์วทุเรียน,auto_durian_valve_V6)
//V7(LED รดน้ำต้นไม้,on=กำลังรดน้ำ-solenoid_durian_led_blynk_v7)
////V8(สวิทช์ปิด-เปิดโซลินอยด์ทุเรียน),V9(terminal-log ปิด-เปิดวาล์ว)
// timer.setInterval(1000L, durian_task);

int durian_valve_D3 = D3;// ปล่อยน้ำรดต้นทุเรียน
bool durian_valve_D3_state=1;//1=คือปิด active low
int auto_durian_valve_V6=0;
// put your main code here, to run repeatedly:
int durian_soil_dryness;
int durian_soil_wetness_percent=0; 
int analogPin = A0; //ประกาศตัวแปร ให้ analogPin แทนขา analog ขาที่5
WidgetLED solenoid_durian_led_blynk_v7(V7);
///////////////////////////////////////////
//4 ปล่อยน้ำรดผัก
//,V10(button auto/manual วาล์วผัก,auto_vegetable_valve_V10),
//V11(button สวิทช์ปิด-เปิดวาล์วผัก),V12(LED ปิด-เปิดวาล์วผัก ),V13(terminal-log ปิด-เปิดวาล์วผัก),
//V14(value display-vegetable_soil_wetness_percent)
//     timer.setInterval(1250L, vegetable_task);
int vegetable_soil_wetness = 0;
int vegetable_soil_wetness_percent = 0;
int vegetable_valve_D0 = D0;// ปิดเปิดวาล์วน้ำรดผัก
bool vegetable_valve_D0_state=1;//1=คือปิด active low
WidgetLED solenoid_vegetable_led_blynk_v12(V12);
int auto_vegetable_valve_V10=0;
///////////////////////////////////////
//5.พัดลมลดความร้อน
//V15(LED ปิด-เปิดพัดลม ),V16(แมนวล/ออโต้พัดลม),V17(สวิทช์ปิดเปิดพัดลม),V18(log พัดลม),
//timer.setInterval(1500L,temp_humid_task);
int fan_D1 = D1;
WidgetLED fan_D1_v15(V15);
int auto_fan_V16=1;
bool fan_D1_state=1;//1=คือปิด active low
///////////////////////////////////////
//6.      volt_12_transformer_task
//V19(transformer_status_v19)
//V20(volt_12_transformer_raw),V21(volt_12_transformer_map),
//timer.setInterval(4500L,volt_12_transformer_task);
int volt_12_transformer_raw,volt_12_transformer_map,volt_12_transformer_average;
WidgetLED transformer_status_v19(V19);//blynk led หม้อแปลงปกติ เขียว,ผิดปกติ แแดง
//unsigned long last_transformer_read_ms=0;//ตัวแปรสำหรับนับเวลาที่ได้ทำงานตรวจแบตล่าสุด
unsigned long start_5min_interval_transformer_read_ms=0;//ตัวแปรสำหรับนับเวลาที่ได้ทำงานตรวจแบตล่าสุด
////////

//7 ปล่อยน้ำรดผักบุ้ง1
//V22(water_spinach1_solenoid_led_blynk_v22)
//V23(auto_water_spinach1_valve_V23),V24(manual_water_spinach1_valve_V24),
//V25(valveผักบุ้ง1=ปิดค่าเท่ากับ10 เปิดค่าเท่ากับ20เพื่อแสดงในsuperchart)
//V26(ค่าเปอร์เซนต์ดินผักบุ้ง1-water_spinach1_soil_wetness_percent),V27(log ผักบุ้งและผักกาด)
//timer.setInterval(1400L,water_spinach1_task);
//int water_spinach1_valve_on_value_V25=0;
#include <ArduinoJson.h>
//String recv_jsondata;
String order_from_node1;
String info_from_node2;
StaticJsonDocument<256> doc_to_node2;
StaticJsonDocument<256> doc_from_node2;
int water_spinach1_soil_wetness_raw = 0;
int water_spinach1_soil_wetness_percent = 0;
int water_spinach1_valve_state_to_node2;
int water_spinach1_valve_state_from_node2;//0 คือเปิดวาล์ว 1คือปิด active low
int water_spinach1_soil_wetness_state=1;//0 คือดินแห้ง 1คือดินชื้น
WidgetLED water_spinach1_solenoid_led_blynk_v22(V22);
int auto_water_spinach1_valve_V23=0;
/////
//8  lettuce1_task
//V28(lettuce1_solenoid_led_blynk_v28)
//V29(auto_lettuce1_valve_V29),V30(manual_lettuce1_valve_V30),
//V31(valveผักกาด1=ปิดค่าเท่ากับ10 เปิดค่าเท่ากับ20เพื่อแสดงในsuperchart)
//V32(ค่าเปอร์เซนต์ดินผักกาด1-lettuce1_soil_wetness_percent),
//timer.setInterval(1400L,lettuce1_task);
int lettuce1_soil_wetness_raw,lettuce1_soil_wetness_state;
int lettuce1_soil_wetness_percent;
int lettuce1_valve_state_to_node2;
int lettuce1_valve_state_from_node2 ;// ปิดเปิดวาล์วน้ำรดผักกาด1
WidgetLED lettuce1_solenoid_led_blynk_v28(V28);
int auto_lettuce1_valve_V29=0;
////////////////////////////////////////
//9 ปล่อยน้ำรดผักบุ้ง2
//V33(water_spinach2_solenoid_led_blynk_V33)
//V34(auto_water_spinach2_valve_V34)
//V35(manual_water_spinach2_valve_V35)
//V36(valveผักบุ้ง2=ปิดค่าเท่ากับ10 เปิดค่าเท่ากับ20เพื่อแสดงในsuperchart)
//V37(ค่าเปอร์เซนต์ดินผักบุ้ง1-water_spinach2_soil_wetness_percent)
//timer.setInterval(1400L,water_spinach2_task);
int auto_water_spinach2_valve_V34=0;
WidgetLED water_spinach2_solenoid_led_blynk_V33(V33);
int water_spinach2_soil_wetness_raw=0;
int water_spinach2_soil_wetness_percent=0;
int water_spinach2_soil_wetness_state=1;
int water_spinach2_valve_state_to_node2 ;// ปิดเปิดวาล์วน้ำรดผักบุ้ง2
int water_spinach2_valve_state_from_node2 ;// ปิดเปิดวาล์วน้ำรดผักบุ้ง2
////////////////////////////////////////////////
//10 lettuce2
//V39(lettuce2_solenoid_led_blynk_v39)
//V40(auto_lettuce2_valve_V40)
//V41(manual_lettuce2_valve_V41),
//V42(valveผักกาด2=ปิดค่าเท่ากับ10 เปิดค่าเท่ากับ20เพื่อแสดงในsuperchart)
//V43(ค่าเปอร์เซนต์ดินผักกาด2-lettuce2_soil_wetness_percent),
//   timer.setInterval(1800L,lettuce2_task)
WidgetLED lettuce2_solenoid_led_blynk_v39(V39);
int auto_lettuce2_valve_V40=0;
int lettuce2_soil_wetness_raw;
int lettuce2_soil_wetness_percent;
int lettuce2_soil_wetness_state;
int lettuce2_valve_state_to_node2;//0 คือเปิดวาล์ว 1คือปิด active low
int lettuce2_valve_state_from_node2;//0 คือเปิดวาล์ว 1คือปิด active low
///////////////////////////////////////////
//Sync blynk
//timer.setInterval(2100L,V6_sync);
//  timer.setInterval(2300L,V10_sync);
//   timer.setInterval(2200L,V16_sync);
//
void setup() {
   Serial.begin(9600);
   pinMode(fan_D1, OUTPUT);
  digitalWrite(fan_D1, 1);//low active
  pinMode(durian_valve_D3, OUTPUT);
  digitalWrite(durian_valve_D3, 1);//low active
  pinMode(vegetable_valve_D0, OUTPUT);
  digitalWrite(vegetable_valve_D0, 1);//low active
  Serial.println("ปิดวาล์วน้ำ");
  Serial.println();
  // put your setup code here, to run once:
      dht.begin(); // initialize the DHT sensor
     WiFi.mode(WIFI_STA); //เชื่อมต่อ Wifi
     WiFi.begin(ssid, password);
   delay(500);
     Serial.println("\nConnecting to WiFi");
     while ((WiFi.status() != WL_CONNECTED)&&(a<10)) {
           Serial.print("*");
           a=a+1;
           delay(500);
      }
// Initialize a NTPClient to get time
  timeClient.begin();
   delay(500);
  // Set offset time in seconds to adjust for your timezone, for example:
  // GMT +1 = 3600
  // GMT +7 = 25200
  // GMT -1 = -3600
  // GMT 0 = 0
  timeClient.setTimeOffset(25200);
  //
     configTime(timezone, dst, "pool.ntp.org", "time.nist.gov"); //ดึงเวลาจาก Server
     Serial.println("\nLoading time");
     while (!time(nullptr)) {
           Serial.print("!time(nullptr)");
           
           delay(500);
     }
     Serial.println("");
    Blynk.begin(auth, ssid, password, "oasiskit.com", 8080);  
    delay(500);
    start_ms_thisApp=millis();//เริ่มจับเวลาระบบเริ่มทำงาน
  //0  ตรวจสอบอุณหภูมิ
  Serial.println();
  Serial.println("Status\tHumidity (%)\tTemperature (C)\t(F)");
  //2 ความชื้นในดิน
    //Deifne output pins for Mux ic4051
  pinMode(MUX_A, OUTPUT);
  pinMode(MUX_B, OUTPUT);     
  pinMode(MUX_C, OUTPUT);     
  //int analogPin = A0; //ประกาศตัวแปร ให้ analogPin แทนขา analog ขาที่5
  //3 ปล่อยน้ำรดต้นไม้
  Blynk.syncVirtual(V6,V10);//updatenปุ่มออโต้ทุเรียน,ผักตามในมือถือ
  transformer_status_v19.on();
  //timer.setInterval   
   timer.setInterval(1250L, ic4051_task);
   timer.setInterval(1000L, durian_task);
   timer.setInterval(1250L, vegetable_task);
   timer.setInterval(1400L,water_spinach1_task);
   timer.setInterval(1600L,lettuce1_task);
   timer.setInterval(1500L,temp_humid_task);
   timer.setInterval(1700L,water_spinach2_task);
   timer.setInterval(1800L,lettuce2_task);
   timer.setInterval(2000L,check_time_task);
   timer.setInterval(2100L,V6_sync);
   timer.setInterval(2300L,V10_sync);
   timer.setInterval(2200L,V16_sync);
   timer.setInterval(4500L,volt_12_transformer_task);
//////////////////////////////////////////////   

}
///////


///////
void volt_12_transformer_task()
{//void volt_12_transformer_task()
  //ถ้า ภายใน5นาที ครังสุดท้าย battery วัดได้ มากกว่า 9 ถือว่าปกติ  น้อยกว่า 9 V  transformerมีปัญหา
  if ((millis()-start_5min_interval_transformer_read_ms)<300000)
  {//if ((millis()-start_5min_interval_transformer_read_ms)<300000)
    volt_12_transformer_average=(volt_12_transformer_average+volt_12_transformer_map)/2;
    Blynk.virtualWrite(V20,volt_12_transformer_raw);
    Blynk.virtualWrite(V21,volt_12_transformer_map);
    if (volt_12_transformer_average>=9)
    {//if (volt_12_transformer_average>=9)
      Blynk.setProperty(V19,"color","#01DF01");//เชียว    

    }//if (volt_12_transformer_average>=9)
    else//if (volt_12_transformer_average>=9)
    {//else if (volt_12_transformer_average>=9)
      Blynk.setProperty(V19,"color","#D3435C");//สีแดง          
    }//elseif (volt_12_transformer_average>=9)
  }//if ((millis()-start_5min_interval_transformer_read_ms)<300000)
  else//if ((millis()-start_5min_interval_transformer_read_ms)<300000)
  {//else if ((millis()-start_5min_interval_transformer_read_ms)<300000)
    volt_12_transformer_average=volt_12_transformer_map;   
    start_5min_interval_transformer_read_ms =millis();
  }//else if ((millis()-start_5min_interval_transformer_read_ms)<300000)

}//void volt_12_transformer_task()
///////
void V6_sync()
{
  Blynk.syncVirtual(V6);
}
///////

///////
void V10_sync()
{
  Blynk.syncVirtual(V10);
}
///////

///////
void V16_sync()
{
  Blynk.syncVirtual(V16);
}
///////
void ic4051_task()//ปัองกันการกำหนดที่พร้อมกัน ทำให้ analogpin สับสนได้
{
  changeMux(LOW, LOW, LOW);//channel 0 -ทุเรียน
  delay(2000);
  durian_soil_dryness = analogRead(analogPin); //Value of the sensor connected Option 0 pin of Mux
  durian_soil_wetness_percent = map( durian_soil_dryness, 1024, 0, 0, 100 );
  Serial.print("durian_soil_dryness=");
  Serial.println(durian_soil_dryness);
  Serial.print("durian_soil_wetness_percent=");
  Serial.println(durian_soil_wetness_percent);
  delay(2000);
  changeMux(LOW, LOW, HIGH);//channel 1-ผัก
  delay(2000);
  vegetable_soil_wetness = analogRead(analogPin); //Value of the sensor connected Option 1 pin of Mux
  vegetable_soil_wetness_percent = map( vegetable_soil_wetness, 0, 1024, 0, 100 );
  Serial.print("vegetable_soil_wetness=");
  Serial.println(vegetable_soil_wetness);
  Serial.print("vegetable_soil_wetness_percent=");
  Serial.println(vegetable_soil_wetness_percent);
  delay(2000);
////////////////////////////////
 changeMux(LOW, HIGH, LOW);//channel 2-วัดไฟ12V
  delay(2000);
//  last_transformer_read_ms=millis();
 volt_12_transformer_raw = analogRead(analogPin); //Value of the sensor connected Option 1 pin of Mux
  volt_12_transformer_map = map( volt_12_transformer_raw, 0, 1024, 0, 12 );
  delay(2000);
////////////////////////////////

 changeMux(LOW, HIGH, HIGH);//channel 3-แปลงผักบุ้ง1
  delay(2000);
  water_spinach1_soil_wetness_raw = analogRead(analogPin); //Value of the sensor connected Option 1 pin of Mux
  water_spinach1_soil_wetness_percent = map( water_spinach1_soil_wetness_raw, 0, 1024, 0, 100 );
  delay(2000);
////////////////////////////////
 changeMux(HIGH, LOW, LOW);//channel 4-แปลงผักกาด1
  delay(2000);
  
  lettuce1_soil_wetness_raw = analogRead(analogPin); //Value of the sensor connected Option 1 pin of Mux
  lettuce1_soil_wetness_percent = map(lettuce1_soil_wetness_raw, 0, 1024, 0, 100 );
  delay(2000);
////////////////////////////////
 changeMux(HIGH, LOW, HIGH);//channel 5-แปลงผักบุ้ง2
  delay(2000);
  water_spinach2_soil_wetness_raw = analogRead(analogPin); //Value of the sensor connected Option 1 pin of Mux
  water_spinach2_soil_wetness_percent = map( water_spinach2_soil_wetness_raw, 0, 1024, 0, 100 );
  delay(2000);
////////////////////////////////
 changeMux(HIGH, HIGH, LOW);//channel 6-แปลงผักกาด2
  delay(2000);
  
  lettuce2_soil_wetness_raw = analogRead(analogPin); //Value of the sensor connected Option 1 pin of Mux
  lettuce2_soil_wetness_percent = map(lettuce2_soil_wetness_raw, 0, 1024, 0, 100 );
  delay(2000);
   
}
///////////////////////////
//ic4051
void changeMux(int c, int b, int a) {
  digitalWrite(MUX_A, a);
  digitalWrite(MUX_B, b);
  digitalWrite(MUX_C, c);
}
//////////////////
void durian_task()
{
  Blynk.virtualWrite(V2, durian_soil_wetness_percent );
  Serial.print(" ความชื้นในดินต้นทุเรียน = "); // พิมพ์ข้อมความส่งเข้าคอมพิวเตอร์ "durian_soil_wetness_percent  = "
  Serial.println(durian_soil_wetness_percent ); // พิมพ์ค่าของตัวแปร durian_soil_wetness_percent 
  if (auto_durian_valve_V6==1)
  {//if (auto_durian_valve_V6==1)
  if (durian_soil_wetness_percent  <50) { 
   Serial.println(" ทุเรียน  ดินแห้ง"); // พิมพ์ค่าของตัวแปร durian_soil_wetness_percent 
   digitalWrite(durian_valve_D3, 0);//active low
   Serial.println("เปิดวาล์วน้ำ");
   solenoid_durian_led_blynk_v7.on();
   Blynk.virtualWrite(V9,string_open);
 //  Blynk.virtualWrite(V8,"onBackColor");//งงมากๆๆ
//   Blynk.setProperty(V8,"onLabel","กำลัง เปิด");
   delay(100);
  }
  else 
  {
   Serial.println(" ทุเรียน  ดินชื้น"); // พิมพ์ค่าของตัวแปร durian_soil_wetness_percent 
   digitalWrite(durian_valve_D3, 1);//active low
   solenoid_durian_led_blynk_v7.off();
   Blynk.virtualWrite(V9,string_close);
   Blynk.virtualWrite(V8,"offBackColor");//งงมากๆๆ
   Blynk.setProperty(V8,"offLabel","กำลัง ปิด");
   Serial.println("ปิดวาล์วน้ำ");
  }
    
  }//if (auto_durian_valve_V6==1)
  else//if (auto_durian_valve_V6==1)
  {//else if (auto_durian_valve_V6==1)
    //แจ้งใน log V9 ตอนนี้ออโต้ไม่ทำงาน
      Blynk.virtualWrite(V9,"ตอนนี้เป็นแมนวล เปลี่ยนเป็นออโต้ด้วย");
  }//else if (auto_durian_valve_V6==1)
}  

//////////////////////////////////////////////


void vegetable_task()
{//void vegetable_task()
    Blynk.virtualWrite(V14,vegetable_soil_wetness_percent);
   if (auto_vegetable_valve_V10==1)
   {//if (auto_vegetable_valve_V10==1)
    if (vegetable_soil_wetness_percent <50 ) 
    { 
     digitalWrite(vegetable_valve_D0, 0);//active low
     Blynk.virtualWrite(V13,string_open);
     vegetable_valve_D0_state=0;
     solenoid_vegetable_led_blynk_v12.on();
     Blynk.virtualWrite(V13,string_open);
//     Blynk.virtualWrite(V11,"onBackColor");//งงมากๆๆ
//     Blynk.setProperty(V11,"onLabel","กำลัง เปิด");
     Serial.println(" ผัก  ดินแห้ง"); // พิมพ์ค่าของตัวแปร val
    }
    else  
    {
     Serial.println(" ผัก   ดินชื้น"); // พิมพ์ค่าของตัวแปร val
     digitalWrite(vegetable_valve_D0, 1);//active low
     vegetable_valve_D0_state=1;
     Blynk.virtualWrite(V13,string_close);
     solenoid_vegetable_led_blynk_v12.off();  
     Blynk.virtualWrite(V11,"offBackColor");//งงมากๆๆ
     Blynk.setProperty(V11,"offLabel","กำลัง ปิด");
    }
    }//if (auto_vegetable_valve_V10==1)
    else//if (auto_vegetable_valve_V10==1)
    {//else if (auto_vegetable_valve_V10==1)
     //แจ้งใน log V13 ตอนนี้ออโต้ไม่ทำงาน
     Blynk.virtualWrite(V13,"ตอนนี้กำลังในโหมดแมนวล,ระบบออโต้ผักไม่ทำงาน");
     
    }//else if (auto_vegetable_valve_V10==1)
}//void vegetable_task()


9-10ตค65
โค้ด Node1 (part2/3)

  
//////////////////
//7 ปล่อยน้ำรดผักบุ้ง1
//V22(water_spinach1_solenoid_led_blynk_v22)
//V23(auto_water_spinach1_valve_V23),V24(manual_water_spinach1_valve_V24),
//V25(valveผักบุ้ง1=ปิดค่าเท่ากับ10 เปิดค่าเท่ากับ20เพื่อแสดงในsuperchart)
//V26(ค่าเปอร์เซนต์ดินผักบุ้ง1-water_spinach1_soil_wetness_percent)int water_spinach1_soil_wetness_raw = 0;
//V27(log ผักบุ้งและผักกาด)
//timer.setInterval(1400L,water_spinach1_task);
//int water_spinach1_soil_wetness_percent = 0;
//int water_spinach1_soil_wetness_state=0;//0 คือดินแห้ง 1คือดินชื้น
//bool water_spinach1_valve_state_from_node2=1;//1=คือปิด active low
//WidgetLED water_spinach1_solenoid_led_blynk_v22(V22);
//int auto_water_spinach1_valve_V23=0;

void water_spinach1_task()
{//void water_spinach1_task()
  Blynk.virtualWrite(V26,water_spinach1_soil_wetness_percent);
  Serial.print(" ดินผักบุ้ง1 ชื้น(%)="); // พิมพ์ค่าของตัวแปร val
  Serial.println(water_spinach1_soil_wetness_percent); // พิมพ์ค่าของตัวแปร val
  if (auto_water_spinach1_valve_V23==1)
   {//if (auto_water_spinach1_valve_V23==1)
    if (water_spinach1_soil_wetness_percent <50 ) 
     { //if (water_spinach1_soil_wetness_percent <50 ) 
      Serial.println(" ผักบุ้ง1  ดินแห้ง"); // พิมพ์ค่าของตัวแปร val
      water_spinach1_soil_wetness_state=0;//0 คือดินแห้ง 1คือดินชื้น
      water_spinach1_valve_state_to_node2=0;//0 คือเปิด active low
      doc_to_node2["v5"] = water_spinach1_valve_state_to_node2;      
      serializeJson(doc_to_node2, order_from_node1);
      Serial.println(order_from_node1); 
      order_from_node1 ="";delay(500);
      if(water_spinach1_valve_state_from_node2==0)//0คือเปิดวาล์ว
      {//if(water_spinach1_valve_state_from_node2==0)//0คือเปิดวาล์ว
       water_spinach1_solenoid_led_blynk_v22.on();
       Blynk.virtualWrite(V25,20);//ปิดค่าเท่ากับ10 เปิดค่าเท่ากับ20เพื่อแสดงในsuperchart
      }//if(water_spinach1_valve_state_from_node2==0)//0คือเปิดวาล์ว
     }//if (water_spinach1_soil_wetness_percent <50 ) 
     else  //if (water_spinach1_soil_wetness_percent <50 ) 
     {//else //if (water_spinach1_soil_wetness_percent <50 ) 
      Serial.println(" ผักบุ้ง1 ดินชื้น"); // พิมพ์ค่าของตัวแปร val
      water_spinach1_soil_wetness_state=1;//0 คือดินแห้ง 1คือดินชื้น
      water_spinach1_valve_state_to_node2=1;//1 คือปิด active low
      doc_to_node2["v5"] = water_spinach1_valve_state_to_node2;      
      serializeJson(doc_to_node2, order_from_node1);
      Serial.println(order_from_node1); 
      order_from_node1 ="";delay(500);
      if(water_spinach1_valve_state_from_node2==1)//0คือเปิดวาล์ว
      {//if(water_spinach1_valve_state_from_node2==1)//0คือเปิดวาล์ว
       water_spinach1_solenoid_led_blynk_v22.off();
       Blynk.virtualWrite(V25,10);//ปิดค่าเท่ากับ10 เปิดค่าเท่ากับ20เพื่อแสดงในsuperchart
       Blynk.virtualWrite(V24,"offBackColor");//งงมากๆๆ
       Blynk.setProperty(V24,"offLabel","กำลัง ปิด");
      }//if(water_spinach1_valve_state_from_node2==1)//0คือเปิดวาล์ว
      
     }//else //if (water_spinach1_soil_wetness_percent <50 ) 
    }//if (auto_water_spinach1_valve_V23==1)
    else//if (auto_water_spinach1_valve_V23==1)
    {//else //if (auto_water_spinach1_valve_V23==1)//แจ้งใน log V27 ตอนนี้ออโต้ไม่ทำงาน
     Blynk.virtualWrite(V27,"ตอนนี้กำลังในโหมดแมนวล,ระบบออโต้ผักบุ้ง1ไม่ทำงาน");
     
    }//else //if (auto_water_spinach1_valve_V23==1)
  
}//void water_spinach1_task()
/////////////////////
//V28(lettuce1_solenoid_led_blynk_v28)
//V29(auto_lettuce1_valve_V29),V30(manual_lettuce1_valve_V30),
//V31(valveผักกาด1=ปิดค่าเท่ากับ10 เปิดค่าเท่ากับ20เพื่อแสดงในsuperchart)
//V32(ค่าเปอร์เซนต์ดินผักกาด1-lettuce1_soil_wetness_percent),
//timer.setInterval(1400L,lettuce1_task);
//int lettuce1_soil_wetness_raw;
//int lettuce1_soil_wetness_percent;
//int  lettuce1_soil_wetness_state=1;
//WidgetLED lettuce1_solenoid_led_blynk_v28(V28);
//int auto_lettuce1_valve_V29=0;
void lettuce1_task()
{//void lettuce1_task()
  Blynk.virtualWrite(V32,lettuce1_soil_wetness_percent);
  Serial.print(" ดินผักกาด1 ความชื้น(%)="); // พิมพ์ค่าของตัวแปร val
  Serial.println(lettuce1_soil_wetness_percent); // พิมพ์ค่าของตัวแปร val
  if (auto_lettuce1_valve_V29==1)
   {//if (auto_lettuce1_valve_V23==1)
    if (lettuce1_soil_wetness_percent <50 ) 
     { //if (lettuce1_soil_wetness_percent <50 ) 
      Serial.println(" ผักกาด1  ดินแห้ง"); // พิมพ์ค่าของตัวแปร val
      lettuce1_soil_wetness_state=0;//0 คือดินแห้ง 1คือดินชื้น
      lettuce1_valve_state_to_node2=0;
      doc_to_node2["v6"] = lettuce1_valve_state_to_node2;
      serializeJson(doc_to_node2, order_from_node1);
      Serial.println(order_from_node1); 
      order_from_node1 = "";
      delay(500);
      if(lettuce1_valve_state_from_node2==0)//0คือเปิดวาล์ว
      {//if(lettuce1_valve_state_from_node2==0)//0คือเปิดวาล์ว
        lettuce1_solenoid_led_blynk_v28.on();
        Blynk.virtualWrite(V31,20);//ปิดค่าเท่ากับ10 เปิดค่าเท่ากับ20เพื่อแสดงในsuperchart
      }//if(water_spinach1_valve_state_from_node2==0)//0คือเปิดวาล์ว
     }//if (lettuce1_soil_wetness_percent <50 ) 
     else  //if (lettuce1_soil_wetness_percent <50 ) 
     {//else if (lettuce1_soil_wetness_percent <50 ) 
      Serial.println(" ผักกาด1 ดินชื้น"); // พิมพ์ค่าของตัวแปร val
      lettuce1_soil_wetness_state=1;//0 คือดินแห้ง 1คือดินชื้น
      lettuce1_valve_state_to_node2=1;
      doc_to_node2["v6"] = lettuce1_valve_state_to_node2;
      serializeJson(doc_to_node2, order_from_node1);
      Serial.println(order_from_node1); 
      order_from_node1 = "";
      delay(500);
      if(lettuce1_valve_state_from_node2==1)//0คือเปิดวาล์ว
      {//if(lettuce1_valve_state_from_node2==1)//0คือเปิดวาล์ว
       lettuce1_solenoid_led_blynk_v28.off();
       Blynk.virtualWrite(V31,10);//ปิดค่าเท่ากับ10 เปิดค่าเท่ากับ20เพื่อแสดงในsuperchart
       Blynk.virtualWrite(V30,"offBackColor");//งงมากๆๆ
       Blynk.setProperty(V30,"offLabel","กำลัง ปิด");
      }//if(lettuce1_valve_state_from_node2==1)//0คือเปิดวาล์ว
     }//else if (lettuce1_soil_wetness_percent <50 ) 
    }//if (auto_lettuce1_valve_V23==1)
    else//if (auto_lettuce1_valve_V23==1)
    {//else //if (auto_lettuce1_valve_V23==1)//แจ้งใน log V27 ตอนนี้ออโต้ไม่ทำงาน
     Blynk.virtualWrite(V27,"ตอนนี้กำลังในโหมดแมนวล,ระบบออโต้ผักกาด1ไม่ทำงาน");
    }//else //if (auto_lettuce1_valve_V23==1)
}//void lettuce1_task()
////////////////////////////////////////
//9 ปล่อยน้ำรดผักบุ้ง2
//V33(water_spinach2_solenoid_led_blynk_V33)
//V34(auto_water_spinach2_valve_V34)
//V35(manual_water_spinach2_valve_V35)
//V36(valveผักบุ้ง2=ปิดค่าเท่ากับ10 เปิดค่าเท่ากับ20เพื่อแสดงในsuperchart)
//V37(ค่าเปอร์เซนต์ดินผักบุ้ง1-water_spinach2_soil_wetness_percent)
//timer.setInterval(1400L,water_spinach2_task);
//int auto_water_spinach2_valve_V34=0;
//WidgetLED water_spinach2_solenoid_led_blynk_V33(V33);
//int water_spinach2_soil_wetness_raw=0;
//int water_spinach2_soil_wetness_percent=0;
//int water_spinach2_soil_wetness_state=1;

void water_spinach2_task()
{//void water_spinach2_task()
  Blynk.virtualWrite(V37,water_spinach2_soil_wetness_percent);
  Serial.print(" ดินผักบุ้ง2 ชื้น(%)="); // พิมพ์ค่าของตัวแปร val
  Serial.println(water_spinach2_soil_wetness_percent); // พิมพ์ค่าของตัวแปร val
  if (auto_water_spinach2_valve_V34==1)
   {//if (auto_water_spinach2_valve_V34==1)
    if (water_spinach2_soil_wetness_percent <50 )
     { //if (water_spinach2_soil_wetness_percent <50 ) 
     Serial.println(" ผักบุ้ง2  ดินแห้ง"); // พิมพ์ค่าของตัวแปร val 
      water_spinach2_soil_wetness_state=0;//0 คือดินแห้ง 1คือดินชื้น
      water_spinach2_valve_state_to_node2=0;
      doc_to_node2["v7"] = water_spinach2_valve_state_to_node2;
      serializeJson(doc_to_node2, order_from_node1);
      Serial.println(order_from_node1); 
      order_from_node1 = "";
      delay(500);
      if(water_spinach2_valve_state_from_node2==0)//0คือเปิดวาล์ว
      {//if(water_spinach2_valve_state_from_node2==0)//0คือเปิดวาล์ว
       water_spinach2_solenoid_led_blynk_V33.on();
       Blynk.virtualWrite(V36,20);//ปิดค่าเท่ากับ10 เปิดค่าเท่ากับ20เพื่อแสดงในsuperchart
      }//if(water_spinach1_valve_state_from_node2==0)//0คือเปิดวาล์ว
     }//if (water_spinach2_soil_wetness_percent <50 ) 
     else  //if (water_spinach2_soil_wetness_percent <50 ) 
     {//else if (water_spinach2_soil_wetness_percent <50 ) 
      Serial.println(" ผักบุ้ง2 ดินชื้น"); // พิมพ์ค่าของตัวแปร val
      water_spinach2_soil_wetness_state=1;//0 คือดินแห้ง 1คือดินชื้น
      water_spinach2_valve_state_to_node2=1;//1 คือปิด active low
      doc_to_node2["v7"] = water_spinach2_valve_state_to_node2;      
      serializeJson(doc_to_node2, order_from_node1);
      Serial.println(order_from_node1); 
      order_from_node1 ="";delay(500);
      if(water_spinach2_valve_state_from_node2==1)//0คือเปิดวาล์ว
      {//if(water_spinach2_valve_state_from_node2==1)//0คือเปิดวาล์ว
       water_spinach2_solenoid_led_blynk_V33.off();
       Blynk.virtualWrite(V36,10);//ปิดค่าเท่ากับ10 เปิดค่าเท่ากับ20เพื่อแสดงในsuperchart
       Blynk.virtualWrite(V35,"offBackColor");//งงมากๆๆ
       Blynk.setProperty(V35,"offLabel","กำลัง ปิด");
      }//if(water_spinach1_valve_state_from_node2==1)//0คือเปิดวาล์ว
     }//else if (water_spinach2_soil_wetness_percent <50 )
    }//if (auto_water_spinach2_valve_V34==1)
    else//if (auto_water_spinach2_valve_V34==1)
    {//else //if (auto_water_spinach2_valve_V34==1)//แจ้งใน log V27 ตอนนี้ออโต้ไม่ทำงาน
     Blynk.virtualWrite(V27,"ตอนนี้กำลังในโหมดแมนวล,ระบบออโต้ผักบุ้ง2ไม่ทำงาน");
    }//else //if (auto_water_spinach2_valve_V34==1)
}//void water_spinach2_task()
/////////////////////
//V39(lettuce2_solenoid_led_blynk_v39)
//V40(auto_lettuce2_valve_V40)
//V41(manual_lettuce2_valve_V41),
//V42(valveผักกาด2=ปิดค่าเท่ากับ10 เปิดค่าเท่ากับ20เพื่อแสดงในsuperchart)
//V43(ค่าเปอร์เซนต์ดินผักกาด2-lettuce2_soil_wetness_percent),
//   timer.setInterval(1800L,lettuce2_task)
//WidgetLED lettuce2_solenoid_led_blynk_v39(V39);
//int auto_lettuce2_valve_V40=0;
//int lettuce2_soil_wetness_raw;
//int lettuce2_soil_wetness_percent;
//int lettuce2_soil_wetness_state;
///////////////////////////////////////////
void lettuce2_task()
{//void lettuce2_task()
  Blynk.virtualWrite(V43,lettuce2_soil_wetness_percent);
  Serial.print(" ดินผักกาด2 ความชื้น(%)="); // พิมพ์ค่าของตัวแปร val
  Serial.println(lettuce2_soil_wetness_percent); // พิมพ์ค่าของตัวแปร val
  if (auto_lettuce2_valve_V40==1)
   {//if (auto_lettuce2_valve_V40==1)
    if (lettuce2_soil_wetness_percent <50 ) 
     { //if (lettuce2_soil_wetness_percent <50 ) 
      Serial.println(" ผักกาด2  ดินแห้ง"); // พิมพ์ค่าของตัวแปร val
      lettuce2_soil_wetness_state=0;//0 คือดินแห้ง 1คือดินชื้น
      lettuce2_valve_state_to_node2=0;
      doc_to_node2["v8"] = lettuce2_valve_state_to_node2;
      serializeJson(doc_to_node2, order_from_node1);
      Serial.println(order_from_node1); 
      order_from_node1 = "";
      delay(500);
      if(lettuce2_valve_state_from_node2==0)//0คือเปิดวาล์ว
      {//if(lettuce2_valve_state_from_node2==0)//0คือเปิดวาล์ว
        lettuce2_solenoid_led_blynk_v39.on();
        Blynk.virtualWrite(V42,20);//ปิดค่าเท่ากับ10 เปิดค่าเท่ากับ20เพื่อแสดงในsuperchart
      }//if(water_spinach1_valve_state_from_node2==0)//0คือเปิดวาล์ว
     }//if (lettuce2_soil_wetness_percent <50 ) 
     else  //if (lettuce2_soil_wetness_percent <50 ) 
     {//else if (lettuce2_soil_wetness_percent <50 ) 
      Serial.println(" ผักกาด2 ดินชื้น"); // พิมพ์ค่าของตัวแปร val
      lettuce2_soil_wetness_state=1;//0 คือดินแห้ง 1คือดินชื้น
      lettuce2_valve_state_to_node2=1;
      doc_to_node2["v8"] = lettuce2_valve_state_to_node2;
      serializeJson(doc_to_node2, order_from_node1);
      Serial.println(order_from_node1); 
      order_from_node1 = "";
      delay(500);
      if(lettuce2_valve_state_from_node2==1)//0คือเปิดวาล์ว
      {//if(lettuce2_valve_state_from_node2==1)//0คือเปิดวาล์ว
       lettuce2_solenoid_led_blynk_v39.off();
       Blynk.virtualWrite(V42,10);//ปิดค่าเท่ากับ10 เปิดค่าเท่ากับ20เพื่อแสดงในsuperchart
       Blynk.virtualWrite(V41,"offBackColor");//งงมากๆๆ
       Blynk.setProperty(V41,"offLabel","กำลัง ปิด");
      }//if(lettuce1_valve_state_from_node2==1)//0คือเปิดวาล์ว
     }//else if (lettuce2_soil_wetness_percent <50 ) 
    }//if (auto_lettuce2_valve_V40==1)
    else//if (auto_lettuce2_valve_V23==1)
    {//else //if (auto_lettuce2_valve_V23==1)//แจ้งใน log V27 ตอนนี้ออโต้ไม่ทำงาน
     Blynk.virtualWrite(V27,"ตอนนี้กำลังในโหมดแมนวล,ระบบออโต้ผักกาด2ไม่ทำงาน");
    
    }//else //if (auto_lettuce2_valve_V40==1)
  
}//void lettuce2_task()
///////////////////////
void check_time_task()
{
    timeClient.update();
  time_t epochTime = timeClient.getEpochTime();
delay(500);
String formattedTime = timeClient.getFormattedTime();
  Serial.print("Formatted Time: ");
  Serial.println(formattedTime);  

  currentHour = timeClient.getHours();// int currentHour อยู่ด้านบนแล้ว เพื่อประกาศเป็น global var
  Serial.print("Hour: ");
  Serial.println(currentHour);  
  currentMinute = timeClient.getMinutes();
  Serial.print("Minutes: ");
  Serial.println(currentMinute); 
   
  int currentSecond = timeClient.getSeconds();
  Serial.print("Seconds: ");
  Serial.println(currentSecond);  

  String weekDay = weekDays[timeClient.getDay()];
  Serial.print("Week Day: ");
  Serial.println(weekDay);    

  //Get a time structure
  struct tm *ptm = gmtime ((time_t *)&epochTime); 

  monthDay = ptm->tm_mday;
  Serial.print("Month day: ");
  Serial.println(monthDay);

  currentMonth = ptm->tm_mon+1;
  Serial.print("Month: ");
  Serial.println(currentMonth);

  currentMonthName = months[currentMonth-1];
  Serial.print("Month name: ");
  Serial.println(currentMonthName);

  int currentYear = ptm->tm_year+1900;
  Serial.print("Year: ");
  Serial.println(currentYear);

  //Print complete date:
  String currentDate = String(weekDay) + "-" +String(monthDay) + "-" + String(currentMonth) + "-" + String(currentYear) ;
  Serial.print("Current date: ");
  Serial.println(currentDate);
     Serial.print("current Time=");
     Serial.println(formattedTime);
  Blynk.virtualWrite(V4, currentDate);
   delay(500);
    Blynk.virtualWrite(V5, formattedTime);
   delay(500);
     string_close="|| ปิดเวลา"+String(currentHour)+":"+String(currentMinute)+","+String(monthDay) + "/" + String(currentMonth);
     string_open= "|| เปิดเวลา"+String(currentHour)+":"+String(currentMinute)+","+String(monthDay) + "/" + String(currentMonth);

     Serial.print("current Time=");
     Serial.println(formattedTime);
  Serial.print("Current date: ");
  Serial.println(currentDate);

      if (((millis()-start_ms_thisApp)/86400000) < 1)
      {
        start_thisApp_V3=int((millis()-start_ms_thisApp)/3600000);
        Blynk.virtualWrite(V3, String(start_thisApp_V3)+" ชั่วโมง");
      }
    else
     {
       if (((millis()-start_ms_thisApp)%86400000) == 0)
       {
        start_thisApp_V3=int((millis()-start_ms_thisApp)/86400000);
        Blynk.virtualWrite(V3, String(start_thisApp_V3)+" วัน");
        
       }
       else
       {
        start_thisApp_V3=int((millis()-start_ms_thisApp)/86400000)+1;
        Blynk.virtualWrite(V3, String(start_thisApp_V3)+" วัน");
        
       }
      
     }

  delay(500);
/////////////////
}
void temp_humid_task()
{
 //0  ตรวจสอบอุณหภูมิ
  humidity = dht.readHumidity(); // ดึงค่าความชื้น
  temperature = dht.readTemperature(); // ดึงค่าอุณหภูมิ
  Serial.print("ความชื้น");
  Serial.print("\t");
  Serial.print(humidity, 1);
  Serial.print("\t");
  Serial.print("อุณหภูมิ");
  Serial.println(temperature, 1);


  Blynk.virtualWrite(V0, temperature);
  Blynk.virtualWrite(V1, humidity);
  if (auto_fan_V16==1)
   {//if (auto_fan_V16==1)
     if (temperature >=38)
     {
      digitalWrite(fan_D1,0);//active low
      fan_D1_v15.on();
      fan_D1_state=0;
      Blynk.virtualWrite(V18,string_open);
     }
     else
     {
      digitalWrite(fan_D1,1);//active low
      fan_D1_v15.off();
      fan_D1_state=1;
      Blynk.virtualWrite(V18,string_close);
     }
   }//if (auto_fan_V16==1)
   else//if (auto_fan_V16==1)
   {//else if (auto_fan_V16==1)
     //แจ้งใน log V18 ตอนนี้ออโต้ไม่ทำงาน
     Blynk.virtualWrite(V18,"ตอนนี้กำลังในโหมดแมนวล,ระบบออโต้พัดลมไม่ทำงาน");
     
    
   }//else if (auto_fan_V16==1)

}
////////////////////
BLYNK_WRITE(V6) //Vbutton auto/manual วาล์วทุเรียน,auto_durian_valve_V6
{//BLYNK_WRITE(V6) //auto/manual วาล์วทุเรียน,auto_durian_valve_V6
  if (param.asInt()==1)//1=ทำงาน
  {//if (param.asInt()==1)//1=ทำงาน
    auto_durian_valve_V6=1;
    if(durian_valve_D3_state==0)
    {
     Blynk.virtualWrite(V8,"offBackColor");//งงมากๆๆ
     digitalWrite(durian_valve_D3, 1);//active low
     solenoid_durian_led_blynk_v7.off();
     Blynk.virtualWrite(V9,string_close);
     Serial.println("ปิดวาล์วน้ำ");
     durian_valve_D3_state=1;  
    }

  }//if (param.asInt()==1)//1=ทำงาน
  else//if (param.asInt()==1)//1=ทำงาน
  {//else if (param.asInt()==1)//1=ทำงาน
    auto_durian_valve_V6=0;
    
  }//else if (param.asInt()==1)//1=ทำงาน
}//BLYNK_WRITE(V6) //Vbutton auto/manual วาล์วทุเรียน,auto_durian_valve_V6
/////////////////
BLYNK_WRITE(V8) //(สวิทช์ปิด-เปิดโซลินอยด์ทุเรียน
{//BLYNK_WRITE(V8) //(สวิทช์ปิด-เปิดโซลินอยด์ทุเรียน
  if (auto_durian_valve_V6==0)
  {//if (auto_durian_valve_V6==0)
      if (param.asInt()==1)//1=ทำงาน
      {//if (param.asInt()==1)//1=ทำงาน
       digitalWrite(durian_valve_D3, 0);//active low
       durian_valve_D3_state=0;
       Serial.println("เปิดวาล์วน้ำ");
       solenoid_durian_led_blynk_v7.on();
       Blynk.virtualWrite(V9,string_open);
       Blynk.setProperty(V8,"onLabel","กำลัง เปิด");
        
      }//if (param.asInt()==1)//1=ทำงาน
      else//if (param.asInt()==1)//1=ทำงาน
      {//else if (param.asInt()==1)//1=ทำงาน
       digitalWrite(durian_valve_D3, 1);//active low
       Serial.println("ปิดวาล์วน้ำ");
       solenoid_durian_led_blynk_v7.off();
       Blynk.virtualWrite(V9,string_close);
       Blynk.virtualWrite(V8,"offBackColor");//งงมากๆๆ
       durian_valve_D3_state=1;
        
      }//else if (param.asInt()==1)//1=ทำงาน

  }//if (auto_durian_valve_V6==0)
  else//if (auto_durian_valve_V6==0)
  {//else if (auto_durian_valve_V6==0)
   //แจ้งในlog ว่า ตอนนี้เป็นออโต้ ให้เปลี่ยนเป็นแมนวลก่อน
   Blynk.virtualWrite(V9,"ตอนนี้เป็นออโต้ ให้เปลี่ยนเป็นแมนวลก่อน");
   Blynk.virtualWrite(V8,"offBackColor");//งงมากๆๆ
   Blynk.setProperty(V8,"offLabel","กำลัง ปิด");

  }//else if (auto_durian_valve_V6==0)
}//BLYNK_WRITE(V8) //(สวิทช์ปิด-เปิดโซลินอยด์ทุเรียน
/////////////////
BLYNK_WRITE(V10) //auto_vegetable_valve_V10
{ //BLYNK_WRITE(V10) //auto_vegetable_valve_V10
  if (param.asInt()==1)//1=ทำงาน
  {//if (param.asInt()==1)//1=ทำงาน
    auto_vegetable_valve_V10=1;
    if(vegetable_valve_D0_state==0)
    {
    Blynk.virtualWrite(V11,"offBackColor");//งงมากๆๆ
     digitalWrite(vegetable_valve_D0, 1);//active low
     solenoid_vegetable_led_blynk_v12.off();  
     vegetable_valve_D0_state=1;
     Blynk.virtualWrite(V13,string_close);
    }
    
  }//if (param.asInt()==1)//1=ทำงาน
  else//if (param.asInt()==1)//1=ทำงาน
  {//else if (param.asInt()==1)//1=ทำงาน
    auto_vegetable_valve_V10=0;
    
  }//else if (param.asInt()==1)//1=ทำงาน
}//BLYNK_WRITE(V10) //auto_vegetable_valve_V10
/////////////////

BLYNK_WRITE(V11) //(สวิทช์ปิด-เปิดโซลินอยด์ผัก
{//BLYNK_WRITE(V11) //(สวิทช์ปิด-เปิดโซลินอยด์ผัก
  if (auto_vegetable_valve_V10==0)
  {//if (auto_vegetable_valve_V10==0)
      if (param.asInt()==1)//1=ทำงาน
      {//if (param.asInt()==1)//1=ทำงาน
       digitalWrite(vegetable_valve_D0, 0);//active low
       Serial.println("เปิดวาล์วน้ำ");
       solenoid_vegetable_led_blynk_v12.on();
       Blynk.virtualWrite(V13,string_open);
       Blynk.setProperty(V11,"onLabel","กำลัง เปิด");

      }//if (param.asInt()==1)//1=ทำงาน
      else//if (param.asInt()==1)//1=ทำงาน
      {//else if (param.asInt()==1)//1=ทำงาน
       Blynk.virtualWrite(V11,"offBackColor");//งงมากๆๆ
       Blynk.setProperty(V11,"offLabel","กำลัง ปิด");
      digitalWrite(vegetable_valve_D0, 1);//active low
       solenoid_vegetable_led_blynk_v12.off();
       Blynk.virtualWrite(V13,string_close);
       Serial.println("ปิดวาล์วน้ำ");
        
      }//else if (param.asInt()==1)//1=ทำงาน

  }//if (auto_vegetable_valve_V10==0)
  else//if (auto_vegetable_valve_V10==0)
  {//else if (auto_vegetable_valve_V10==0)
   //แจ้งในlog ว่า ตอนนี้เป็นออโต้ ให้เปลี่ยนเป็นแมนวลก่อน
   Blynk.virtualWrite(V13,"ตอนนี้เป็นออโต้ ให้เปลี่ยนเป็นแมนวลก่อน");
   Blynk.virtualWrite(V11,"offBackColor");//งงมากๆๆ
   Blynk.setProperty(V11,"offLabel","กำลัง ปิด");

  }//else if (auto_vegetable_valve_V10==0)
}//BLYNK_WRITE(V11) //(สวิทช์ปิด-เปิดโซลินอยด์ผัก

/////////////////

9-10ตค65
โค้ด Node1 (part3/3)

BLYNK_WRITE(V16) //auto_fan_V16
{ //BLYNK_WRITE(V16) //auto_fan_V16
  if (param.asInt()==1)//1=ทำงาน
  {//if (param.asInt()==1)//1=ทำงาน
   if(fan_D1_state==0)
   {
    auto_fan_V16=1;
    Blynk.virtualWrite(V17,"offBackColor");//งงมากๆๆ
    digitalWrite(fan_D1, 1);//active low
    fan_D1_v15.off();  
    fan_D1_state=1;
    Blynk.virtualWrite(V18,string_close);
   }

  }//if (param.asInt()==1)//1=ทำงาน
  else//if (param.asInt()==1)//1=ทำงาน
  {//else if (param.asInt()==1)//1=ทำงาน
   auto_fan_V16=0;
  }//else if (param.asInt()==1)//1=ทำงาน
}//BLYNK_WRITE(V16) //auto_fan_V16
/////////////////
BLYNK_WRITE(V17) //(สวิทช์ปิด-เปิดพัดลม
{//BLYNK_WRITE(V17) //(สวิทช์ปิด-เปิดพัดลม
  if (auto_fan_V16==0)
  {//if (auto_fan_V16==0)
   if (param.asInt()==1)//1=ทำงาน
   {//if (param.asInt()==1)//1=ทำงาน
    digitalWrite(fan_D1, 0);//active low
    Serial.println("เปิดพัดลม");
    fan_D1_state=0;
    fan_D1_v15.on();
    Blynk.virtualWrite(V18,string_open);
    Blynk.setProperty(V17,"onLabel","กำลัง เปิด");

   }//if (param.asInt()==1)//1=ทำงาน
   else//if (param.asInt()==1)//1=ทำงาน
   {//else if (param.asInt()==1)//1=ทำงาน
    Blynk.virtualWrite(V17,"offBackColor");//งงมากๆๆ
    Blynk.setProperty(V17,"offLabel","กำลัง ปิด");
    digitalWrite(fan_D1, 1);//active low
    fan_D1_state=1;
    fan_D1_v15.off();
    Blynk.virtualWrite(V18,string_close);
    Serial.println("ปิดพัดลม");
   }//else if (param.asInt()==1)//1=ทำงาน
  }//if (auto_fan_V16==0)
  else//if (auto_fan_V16==0)
  {//if (auto_fan_V16==0)
   //แจ้งในlog ว่า ตอนนี้เป็นออโต้ ให้เปลี่ยนเป็นแมนวลก่อน
   Blynk.virtualWrite(V18,"ตอนนี้เป็นออโต้ ให้เปลี่ยนเป็นแมนวลก่อน");
   Blynk.virtualWrite(V17,"offBackColor");//งงมากๆๆ
   Blynk.setProperty(V17,"offLabel","กำลัง ปิด");
   digitalWrite(fan_D1, 1);//active low
    fan_D1_state=1;
    fan_D1_v15.off();
  }//if (auto_fan_V16==0)
}//BLYNK_WRITE(V17) //(สวิทช์ปิด-เปิดพัดลม
/////////////////
BLYNK_WRITE(V23) //auto_water_spinach1_valve_V23
{ //BLYNK_WRITE(V23) //auto_water_spinach1_valve_V23
  if (param.asInt()==1)//1=ทำงาน
  {//if (param.asInt()==1)//1=ทำงาน
   if(water_spinach1_valve_state_from_node2==0)
   {
    auto_water_spinach1_valve_V23=1;
    water_spinach1_solenoid_led_blynk_v22.off();  
    water_spinach1_valve_state_to_node2=1;
    doc_to_node2["v5"] = water_spinach1_valve_state_to_node2;  // Creating JSON data. Here { v1 : 28.55 }
    serializeJson(doc_to_node2, order_from_node1);
    Serial.println(order_from_node1); 
    order_from_node1 ="";delay(500);
    Blynk.virtualWrite(V25,10);//ปิดค่าเท่ากับ10 เปิดค่าเท่ากับ20เพื่อแสดงในsuperchart
    Blynk.virtualWrite(V24,"offBackColor");//งงมากๆๆ
    Blynk.setProperty(V24,"offLabel","กำลัง ปิด");
   }

  }//if (param.asInt()==1)//1=ทำงาน
  else//if (param.asInt()==1)//1=ทำงาน
  {//else if (param.asInt()==1)//1=ทำงาน
   auto_water_spinach1_valve_V23=0;
  }//else if (param.asInt()==1)//1=ทำงาน
}//BLYNK_WRITE(V23) //auto_water_spinach1_valve_V23
/////////////////

BLYNK_WRITE(V24) //(สวิทช์ปิด-เปิดโซลินอยด์ผักบุ้ง1
{//BLYNK_WRITE(V24) //(สวิทช์ปิด-เปิดโซลินอยด์ผักบุ้ง1
  if (auto_water_spinach1_valve_V23==0)
  {//if (auto_water_spinach1_valve_V23==0)
      if (param.asInt()==1)//1=ทำงาน
      {//if (param.asInt()==1)//1=ทำงาน
       water_spinach1_valve_state_to_node2=0;
       doc_to_node2["v5"] = water_spinach1_valve_state_to_node2;  // Creating JSON data. Here { v1 : 28.55 }
       serializeJson(doc_to_node2, order_from_node1);
       Serial.println(order_from_node1); 
       order_from_node1 ="";delay(500);
       if(water_spinach1_valve_state_from_node2==0)
       {//if(water_spinach1_valve_state_from_node2==0)
        Serial.println("เปิดวาล์วน้ำผักบุ้ง1");
        water_spinach1_solenoid_led_blynk_v22.on();
        Blynk.virtualWrite(V25,20);//ปิดค่าเท่ากับ10 เปิดค่าเท่ากับ20เพื่อแสดงในsuperchart
        Blynk.setProperty(V24,"onLabel","กำลัง เปิด");
       }//if(water_spinach1_valve_state_from_node2==0)

      }//if (param.asInt()==1)//1=ทำงาน
      else//if (param.asInt()==1)//1=ทำงาน
      {//else if (param.asInt()==1)//1=ทำงาน
       water_spinach1_valve_state_to_node2=1;
       doc_to_node2["v5"] = water_spinach1_valve_state_to_node2;  // Creating JSON data. Here { v1 : 28.55 }
       serializeJson(doc_to_node2, order_from_node1);
       Serial.println(order_from_node1); 
       order_from_node1 ="";delay(500);
       if(water_spinach1_valve_state_from_node2==1)
       {//if(water_spinach1_valve_state_from_node2==1)
        Serial.println("ปิดวาล์วน้ำผักบุ้ง1");
        water_spinach1_solenoid_led_blynk_v22.off();
        Blynk.virtualWrite(V25,10);//ปิดค่าเท่ากับ10 เปิดค่าเท่ากับ20เพื่อแสดงในsuperchart
        Blynk.virtualWrite(V24,"offBackColor");//งงมากๆๆ
        Blynk.setProperty(V24,"offLabel","กำลัง ปิด");
       }//if(water_spinach1_valve_state_from_node2==0)
      }//else if (param.asInt()==1)//1=ทำงาน
  }//if (auto_water_spinach1_valve_V23==0)
  else//if (auto_water_spinach1_valve_V23==0)
  {//else if (auto_water_spinach1_valve_V23==0)
   //แจ้งในlog ว่า ตอนนี้เป็นออโต้ ให้เปลี่ยนเป็นแมนวลก่อน
   Blynk.virtualWrite(V27,"ตอนนี้เป็นออโต้ ให้เปลี่ยนเป็นแมนวลก่อน");
   Blynk.virtualWrite(V24,"offBackColor");//งงมากๆๆ
   Blynk.setProperty(V24,"offLabel","กำลัง ปิด");
  }//else if (auto_water_spinach1_valve_V23==0)
}//BLYNK_WRITE(V24) //(สวิทช์ปิด-เปิดโซลินอยด์ผักบุ้ง1
/////////////////
//8  lettuce1_task
//V28(lettuce1_solenoid_led_blynk_v28)
//V29(auto_lettuce1_valve_V29),V30(manual_lettuce1_valve_V30),
//V31(valveผักกาด1=ปิดค่าเท่ากับ10 เปิดค่าเท่ากับ20เพื่อแสดงในsuperchart)
//V32(ค่าเปอร์เซนต์ดินผักกาด1-lettuce1_soil_wetness_percent),
//timer.setInterval(1400L,lettuce1_task);
//int lettuce1_soil_wetness_raw,lettuce1_soil_wetness_state;
//int lettuce1_soil_wetness_percent;
//int lettuce1_valve_state_to_node2;
//int lettuce1_valve_state_from_node2 ;// ปิดเปิดวาล์วน้ำรดผักกาด1
//WidgetLED lettuce1_solenoid_led_blynk_v28(V28);
//int auto_lettuce1_valve_V29=0;

BLYNK_WRITE(V29) //auto_lettuce1_valve_V29
{ //BLYNK_WRITE(V29) //auto_lettuce1_valve_V29
  if (param.asInt()==1)//1=ทำงาน
  {//if (param.asInt()==1)//1=ทำงาน
   if(lettuce1_valve_state_from_node2==0)
   {
    auto_lettuce1_valve_V29=1;
    lettuce1_solenoid_led_blynk_v28.off();  
    lettuce1_valve_state_to_node2=1;
    doc_to_node2["v6"] = lettuce1_valve_state_to_node2;  // Creating JSON data. Here { v1 : 28.55 }
    serializeJson(doc_to_node2, order_from_node1);
    Serial.println(order_from_node1); 
    order_from_node1 ="";delay(500);
    Blynk.virtualWrite(V31,10);//ปิดค่าเท่ากับ10 เปิดค่าเท่ากับ20เพื่อแสดงในsuperchart
    Blynk.virtualWrite(V30,"offBackColor");//งงมากๆๆ
    Blynk.setProperty(V30,"offLabel","กำลัง ปิด");
   }

  }//if (param.asInt()==1)//1=ทำงาน
  else//if (param.asInt()==1)//1=ทำงาน
  {//else if (param.asInt()==1)//1=ทำงาน
   auto_lettuce1_valve_V29=0;
  }//else if (param.asInt()==1)//1=ทำงาน
}//BLYNK_WRITE(V29) //auto_lettuce1_valve_V29
/////////////////
BLYNK_WRITE(V30) //(สวิทช์ปิด-เปิดโซลินอยด์ผักกาด1
{//BLYNK_WRITE(V30) //(สวิทช์ปิด-เปิดโซลินอยด์ผักกาด1
  if (auto_lettuce1_valve_V29==0)
  {//if (auto_auto_lettuce1_valve_V29==0)
      if (param.asInt()==1)//1=ทำงาน
      {//if (param.asInt()==1)//1=ทำงาน
       lettuce1_valve_state_to_node2=0;
       doc_to_node2["v6"] = lettuce1_valve_state_to_node2;  // Creating JSON data. Here { v1 : 28.55 }
       serializeJson(doc_to_node2, order_from_node1);
       Serial.println(order_from_node1); 
       order_from_node1 ="";delay(500);
       if(lettuce1_valve_state_from_node2==0)
       {//if(lettuce1_valve_state_from_node2==0)
        Serial.println("เปิดวาล์วน้ำผักกาด1");
        lettuce1_solenoid_led_blynk_v28.on();
        Blynk.virtualWrite(V31,20);//ปิดค่าเท่ากับ10 เปิดค่าเท่ากับ20เพื่อแสดงในsuperchart
        Blynk.setProperty(V30,"onLabel","กำลัง เปิด");
       }//if(water_spinach1_valve_state_from_node2==0)

      }//if (param.asInt()==1)//1=ทำงาน
      else//if (param.asInt()==1)//1=ทำงาน
      {//else if (param.asInt()==1)//1=ทำงาน
       lettuce1_valve_state_to_node2=1;
       doc_to_node2["v6"] = lettuce1_valve_state_to_node2;  // Creating JSON data. Here { v1 : 28.55 }
       serializeJson(doc_to_node2, order_from_node1);
       Serial.println(order_from_node1); 
       order_from_node1 ="";delay(500);
       if(lettuce1_valve_state_from_node2==1)
       {//if(lettuce1_valve_state_from_node2==1)
        Serial.println("ปิดวาล์วน้ำผักกาด1");
        lettuce1_solenoid_led_blynk_v28.off();
        Blynk.virtualWrite(V31,10);//ปิดค่าเท่ากับ10 เปิดค่าเท่ากับ20เพื่อแสดงในsuperchart
        Blynk.virtualWrite(V30,"offBackColor");//งงมากๆๆ
        Blynk.setProperty(V30,"offLabel","กำลัง ปิด");
       }//if(lettuce1_valve_state_from_node2==1)
      }//else if (param.asInt()==1)//1=ทำงาน
  }//if (auto_lettuce1_valve_V29==0)
  else//if (auto_lettuce1_valve_V29==0)
  {//else if (auto_lettuce1_valve_V29==0)
   //แจ้งในlog ว่า ตอนนี้เป็นออโต้ ให้เปลี่ยนเป็นแมนวลก่อน
   Blynk.virtualWrite(V27,"ตอนนี้เป็นออโต้ ให้เปลี่ยนเป็นแมนวลก่อน");
   Blynk.virtualWrite(V30,"offBackColor");//งงมากๆๆ
   Blynk.setProperty(V30,"offLabel","กำลัง ปิด");
  }//else if (auto_lettuce1_valve_V29==0)
}//BLYNK_WRITE(V30) //(สวิทช์ปิด-เปิดโซลินอยด์ผักกาด1
/////////
//9 ปล่อยน้ำรดผักบุ้ง2
//V33(water_spinach2_solenoid_led_blynk_V33)
//V34(auto_water_spinach2_valve_V34)
//V35(manual_water_spinach2_valve_V35)
//V36(valveผักบุ้ง2=ปิดค่าเท่ากับ10 เปิดค่าเท่ากับ20เพื่อแสดงในsuperchart)
//V37(ค่าเปอร์เซนต์ดินผักบุ้ง1-water_spinach2_soil_wetness_percent)
//timer.setInterval(1400L,water_spinach2_task);
//V38(water_spinach2_solenoid_led_blynk_V33);
//int auto_water_spinach2_valve_V34=0;
//WidgetLED water_spinach2_solenoid_led_blynk_V33(V38);
//int water_spinach2_soil_wetness_raw=0;
//int water_spinach2_soil_wetness_percent=0;
//int water_spinach2_soil_wetness_state=1;
//int water_spinach2_valve_state_to_node2 ;// ปิดเปิดวาล์วน้ำรดผักบุ้ง2
//int water_spinach2_valve_state_from_node2 ;// ปิดเปิดวาล์วน้ำรดผักบุ้ง2
////////////////////////////////////////////////
BLYNK_WRITE(V35) //(สวิทช์ปิด-เปิดโซลินอยด์ผักบุ้ง2
{//BLYNK_WRITE(V35) //(สวิทช์ปิด-เปิดโซลินอยด์ผักบุ้ง2
  if (auto_water_spinach2_valve_V34==0)
  {//if (auto_water_spinach2_valve_V34==0)
   if (param.asInt()==1)//1=ทำงาน
   {//if (param.asInt()==1)//1=ทำงาน
     water_spinach2_valve_state_to_node2=0;
     doc_to_node2["v7"] = water_spinach2_valve_state_to_node2;  // Creating JSON data. Here { v1 : 28.55 }
     serializeJson(doc_to_node2, order_from_node1);
     order_from_node1 ="";delay(500);
     if(water_spinach2_valve_state_from_node2==0)
     {//if(water_spinach2_valve_state_from_node2==0)
      Serial.println("เปิดวาล์วน้ำผักบุ้ง2");
      water_spinach2_solenoid_led_blynk_V33.on();
      Blynk.virtualWrite(V36,20);//ปิดค่าเท่ากับ10 เปิดค่าเท่ากับ20เพื่อแสดงในsuperchart
      Blynk.setProperty(V35,"onLabel","กำลัง เปิด");
     }//if(water_spinach1_valve_state_from_node2==0)
   }//if (param.asInt()==1)//1=ทำงาน
   else//if (param.asInt()==1)//1=ทำงาน
   {//else if (param.asInt()==1)//1=ทำงาน
    water_spinach2_valve_state_to_node2=1;
    doc_to_node2["v7"] = water_spinach2_valve_state_to_node2;  // Creating JSON data. Here { v1 : 28.55 }
    serializeJson(doc_to_node2, order_from_node1);
    Serial.println(order_from_node1); 
    order_from_node1 ="";delay(500);
    if(water_spinach2_valve_state_from_node2==1)
    {//if(water_spinach2_valve_state_from_node2==1)
     Serial.println("ปิดวาล์วน้ำผักบุ้ง2");
     water_spinach2_solenoid_led_blynk_V33.off();
     Blynk.virtualWrite(V36,10);//ปิดค่าเท่ากับ10 เปิดค่าเท่ากับ20เพื่อแสดงในsuperchart
     Blynk.virtualWrite(V35,"offBackColor");//งงมากๆๆ
     Blynk.setProperty(V35,"offLabel","กำลัง ปิด");
    }//if(water_spinach2_valve_state_from_node2==1)
   }//else if (param.asInt()==1)//1=ทำงาน
  }//if (auto_water_spinach2_valve_V34==0)
  else//if (auto_water_spinach2_valve_V34==0)
  {//else if (auto_water_spinach2_valve_V34==0)
   //แจ้งในlog ว่า ตอนนี้เป็นออโต้ ให้เปลี่ยนเป็นแมนวลก่อน
   Blynk.virtualWrite(V27,"ตอนนี้เป็นออโต้ ให้เปลี่ยนเป็นแมนวลก่อน");
   Blynk.virtualWrite(V35,"offBackColor");//งงมากๆๆ
   Blynk.setProperty(V35,"offLabel","กำลัง ปิด");
  }//else//if (auto_water_spinach2_valve_V34==0)
}//BLYNK_WRITE(V35) //(สวิทช์ปิด-เปิดโซลินอยด์ผักบุ้ง2
/////////////////////////////////////////////////////
//10 lettuce2
//V39(lettuce2_solenoid_led_blynk_v39)
//V40(auto_lettuce2_valve_V40)
//V41(manual_lettuce2_valve_V41),
//V42(valveผักกาด2=ปิดค่าเท่ากับ10 เปิดค่าเท่ากับ20เพื่อแสดงในsuperchart)
//V43(ค่าเปอร์เซนต์ดินผักกาด2-lettuce2_soil_wetness_percent),
//   timer.setInterval(1800L,lettuce2_task)
//WidgetLED lettuce2_solenoid_led_blynk_v39(V39);
//int auto_lettuce2_valve_V40=0;
//int lettuce2_soil_wetness_raw;
//int lettuce2_soil_wetness_percent;
//int lettuce2_soil_wetness_state;
//int lettuce2_valve_state_to_node2;//0 คือเปิดวาล์ว 1คือปิด active low
//int lettuce2_valve_state_from_node2;//0 คือเปิดวาล์ว 1คือปิด active low
BLYNK_WRITE(V40) //auto_lettuce2_valve_V40
{ //BLYNK_WRITE(V40) //auto_lettuce2_valve_V40
  if (param.asInt()==1)//1=ทำงาน
  {//if (param.asInt()==1)//1=ทำงาน
   if(lettuce2_valve_state_from_node2==0)
   {// if(lettuce2_valve_state_from_node2==0)
    auto_lettuce2_valve_V40=1;
    lettuce2_valve_state_to_node2=1;
    doc_to_node2["v8"] = lettuce2_valve_state_to_node2;  // Creating JSON data. Here { v1 : 28.55 }
    serializeJson(doc_to_node2, order_from_node1);
    Serial.println(order_from_node1); 
    order_from_node1 ="";delay(500);
    if(lettuce2_valve_state_from_node2==1)
    {
     lettuce2_solenoid_led_blynk_v39.off() ;
     Blynk.virtualWrite(V42,10);//ปิดค่าเท่ากับ10 เปิดค่าเท่ากับ20เพื่อแสดงในsuperchart
     Blynk.virtualWrite(V41,"offBackColor");//งงมากๆๆ
     Blynk.setProperty(V41,"offLabel","กำลัง ปิด");
    }
   }// if(lettuce2_valve_state_from_node2==0)
  }//if (param.asInt()==1)//1=ทำงาน
  else//if (param.asInt()==1)//1=ทำงาน
  {//else if (param.asInt()==1)//1=ทำงาน
   auto_lettuce2_valve_V40=1;
  }//else if (param.asInt()==1)//1=ทำงาน
}//BLYNK_WRITE(V40) //auto_lettuce2_valve_V40
/////////////////
BLYNK_WRITE(V41) //(สวิทช์ปิด-เปิดโซลินอยด์ผักกาด2
{//BLYNK_WRITE(V41) //(สวิทช์ปิด-เปิดโซลินอยด์ผักกาด2
 if (auto_lettuce2_valve_V40==0)
 {//if (auto_lettuce2_valve_V40==0)
  if (param.asInt()==1)//1=ทำงาน
  {//if (param.asInt()==1)//1=ทำงาน
   lettuce2_valve_state_to_node2=0;
   doc_to_node2["v8"] = lettuce2_valve_state_to_node2;  // Creating JSON data. Here { v1 : 28.55 }
   serializeJson(doc_to_node2, order_from_node1);
   Serial.println(order_from_node1); 
   order_from_node1 ="";delay(500);
   if(lettuce2_valve_state_from_node2==0)
   {//if(lettuce2_valve_state_from_node2==0)
    Serial.println("เปิดวาล์วน้ำผักกาด2");
    lettuce2_solenoid_led_blynk_v39.on();
    Blynk.virtualWrite(V42,20);//ปิดค่าเท่ากับ10 เปิดค่าเท่ากับ20เพื่อแสดงในsuperchart
    Blynk.setProperty(V41,"onLabel","กำลัง เปิด");
   }//if(lettuce2_valve_state_from_node2==0)
  }//if (param.asInt()==1)//1=ทำงาน
  else//if (param.asInt()==1)//1=ทำงาน
  {//else if (param.asInt()==1)//1=ทำงาน
   lettuce2_valve_state_to_node2=1;
   doc_to_node2["v8"] = lettuce2_valve_state_to_node2;  // Creating JSON data. Here { v1 : 28.55 }
   serializeJson(doc_to_node2, order_from_node1);
   Serial.println(order_from_node1); 
   order_from_node1 ="";delay(500);
   if(lettuce2_valve_state_from_node2==1)
   {//if(lettuce1_valve_state_from_node2==1)
    Serial.println("ปิดวาล์วน้ำผักกาด2");
    lettuce2_solenoid_led_blynk_v39.off();
    Blynk.virtualWrite(V42,10);//ปิดค่าเท่ากับ10 เปิดค่าเท่ากับ20เพื่อแสดงในsuperchart
    Blynk.virtualWrite(V41,"offBackColor");//งงมากๆๆ
    Blynk.setProperty(V41,"offLabel","กำลัง ปิด");
   }//if(lettuce1_valve_state_from_node2==1)
   }//else if (param.asInt()==1)//1=ทำงาน
 }//if (auto_lettuce2_valve_V40==0)
 else//if (auto_lettuce2_valve_V40==0)
 {//else //if (auto_lettuce2_valve_V40==0)
  //แจ้งในlog ว่า ตอนนี้เป็นออโต้ ให้เปลี่ยนเป็นแมนวลก่อน
  Blynk.virtualWrite(V27,"ตอนนี้เป็นออโต้ ให้เปลี่ยนเป็นแมนวลก่อน");
  Blynk.virtualWrite(V41,"offBackColor");//งงมากๆๆ
  Blynk.setProperty(V41,"offLabel","กำลัง ปิด");
 }//else //if (auto_lettuce2_valve_V40==0)
}//BLYNK_WRITE(V41) //(สวิทช์ปิด-เปิดโซลินอยด์ผักกาด2
/////////
void loop() {
//String info_from_node2;
//StaticJsonDocument<256> doc_from_node2;
if (Serial.available() > 0) 
{
  info_from_node2 = Serial.readStringUntil('\n');
DeserializationError error = deserializeJson(doc_from_node2, info_from_node2);
 if (!error) {
    Serial.print("info_from_node2 : ");
    Serial.println(info_from_node2);
    water_spinach1_valve_state_from_node2=doc_to_node2["v9"] ;  // Creating JSON data. Here { v1 : 28.55 }
    lettuce1_valve_state_from_node2=doc_to_node2["v10"] ;
    water_spinach2_valve_state_from_node2=doc_to_node2["v11"] ;
    lettuce2_valve_state_from_node2=doc_to_node2["v12"] ;
    Serial.print("(void loop)water_spinach1_valve_state_from_node2=");
    Serial.println(water_spinach1_valve_state_from_node2);
    Serial.print("(void loop)lettuce1_valve_state_from_node2=");
    Serial.println(lettuce1_valve_state_from_node2);
    Serial.print("(void loop)water_spinach2_valve_state_from_node2=");
    Serial.println(water_spinach2_valve_state_from_node2);
    Serial.print("(void loop)lettuce2_valve_state_from_node2=");
    Serial.println(lettuce2_valve_state_from_node2);
  }

  else
  {
    Serial.print(("deserializeJson() failed: "));
    Serial.println(error.f_str());
    return;
  }
  }
       Blynk.run();
     timer.run();
  delay(5000);
}





  
//  doc_to_node2["v1"] = water_spinach1_soil_wetness_state_to_node2;  // Creating JSON data. Here { v1 : 28.55 }
//  doc_to_node2["v2"] = lettuce1_soil_wetness_state_to_node2;  // Creating JSON data. Here { v1 : 28.55 }
//  doc_to_node2["v3"] = water_spinach2_soil_wetness_state_to_node2;  // Creating JSON data. Here { v1 : 28.55 }
//  doc_to_node2["v4"] = lettuce2_soil_wetness_state_to_node2;  // Creating JSON data. Here { v1 : 28.55 }
//  doc_to_node2["v5"] = water_spinach1_valve_state_to_node2;  // Creating JSON data. Here { v1 : 28.55 }
//  doc_to_node2["v6"] = lettuce1_valve_state_to_node2;  // Creating JSON data. Here { v1 : 28.55 }
//  doc_to_node2["v7"] = water_spinach2_valve_state_to_node2;  // Creating JSON data. Here { v1 : 28.55 }
//  doc_to_node2["v8"] = lettuce2_valve_state_to_node2;  // Creating JSON data. Here { v1 : 28.55 }
//  doc_to_node2["v9"] = water_spinach1_valve_state_from_node2;  // Creating JSON data. Here { v1 : 28.55 }
//  doc_to_node2["v10"] = lettuce1_valve_state_from_node2;  // Creating JSON data. Here { v1 : 28.55 }
//  doc_to_node2["v11"] = water_spinach2_valve_state_from_node2;  // Creating JSON data. Here { v1 : 28.55 }
//  doc_to_node2["v12"] = lettuce2_valve_state_from_node2;  // Creating JSON data. Here { v1 : 28.55 }
//  serializeJson(doc_to_node2, order_from_node1);
//  Serial.println(order_from_node1); 
//  order_from_node1 ="";delay(500);

xxxxxxxxxxxxx

โค้ด Node2

//ขาที่ใช้แล้วได้แก่ 
//D0(water_spinach1_valve_D0);D1(lettuce1_valve_D1),D2(),D3(water_spinach2_valve_D3),D4(),D5(lettuce2_valve_D5),D6(),D7()
//D8(ใช้แล้ว uploadไม่ได้)
//A0(),
#include <SimpleTimer.h>
SimpleTimer timer;
#define BLYNK_PRINT Serial;

#include <ArduinoJson.h>
StaticJsonDocument<256> doc_to_node1; // JSON Doc for Transmitting data to node2
StaticJsonDocument<256> doc_from_node1; // JSON Doc 
String info_to_node1;               // create JSON string
String order_from_node1;               // create JSON string

//ผักบุ้ง1
int water_spinach1_valve_D0 = D0;// ปิดเปิดวาล์วน้ำรดผักบุ้ง1
int water_spinach1_valve_state_to_node2;
int water_spinach1_valve_state_from_node2;

//ผักกาด1
int lettuce1_valve_D1 = D0;// ปิดเปิดวาล์วน้ำรดผักกาด1
int lettuce1_valve_state_to_node2;
int lettuce1_valve_state_from_node2;

//ผักบุ้ง2
int water_spinach2_valve_D3 = D3;// ปิดเปิดวาล์วน้ำรดผักบุ้ง2
int water_spinach2_valve_state_to_node2;
int water_spinach2_valve_state_from_node2;

//ผักกาด2
int lettuce2_valve_D5 = D5;// ปิดเปิดวาล์วน้ำรดผักกาด2
int lettuce2_valve_state_to_node2;
int lettuce2_valve_state_from_node2;

//  doc_to_node2["v1"] = water_spinach1_soil_wetness_state;  // Creating JSON data. Here { v1 : 28.55 }
//  doc_to_node2["v2"] = water_spinach2_soil_wetness_state;  // Creating JSON data. Here { v1 : 28.55 }
//  doc_to_node2["v3"] = lettuce1_soil_wetness_state;  // Creating JSON data. Here { v1 : 28.55 }
//  doc_to_node2["v4"] = lettuce2_soil_wetness_state;  // Creating JSON data. Here { v1 : 28.55 }

///////////////////////////////////////////////////


void water_spinach1_task()
{
  if(water_spinach1_valve_state_to_node2==0)
  {
   digitalWrite(water_spinach1_valve_D0, 0);//low active
   water_spinach1_valve_state_from_node2=0;
   doc_to_node1["v9"] = water_spinach1_valve_state_from_node2;
   serializeJson(doc_to_node1, info_to_node1);
   Serial.print("void water_spinach1_task()=>info_to_node1="); 
   Serial.println(info_to_node1); 
   info_to_node1 = "";
   delay(500);
  }
  else
  {
   digitalWrite(water_spinach1_valve_D0, 1);//low active
   water_spinach1_valve_state_from_node2=1;
   doc_to_node1["v9"] = water_spinach1_valve_state_from_node2;
   serializeJson(doc_to_node1, info_to_node1);
   Serial.print("void water_spinach1_task()=>info_to_node1="); 
   Serial.println(info_to_node1); 
   info_to_node1 = "";
   delay(500);
  }
}   
////////////////////////////
void lettuce1_task()
{
  if(lettuce1_valve_state_to_node2==0)
  {
   digitalWrite(lettuce1_valve_D1, 0);//low active
   lettuce1_valve_state_from_node2=0;
   doc_to_node1["v9"] = lettuce1_valve_state_from_node2;
   serializeJson(doc_to_node1, info_to_node1);
   Serial.print("void lettuce1_task()=>info_to_node1="); 
   Serial.println(info_to_node1); 
   info_to_node1 = "";
   delay(500);
  }
  else
  {
   digitalWrite(lettuce1_valve_D1, 1);//low active
   lettuce1_valve_state_from_node2=1;
   doc_to_node1["v10"] = lettuce1_valve_state_from_node2;
   serializeJson(doc_to_node1, info_to_node1);
   Serial.print("void lettuce1_task()=>info_to_node1="); 
   Serial.println(info_to_node1); 
   info_to_node1 = "";
   delay(500);
  }
} 
////////////////////////////
void water_spinach2_task()
{
  if(water_spinach2_valve_state_to_node2==0)
  {
   digitalWrite(water_spinach2_valve_D3, 0);//low active
   water_spinach2_valve_state_from_node2=0;
   doc_to_node1["v11"] = water_spinach2_valve_state_from_node2;
   serializeJson(doc_to_node1, info_to_node1);
   Serial.print("void water_spinach2_task()=>info_to_node1="); 
   Serial.println(info_to_node1); 
   info_to_node1 = "";
   delay(500);
  }
  else
  {
   digitalWrite(water_spinach2_valve_D3, 1);//low active
   water_spinach2_valve_state_from_node2=1;
   doc_to_node1["v11"] = water_spinach2_valve_state_from_node2;
   serializeJson(doc_to_node1, info_to_node1);
   Serial.print("void water_spinach2_task()=>info_to_node1="); 
   Serial.println(info_to_node1); 
   info_to_node1 = "";
   delay(500);    
  }
  
}
////////////////////////////
void lettuce2_task()
{
  if(lettuce2_valve_state_to_node2==0)
  {
   digitalWrite(lettuce2_valve_D5, 0);//low active
   lettuce1_valve_state_from_node2=0;
   doc_to_node1["v9"] = lettuce1_valve_state_from_node2;
   serializeJson(doc_to_node1, info_to_node1);
   Serial.print("void lettuce1_task()=>info_to_node1="); 
   Serial.println(info_to_node1); 
   info_to_node1 = "";
   delay(500);
  }
  else
  {
   digitalWrite(lettuce2_valve_D5, 1);//low active
   lettuce2_valve_state_from_node2=1;
   doc_to_node1["v12"] = lettuce2_valve_state_from_node2;
   serializeJson(doc_to_node1, info_to_node1);
   Serial.print("void lettuce2_task()=>info_to_node1="); 
   Serial.println(info_to_node1); 
   info_to_node1 = "";
   delay(500);
  }
}  
///////////////////////////
void setup() {
   Serial.begin(9600);
   pinMode(water_spinach1_valve_D0, OUTPUT);
   digitalWrite(water_spinach1_valve_D0, 1);//low active
   pinMode(lettuce1_valve_D1, OUTPUT);
   digitalWrite(lettuce1_valve_D1, 1);//low active
   pinMode(water_spinach2_valve_D3, OUTPUT);
   digitalWrite(water_spinach2_valve_D3, 1);//low active
   pinMode(lettuce2_valve_D5, OUTPUT);
   digitalWrite(lettuce2_valve_D5, 1);//low active
   timer.setInterval(1000L,water_spinach1_task);
   timer.setInterval(1200L,lettuce1_task);
   timer.setInterval(1600L,water_spinach2_task);
   timer.setInterval(1800L,lettuce2_task);
}
////////////////////////////
void loop()
{
 if (Serial.available() > 0) 
  {
   order_from_node1 = Serial.readStringUntil('\n');
   DeserializationError error = deserializeJson(doc_from_node1, order_from_node1);
   if (!error)
   {
    Serial.print("order_from_node1 : ");
    Serial.println(order_from_node1);
    water_spinach1_valve_state_to_node2=doc_from_node1["v9"] ;  // Creating JSON data. Here { v1 : 28.55 }
    lettuce1_valve_state_to_node2=doc_from_node1["v10"] ;
    water_spinach2_valve_state_to_node2=doc_from_node1["v11"] ;
    lettuce2_valve_state_to_node2=doc_from_node1["v12"] ;
    Serial.print("(void loop)water_spinach1_valve_state_to_node2=");
    Serial.println(water_spinach1_valve_state_to_node2);
    Serial.print("(void loop)lettuce1_valve_state_to_node2=");
    Serial.println(lettuce1_valve_state_to_node2);
    Serial.print("(void loop)water_spinach2_valve_state_to_node2=");
    Serial.println(water_spinach2_valve_state_to_node2);
    Serial.print("(void loop)lettuce2_valve_state_to_node2=");
    Serial.println(lettuce2_valve_state_to_node2);
   }
   else
   {
    Serial.print(("deserializeJson() failed: "));
    Serial.println(error.f_str());
    return;
   }
  }

  timer.run();
  delay(5000);
}