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

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);
}

11-12ตค 65
ได้เริ่มทำที่หน้างาน
งาน1
ได้ทำ voltage divider เพื่อติดตามไฟ12V และแจ้งใน Blynk
เพราะ ไฟ12V ต้องใช้ในการหมุนมอเตอร์ปล่อยอาหารไก่,หมุนพัดลมระบายอากาศของระบบฟักไข่ และต้องใช้ในcapacitive sensor ของอาหารไก่
ต่อไปอาจทำโค้ด ที่เกี่ยวข้องไฟ 12V เพิ่มอีกก็ได้
วงจร
ตามที่เว๊บแนะนำแบบนี้


xxxx
แต่ที่ต่อจริงแบบนี้ เพราะ อุปกรณ์ไม่ครบ

ก็เวอร์กครับ ไดโอดกำลังสั่ง ค่อยต่อภายหลังครับ
โค้ด
เนื่องจาก timer แรกผมใช้เกิน 12 task แล้ว
ผมต้องเพิ่ม timer2 ครับ

......
.....
BlynkTimer timer;
BlynkTimer timer2;
......
.....
//V72(volt12_transformer_average)
int volt12_monitor_pin33 = 33;
int volt12_monitor_pin33_value = 0;
int volt12_monitor_pin33_volt = 0;
unsigned long start_5min_interval_transformer_read_ms=0;
int volt12_transformer_average;
WidgetLED volt12_status_led_V71(V71);
......
.....
void setup() {
  // put your setup code here, to run once:
  ......
.....
   timer2.setInterval(1000L,volt12_monitor_task);
   timer2.setInterval(1000L,V71_sync);
......
.....
}

void loop() {
  // put your main code here, to run repeatedly:
     timer.run();
     timer2.run();
     Blynk.run();

}

//////////////////////////////
void volt12_monitor_task()
{//void volt12_monitor_task()
  volt12_monitor_pin33_value = analogRead(volt12_monitor_pin33);  //อ่านค่าสัญญาณ analog ขา33 เว็บไว้ในตัวแปร volt12_monitor_pin33_value
  Serial.print("volt12_monitor_pin33_value = "); // พิมพ์ข้อมความส่งเข้าคอมพิวเตอร์ "val = "
  Serial.println(volt12_monitor_pin33_value); // พิมพ์ค่าของตัวแปร 
  volt12_monitor_pin33_volt=((volt12_monitor_pin33_value*12.23)/3182);
  //volt12_status_led_V71  
  delay(500);
  //ถ้า ภายใน5นาที เฉลี่ย battery วัดได้ มากกว่า 9 ถือว่าปกติ  น้อยกว่า 9 V  transformerมีปัญหา
  Blynk.virtualWrite(V72,volt12_transformer_average);

  if ((millis()-start_5min_interval_transformer_read_ms)<300000)
  {//if ((millis()-start_5min_interval_transformer_read_ms)<300000)
      volt12_transformer_average=(volt12_transformer_average+volt12_monitor_pin33_volt)/2;
      Serial.print("volt12_transformer_average = "); // พิมพ์ข้อมความส่งเข้าคอมพิวเตอร์ "val = "
      Serial.println(volt12_transformer_average); // พิมพ์ค่าของตัวแปร 
    if (volt12_transformer_average>=9)
    {//if (volt12_transformer_average>=9)
      volt12_status_led_V71.on();
      Blynk.setProperty(V71,"color","#2EFE2E");//เชียว    Blynk.setProperty(V2,"color","#2EFE2E");// สีเขียว
      Serial.println("color,#2EFE2E สีเขียว"); // พิมพ์ค่าของตัวแปร 

    }//if (volt12_transformer_average>=9)
    else//if (volt12_transformer_average>=9)
    {//else if (volt12_transformer_average>=9)
      volt12_status_led_V71.on();
     Serial.println("V71,color,FF4000");//สีแดง"); // พิมพ์ค่าของตัวแปร 
      Blynk.setProperty(V71,"color","#FF4000");//สีแดง       Blynk.setProperty(V2,"color","#FF4000");// สีแดง    
    }//elseif (volt12_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)
    volt12_transformer_average=volt12_monitor_pin33_volt;   
    start_5min_interval_transformer_read_ms =millis();
   
  }//else if ((millis()-start_5min_interval_transformer_read_ms)<300000)

}//void volt12_monitor_task()
//////////////////////////////
void V71_sync()
{
  Blynk.syncVirtual(V71);
}
////

volt12_monitor_pin33_volt=((volt12_monitor_pin33_value*12.23)/3182);
มาจาก ผมเทียบวัดของจริงคือ วัดจากpin33 ได้ 3182 โดยที่วัดโวลต์มัลติมิเตอร์ ได้ 12.23 volts
ผลลัพธ์
ผมใส่ใน superchart จะมี ไฟ 5V อยู่แล้ว


ครบสูตรเลยครับ

ปัญหา
1.สายบัดกรี จาก รีเลย์เพื่อรับสัญญาณไฟ12V หลุด ทำให้มีการเติมอาหารจนล้น เลยบัดกรีใหม่ ก็หายปกติ
2.nodeMCU32 ร้อนทำให้อัพโหลดไม่ได้ เปลี่ยนตัวใหม่ก็อัพโหลดได้ ตัวที่ร้อนง่าย ผมจะลองติดฮีตซิ้งค์จะช่วยแก้ปัญหาได้ไหม ไม่ทราบเพื่อนๆได้ลองบ้างไหมครับ
3.ช่วงที่อัพโหลด มีจังหวะสั้นๆ (ไม่เกิน5 วินาที)ที่ต้องรีบกดปุ่ม format มิฉะนั้นจะfail และเริ่มใหม่อีก
4.รู้สึกว่า เสียเวลากับการอัพโหลด node32s มากครับ เป็นเวลาไม่น้อยกว่า 1ชั่วโมง แกะ nodemcu32 ออกจาก แผงบอร์ดขยายขาแล้ว เปลี่ยนสายแล้ว พอร์ต usb แล้ว สามารถแสดงผลการทำงานใน serial monitorได้ แต่อัพโหลดไม่ได้ เจอ error บ่อยมาก เทียบกับ 8266 จะอัพโหลดง่ายกว่าเยอะมากครับ
13-17ตค65
ปัญหา โปรเจ็คไก่โต-nodeesp32 แสดง led blynk 1 led ไม่ตรง
สาเหตุ
1.สายเซ็นเซอร์ที่บัดกรีหลุด ต่อแล้ว ต่อมาหลุดอีกแต่คนละสายของรีเลย์เดียวกัน
2.อาการแสดง led blynk ยังไม่ตรงอีก ไล่สายใหม่ เปลี่ยนตน.pinใหม่ ก็ดีบ้าง ไม่ดีบ้าง ใช้เวลาท 4 วัน เป็นที่โค้ด วางผิด ตน.ของ loop :hot_face: :hot_face:
พอแก้แล้ว แสดงปกติแล้วครับ

18-23ตค.65
node mcu 8266 ที่ควบคุม ระบบการฟักไข่ มีการเอ๋อ บางครั้ง ไม่ทำงาน ต้องมารีเซ็ต บางครั้ง มีการทำงานค้างจน อุณหภูมิเกิน 40 องศาเซลเซียส
ผลการทำการฟักไข่ 2 เดือนที่ผ่านมา ล้มเหลว ผมสั่งไข่มีเชื้อ 3 รุ่น ไม่สำเร็จเลย
ก่อนหน้านี้ ผมใช้ ระบบควบคุม ด้วย เซ็นเซอร์อุณหภูมิและความชื้นแบบธรรมดา แบบที่ให้ตั้งค่า และให้มันตัดต่อ แล้วผ่านรีเลย์ ยังสำเร็จครับ
พอมาใช้ กับ nodemcu 8266 และ arduino และ dht11 โดยทำโปรแกรมน่าจะโอเค แต่มันมีปัญหาจุกจิก คือ ความเสถียร ทำให้การฟักไข่ ที่ต้องการแบบ intensive care ทำให้ fail อย่างน่าเสียดาย เพราะจุดเด่นคือ สามารถ ติดต่อผ่าน blynk ได้ตลอดเวลา
และวันนี้เป็นวันที่ผมต้องเอาไข่ไก่ 10กว่าฟอง ต้องไปฝังเป็นปุ๋ยต้นกล้วยแทน
เพราะฟักมา 30 วันแล้ว ไม่ยอมออกสักที น่าจะตายคาโครมแล้วหละ ปกติ ไข่ไก่ ฟักใช้เวลา 21 วันเท่านั้น
และผมต้องบอกลา nodemcu สำหรับ การฟักไข่แล้วครับ
เหลือตัวเดียวที่ผมยังไม่ลอง คือ PLC โดยที่ไม่เคยจับมันเลย และต้องมาเริ่มต้นศึกษาใหม่จาก ศูนย์ครับ
30 ตค. 65
ได้สั่ง plc ตัวแรก เป็น บอร์ด PLC.FX3U-24MR เอาท์พุทรีเลย์ พีแอลซี Board FX3U-24MR PLC Controller ราคา 1400 บาท จากร้านนี้

1-10พย.65
และได้ศึกษาข้อมูลจาก ของพี่ปุ๋ย มีประโยชน์มาก :pray: :pray: แต่ระยะแรกผมศึกษาภาษาladder เพื่อใช้สั่งงานโดยตรง สำหรับอนาคต ผมจะลองเอา esp32 ตามพี่ปุ๋ย มาเชื่อมต่ออีกทีครับ
การสั่งงาน plc ใช้ภาษา ladder หรือขั้นบันได เป็นภาษารีเลย์ก็ว่าได้
และได้ค้นหาในยูทูป มีอาจารย์หลายท่านช่วยให้ความรู้ ได้อย่างละเอียด
ด่านแรกที่ผมเจอคือ ต้องเรียนรู้เรื่องเลขฐาน2,8,10,bit,byte,word ผมยอมรับว่า
ไม่มีพื้นฐานในด้านนี้เลยครับ
เพราะเป็นเลขที่plcเข้าใจ
ถึงบางอ้อ ว่าทำไม arduino ไม่ต้องยุ่งเรื่องเลขฐานเหล่านี้ เพราะมี library เป็นตัวช่วยแปลให้ภาษามนุษย์(ภาษา arduino) เป็นภาษาคอมพ์(เลขฐาน)เหล่านี้
ดังนั้น plc ไม่ต้องมี library ให้เราต้องติดตั้งเพิ่มเลย
แต่มันยากมาก กว่าจะได้จับทางได้
มันต่างกับ arduino มาก คนละเรื่องเลย
เพราะไม่มีการเขียนเป็น ประโยคคำสั้ง แต่ plc มันเป็นการขีดเส้นๆ มีตัวหนังสือกำกับนิดหน่อย …

ผมได้รวบรวมหัวข้อเกี่ยวกับ PLC ผมทำบันทึกไว้ใน docs ของ google พร้อมแคปหน้าจอ youtube เพื่อจะรู้ตน. นาที ที่สอนแต่ละเรื่อง เพื่อจะเอามาทบทวนอีกครั้ง ถ้าเพื่อนๆสนใจ ก็กดลิ้งค์นี้ เพื่อเอาไปประกอบในการศึกษาเบื้องต้นด้วยตัวเอง

11-17พย.65
หลังได้รู้เรื่อง plc คร่าวๆ ก็
ลองมาลงรูป การ wiring ลงใน edrawmax มีรูปประกอบ ด้วย จะได้ไม่งง มาก
Screenshot 2022-11-18 055603

xxx


จะเห็นว่า อาหารของPLC คือไฟ 24โวลต์ ขณะ nodemcu ใช้ไฟ 5 v
xxx

xxx

ข้อดีของบอร์ดนี้คือมี output ออกเป็น relay มีจำนวน10ตัว สามารถรับกระแสสูงสุด 5 A
แต่รีเลย์ 10 ตัวนี้ เสียดายใช้ ขา common แค่ 3 ตัวเอง ไม่ใช่ 1:1
comm1 ใช้กับ y0,y1,y2,y3
comm2 ใช้กับ y4,y5,y6,y7
comm3 ใช้กับ y10,y11
ดังนั้นต้องวางแผนให้ดีว่า ใช้ไฟอะไรบ้าง จะได้ประหยัดรีเลย์ ถ้ามากกว่า3 กลุ่ม ก็ต้อง เพิ่มรีเลย์อีกชั้นหนึ่งก็ได้
สำหรับโปรเจ็คนี้ พอดีครับ มีอุปกรณ์ไฟฟ้า 3 ประเภทคือ 12vdv,24vdc,220vacพอดีเลย
และกำหนดค่า y (output) ให้ตรงกับตน.รีเลย์ที่ใช้ด้วยครับ
xxx
จะได้รู้ว่า input(x) มีอะไรบ้าง output(y) มีอะไรบ้าง port rs486 มีอะไรบ้าง
ซึ่งมี input(x) 14 ตัว
สำหรับผมตอนนี้ผมไม่ใช้ x เพราะรอสวิทช์แบบ push button ส่งมา
แต่สามารถใช้สวิทช์โปรแกรมคือ m8000 เพื่อให้เริ่มทำงานได้เลย

xxx
อุปกรณ์ที่สำคัญอีกตัวที่แทน dht11 คือ ตัวนี้ครับ


ผมสั่งจากที่นี่
ราคา 189 บาท ซึ่งเป็นราคาที่ถูกที่สุดในช้อปปี้และลาซาด้า
ต่อเข้า port rs486 และใช้ protocol modbus ในการสื่อสาร ซึ่งเป็นอีก1วิชาที่ต้องศึกษา
ผมได้ลองใช้ค่าตามตย. ที่อาจารย์plc center( :pray:)ให้มาแล้ว และสลับตัวแปรค่า tempและhumid ใช้ได้ครับ เพราะอุปกรณ์ของตย.มันคนละยี่ห้อ นอกนั้นก็เหมือนกันหมด ใครสนใจลองเอาโค้ดในภาษาladderศึกษาดู

xxx
จากนั้น ผมลองสร้างโปรแกรม ladder เพื่อควบคุมการฟักไข่ ตามเงื่อนไข เหมือนกับที่ใช้กับ arduino
ถ้าใครสนใจลองเอาไปศึกษาดูครับ อาจมีข้อผิดพลาดบ้าง อย่าตามทั้งหมดนะ 555
xxx


ผมเก็บเคสplc ใว้ในแกลลอนเปล่ามารีไซเคิลใช้ให้เป็นประโยชน์ อาจดูไม่สวยครับ
และรอเก็บสายไฟใส่ในรางให้เรียบร้อย
xxx
18พย.65
เจอปัญหา หลอดไฟ 100 วัตต์(y1)เปิดค้าง จนอุณหภูมิทะลุ 50 องศา เซลเซียส ทั้งๆที่ ดูออนไลน์ กับgx work2 ไม่ได้สั่งเลย และ ดูที่ไฟ led ที่ y1 ก็ดับอยู่ และไล่สายไฟ ก็ผ่าน รีเลย์ y1 เท่านั้น ไม่ได้ลัดวงจรที่ไหน
แสดงว่า น่าสัมผัสมันค้าง เข้าแล้ว หลังจากผมดึงปลั๊กไฟ 220vac ออก สัก 2 นาที หลอดไฟไม่ค้างแล้ว และเปิดปิดตามรีเลย์แล้ว แต่ไข่ร้อนถึง 50 องศาเซลเซียส ไม่รู้ว่าจะเสียไหม :sob: :sob:
เช็คแล้ว หน้าสัมผัส y1 ค้างครับ ไม่ยอมดีดกลับ หลังจาก ไฟled y1 ดับแล้ว คลิป

1 Likes

29พย.65
หลังจากได้ ใช้ PLC ตัวแรก ควบคุมการฟักไข่ แล้วเดินเครื่องได้ปกติแล้ว
ผมได้สั่ง PLC ตัวที่2 รุ่น เดิม 24MR ต่อครับ เพื่อควบคุมการให้อาหารไก่ แทน esp32 ครับ
ก่อนอื่นผมลองลงรูป การเดินสาย ใน Edrawmax เพื่อให้เข้าใจมากขึ้น
ภาพรวม

ภาพPLC

จะเห็นว่า โปรเจ็คนี้ ใช้ output จนหมดเกลี้ยงครับ(10 device)
เพื่อควบคุม มอเตอร์ 3 ตัว(หมุนทวนและตามเข็ม) และควบคุม การเปิดปิด เซ็นเซอร์อาหาร อีก 3ตัว เพื่อป้องการกันหน้าสัมผัสไม่ให้ทำงานถึ่เกินไป จะได้มีอายุการใช้งานที่นานขึ้นครับ

1 Likes


ผมลองใช้ chat GPT ถามเรื่อง ทำไม เวลาเพิ่ม id ต้วที่ 2 id ตัวที่1 จะทำงานเพี้ยน
มันก็ตอบให้ 5555
Q:device A slave id 1 report correctly,27 degree celceus , but when I add device B id slave=3 ,A report 53 degree celcieus that not correct. why??

A:There could be several reasons why your device A is reporting incorrect temperature values when device B is added to the network. Some potential causes could include:

  1. Interference or noise on the communication network: If there is interference or noise on the communication network, it can cause errors in the data being transmitted, leading to incorrect values being reported.
  2. Configuration or wiring issues: There may be an issue with the configuration or wiring of device B that is causing it to interfere with the communication of device A. For example, if the wiring of device B is incorrect, it could cause a short circuit or other issue that could affect the communication of device A.
  3. Hardware or software issues: There may be a hardware or software issue with one or both of the devices that is causing the incorrect temperature readings. This could include issues with the temperature sensor itself, or with the software that is responsible for reading and transmitting the temperature data.

To troubleshoot the issue, you may want to try the following steps:

  1. Check for interference or noise on the communication network: Check for any external sources of interference or noise that could be affecting the communication of the devices, such as power cables or other electronic devices.
  2. Verify the configuration and wiring of device B: Make sure that device B is properly configured and wired, and that it is not causing any issues with the communication of device A.
  3. Check for hardware or software issues: Test the temperature sensors of both devices to ensure they are working correctly, and check for any software issues that could be causing the incorrect temperature readings.

By following these steps, you may be able to identify the cause of the issue and take the appropriate steps to fix it.

เสียดาย มันใช้แต่ภาษาอังกฤษ ไม่มีภาษาไทย
อยากถามเพื่อนๆ ว่าแก้อย่างไรครับ เรื่อง เซ็นเซอร์อุณหภูมิ ถ้ามีตัวเดียว มันอ่าน 27 องศา แต่พอเพิ่ม sensor ตัวที่2 มันอ่าน 53 องศา ซึ่งมันผิด
พอถอดตัวเซ็นเซอร์ตัวที่ 2 ตัวที่1 ทำงานปกติ

ใช้เซ็นเซอร์ตัวไหนครับ

เจอแล้ว สาเหตุ คือ สาย B- ของ sensor ตัวที่ 2 มันหลุด 555

DIY เซ็นเซอร์วัดความชื้นในดิน งบไม่เกิน 50 บาท
*ข้อดี *
ราคาถูก
ทนทาน เพราะใช้เหล็กชุบกัลวาไนซ์

ข้อเสีย
ไม่มีค่ามาตรฐานว่า เท่าไหร่ถือว่าเปียก หรือแห้ง
เราต้องมาทดสอบวัดเอาเอง ว่า ดินเปียกอ่านได้เท่าไหร่ ดินแห้งอ่านได้เท่าไหร่
ถ้ามาอ่านได้ค่ามากเท่ากันตลอดทั้งเปียกและแห้ง เราแก้โดยเพิ่ม R จาก 1K ohm ไป และเทสต์ดู เป็นต้น


ดินเปียก อ่านกระแสได้ 900+
xxx

ดึงแท่งเหล็กที่ทำเป็นเซ็นเซอร์ออกจากดินเปียก อ่านค่าได้ 400+
xxx
เอา ค่า D50 มาใช้งานได้เลย
โค้ดตัวอย่าง

การต่อวงจร(แก้ไข 7มค65)

ขอย้ำ ว่าให้ใช้ไฟเลี้ยงเซ็นเซอร์วัดความชื้นในดินนี้ให้ใช้ไฟ 24VDC เพื่อจะใช้สาย GND ร่วมกับ ที่ใช้กับ PLC เพราะถ้าใช้ ไฟ 5vdc และใช้ GND ของ 5vdc ในการเชื่อมกับ PLCซึ่งเป็นmaster จะมีผลทำให้ ค่าที่อ่านจาก slaveตัวอื่นๆ เพี้ยนหมดเลยครับ ผมเสียเวลาหาสาเหตุกว่าจะเจอ เสียไป 6 ชั่วโมงเลยครับ

1 Likes

ตอนนี้ ระบบ plc พอทำงานได้บ้างแล้ว

PLC ตัวที่1
PLC ตัวที่2

การต่อวงจร อาจมีบางจุดที่ต้องแก้ไข

เหลืออีกอย่างคือ การให้ esp32 ต่อกับ plc และส่งข้อมูลผ่าน blynk ยังไม่เริ่มทำอีกครับ คิดว่าต้องถามเพื่อนๆอีกหลายครั้งครับ

มีโค้ด ที่ ผีพราย(chatGPT)กระซิบมาบอก แต่ยังไม่ได้ลอง

#include <HardwareSerial.h>

HardwareSerial PLCSerial(2); // Set up a serial communication object using hardware serial port 2

void setup() {
  // Initialize serial communication at a baud rate of 9600
  PLCSerial.begin(9600);
}

void loop() {
  // Send data to the PLC
  PLCSerial.write(0x01); // Send the value 0x01 over the serial connection
  PLCSerial.write(0x02); // Send the value 0x02 over the serial connection

  // Read data from the PLC
  if (PLCSerial.available()) {
    // Read a single byte from the serial connection
    byte data = PLCSerial.read();
  }
}

เป็นรุ่นนี้ ทั้ง 2 ตัวครับ

เทียบเทอร์โมมิเตอร์สำหรับการฟักไข่ 10มค.66

1.เซ็นเซอร์ วัดความชื้นและอุณหภูมิ rs485
วัดได้ 37.0 องศาเซลเซียส
2.แบบ แอลกอฮอล์ สีแดง วัดได้ 36.0 องศาเซลเซียส
3.แบบปรอท วัดไข้ วัดได้ 37.0 องศาเซลเซียส
4…เซ็นเซอร์ วัดความชื้นและอุณหภูมิ dht11 arduino ไม่ได้ทำการวัด
สรุป ผมเอาแบบที่3 เป็นค่ามาตรฐาน จะเห็นว่า เซ็นเซอร์ วัดความชื้นและอุณหภูมิ rs485 ให้ค่าที่ถูกต้องอยู่ ในอนาคตไม่แน่ ต้องเช็คเป็นระยะๆ

1 Likes


อแดปเตอร์12VDC ซื้อเมื่อ 8 เดือนที่แล้ว วันนี้ ท่าทางจะเสื่อมแล้ว เพราะวัดได้ 6V เท่านั้น ไม่มีแรงพอจะขับมอเตอร์ได้ พอที่จะแก้ไขอย่างไรบ้างครับ
ต้องทำการเปลี่ยนตัวใหม่

เคสแบบนี้เจอบ่อยครับ เพื่อนผมเคยไปติดตั้ง ใช้งานได้ไม่นานก็ไฟตก ต้องเข้าไปเปลี่ยนใหม่ อย่างดีไปเลย ซ่อมก็อาจจะไม่จบครับ

อยากทราบเหตุผลที่เลือกใช้ PLC เข้ามาร่วมทำงานในโปรเจ็คนี้หน่อยครับ

เหตุผลคือ ผมจนปัญญากับ nodemcu8266 และ esp32 ในโปรเจ็คทำฟาร์มไก่ เช่น การฟีดอาหารไก่ การฟักไข่ ผมคิดว่า โปรแกรมลองแล้วก็เวิร์กดีนะระดับนึง แต่มีปัญหาเกี่ยวกับ cpu แฮงค์บ่อย ยิ่งกับการควบคุมฟักไข่ ต้องการความต่อเนื่อง และอุณหภูมิที่คงที่มากๆ และแคบมากๆ ไม่ควรเกิน 38 องศา ซ. และไม่ต่ำกว่า 37 องศา ซ ต่อเนื่องกันอย่างน้อย 21 วัน ผมได้ลองทำมาตั้งแต่ มีนาคม 65 พัฒนาความรู้เรื่อยๆ แบบงูๆปลาๆ ผมคิดว่าระบบน่าสมบูรณ์ที่สุดเดือนกันยายน65 , แต่ทำไมใช้ arduino ฟักไข่ 3ชุดแล้วไม่สำเร็จเลย ขณะที่ผมเคยใช้ เซ็นเซอร์แบบอนาลอกควบคุมผ่านรีเลย์ยังสำเร็จได้
ผมก็ลอง PLC ดู เริ่มศึกษา ต้งแต่ ตค.65 , พย.65 เริ่มใช้ plcคตัวแรก 14MR คุมการฟักไข่ ต่อมาธค.65 ซื้อตัวที่2 14MR มาคุมเรื่องฟีดอาหารไก่ , กลางๆ ธค. 65 ซื้อplc ตัวที่3 เป็นรุ่น 48MR คุมทั้งเล้าไก่ในตัวนี้ โดยมี 14MR 1ตัวเป็น slave, เซ็นเซอร์ อุณหภูมิ ความชื้น 3 ตัว ผ่าน RS485 port,
เท่าที่ผมใช้ nodemcu 8266 และ esp32 มีปัญหา คือ เวลาไฟดับ มันหยุดทำงาน พอเวลาไฟมาไม่ยอมรีสตาร์ท ผมอยู่ไกลจากฟาร์ม ทำให้เรามารีเซ็ต และ ทำให้ไข่ไก่ไม่ฟัก และเสียไปเลย ลองๆมา เสียไข่ ประมาณ 30ฟอง หรือ 3 ชุด ไม่เคยได้ตัวไก่เลย 555
พอผมเริ่มใช้plc ก็มีไข่ฟักครั้งแรก 2ตัวจากไข่10ฟอง รอดูชุด2 กำหนดฟัก 21 มค.66 นี้แล้ว
นอกจากนี้แล้ว เรื่องระบบฟีดอาหาร ก็ปัญหาเดียวกัน ที่เมื่อไหร่ ไฟดับ พอไฟมา จะทำงานไม่แน่นอนแล้วครับ
ถ้าเพื่อนอยากใช้ arduino ผมอยากให้เพื่อนข้าม ชิป nodemcu หรือ ESP32 ให้ใช้ของ แท้ เช่น arduino จากอิตาลีไปเลย ซึ่งผมไม่ได้ลองจุดนี้ อยากให้เพื่อนๆลองทำดู แล้วแชร์มาครับ

1 Likes

หลังจากใช้ PLC ทำให้โปรเจ็คเราเดินหน้าได้ ไม่ต้องย่ำอยู่ที่เดิมครับ แต่ arduino เป็นสิ่งแรกที่จุดประกายเรื่อง automation และทำให้เราได้เปรียบเพราะ arduino พร้อมเติมเต็ม ที่จะทำอย่างไรให้โปรเจ็คเราสำเร็จตามเป้าหมาย

1 Likes

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

1 Likes