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

20กค65
ต่อจากที่นี่
ผมได้ IC MCP23017 แบบที่2 และอยากลองต่อตามรูปครับ


จากที่นี่
เพื่อต่อเข้ากับnode1



ซื้อจากที่นี่
หลังจากต่อ และ upload สำเร็จแล้ว
sketch node1 20กค65

#include <Adafruit_MCP23X17.h>
Adafruit_MCP23X17 mcp;
#define lamp 2     // MCP23XXX pin LED is attached to

////-q

//-1·แจ้งทางไลน์
#include <TridentTD_LineNotify.h>
#define LINE_TOKEN  "xxxx"
// HIGH คือ หมด LOW คือมี
//0.ดึงเวลาจากเน็ตมาใช้
#include <NTPClient.h>
#include <time.h>
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>

//1 ขึ้น Blynk
#include <BlynkSimpleEsp8266.h>
#define BLYNK_PRINT Serial;
WidgetLED TANK1(V0);
WidgetLED TANK2(V1);
WidgetLED TANK3(V2);
WidgetLED motorled(V7);
WidgetLED upper_tank_sensor_val_high_blynkled_v15(V15);
WidgetLED rhodes_tank_sensor_val_high_blynkled_v16(V16);
WidgetLED local_tank_sensor_val_high_blynkled_v17(V17);
WidgetLED motor_rhodes_button_v23(V23);
 String formattedTime;
 String formattedTime2;
 String currentDate;
 int monthDay;
 int currentMonth;
 String string_close;
 String string_open;
WiFiUDP ntpUDP;
const long offsetTime = 25200;       // หน่วยเป็นวินาที จะได้ 7*60*60 = 25200
NTPClient timeClient(ntpUDP, "pool.ntp.org");

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

//Month names
String months[12]={"มกราคม", "กุมภาพันธ์", "มีนาคม", "เมษายน", "พฤษภาคม", "มิถุนายน", "กรกฎาคม", "สิงหาคม", "กันยายน", "ตุลาคม", "พฤศจิกายน", "ธันวาคม"};


char auth[]="xxxx";

const char *ssid     = "xx";
const char *password = "xx";
int a=0;

/////////
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 ชั่วโมง

// กำหนด object ของ WiFiUDP ชื่อว่า ntpUDP
//1.ถังอาหารที่1 คือถังอาหารที่เติมอาหารครั้งละ20ลิตร
//   ถ้าอาหารลดลงมากถึงระดับต่ำ1 ให้เตือนทางline
//   ถ้าอาหารลดลงมากถึงระดับต่ำ2 ให้มอเตอร์หยุดทำงาน
//   แต่ต้องเวลากลางวันเท่านั้น ถ้ากลางคืนให้มอเตอร์หยุด
int ac_control = D7;// ควบคุมไฟAC

int motor_rhodes = D0;//หมุนมอเตอร์ไปตามเข็ม ให้ไก่โรดส์
int motor_local = D8;//หมุนมอเตอร์ไปทวนเข็ม ให้ไก่บ้าน
int upper_tank_sensor = D4;
int switch_sensor_upper_tank = D9;
//D9((24 มิย.เปิดปิดไฟsensor ถังบน-switch_sensor_upper_tank)
int switch_sensor_local_tank  =D5;
//D5(24 มิย.).เปิดปิดไฟsensor ถังไก่บ้าน-switch_sensor_local_tank)
int switch_sensor_rhodes_tank =D10;
const int  analogPin = A0; 
//const int sensor =  A0;
float vcc_voltage;
//D10((24 มิย.เปิดปิดไฟsensor ถังไก่โร้ดส์-switch_sensor_rhodes_tank)
//unsigned long upper_tank_sensor_StartTime = millis();
//unsigned long CurrentTime = millis();
//unsigned long upper_tank_sensor_ElapsedTime = CurrentTime - upper_tank_sensor_StartTime;

unsigned long upper_tank_sensor_duration;
unsigned long rhodes_tank_sensor_duration;
unsigned long local_tank_sensor_duration;
//bool local_tank_sensor_state;

int upper_tank_sensor_val = 0;


//int a=0;

//2.ถังอาหารที่2 คือถังที่ให้อาหารไก่ตัวใหญ่จิกกิน
//   ถ้าอาหารลดลงมากถึงระดับต่ำ1 ให้มอเตอร์เริ่มทำงาน
//   แต่ต้องเวลากลางวันเท่านั้น ถ้ากลางคืนให้มอเตอร์หยุด
//   ถ้าอาหารลดลงมากถึงระดับต่ำ2 ให้มอเตอร์หยุดทำงาน

//ถัง2
int rhodes_tank_sensor = D3; //"ถังอาหารไก่โร้ดส์"
int rhodes_tank_sensor_val = 0;
//3.ถังอาหารที่3 คือถังที่ให้อาหารไก่ตัวเล็กจิกกิน
//   ถ้าอาหารลดลงมากถึงระดับต่ำ1 ให้มอเตอร์เริ่มทำงาน
//   แต่ต้องเวลากลางวันเท่านั้น ถ้ากลางคืนให้มอเตอร์หยุด
//   ถ้าอาหารลดลงมากถึงระดับต่ำ2 ให้มอเตอร์หยุดทำงาน

//ถัง3
int local_tank_sensor = D6; 
int local_tank_sensor_val = 0;
        BlynkTimer timer;
//0  ตรวจสอบอุณหภูมิ
 
void setup()
{
   Serial.begin(9600);
   ///q   
  //while (!Serial);
   Serial.println("MCP23xxx Button Test!");

  // uncomment appropriate mcp.begin
  if (!mcp.begin_I2C()) {
  //if (!mcp.begin_SPI(CS_PIN)) {
    Serial.println("Error.");
    while (1);
  }
       mcp.pinMode(lamp, OUTPUT);
      mcp.digitalWrite(lamp, 0);//active low

     WiFi.mode(WIFI_STA); //เชื่อมต่อ Wifi
     WiFi.begin(ssid, password);
     Serial.println("\nConnecting to WiFi");
     while ((WiFi.status() != WL_CONNECTED)&&(a<6)) {
           Serial.print("*");
           a=a+1;
           delay(100);
      }
// Initialize a NTPClient to get time
  timeClient.begin();
  // 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(200);
     }
     Serial.println("");

  Blynk.begin(auth, ssid, password, "oasiskit.com", 8080);  
  delay(100);
     //widget ใน blynk
     TANK1.on();
     TANK2.on();
     TANK3.on();
//     DAYNIGHT.on();
     motorled.on();


     //-1·แจ้งทางไลน์
     // กำหนด Line Token
     LINE.setToken(LINE_TOKEN);
     Serial.println();
     Serial.println(LINE.getVersion());
     //0.ดึงเวลาจากเน็ตมาใช้
     Serial.setDebugOutput(true);
     //-1·แจ้งทางไลน์
     //1.ถังอาหารที่1 คือถังอาหารบนที่เติมอาหารครั้งละ20ลิตร
     pinMode(motor_rhodes, OUTPUT);
     pinMode(motor_local, OUTPUT);
     pinMode(upper_tank_sensor, INPUT_PULLUP);
     pinMode(switch_sensor_upper_tank, OUTPUT);
      digitalWrite(switch_sensor_upper_tank, 1);//active low 24 มิย. 65
     delay(100);
     pinMode(switch_sensor_local_tank, OUTPUT);
     digitalWrite(switch_sensor_local_tank, 1);//active low 24 มิย. 65
     delay(100);
     pinMode(switch_sensor_rhodes_tank, OUTPUT);
     digitalWrite(switch_sensor_rhodes_tank, 1);//active low 24 มิย. 65
     delay(100);
     //2.ถังอาหารที่2 คือถังที่ให้อาหารไก่โรดส์กิน
     pinMode(rhodes_tank_sensor, INPUT_PULLUP);// กำหนดขาทำหน้าที่ให้ขา D3 เป็น INPUT รับค่าจากเซ็นเซอิร์cntd "ถังอาหารไก่โร้ดส์: "  
 
      //3.ถังอาหารที่3 คือถังที่ให้อาหารไก่บ้านกิน
     pinMode(local_tank_sensor, INPUT_PULLUP);// กำหนดขาทำหน้าที่ให้ขา D6 เป็น INPUT รับค่าจากเซ็นเซอิร์local_tank_sensor    //แทนpinMode(infrared3, INPUT);
     digitalWrite(motor_rhodes, 1);//ปิดมอเตอร์
     delay(100);
     Blynk.virtualWrite(V21,string_close);
     digitalWrite(motor_local, 1);//ปิดมอเตอร์
     delay(100);
     Blynk.virtualWrite(V22, string_close);
     pinMode(ac_control, OUTPUT); //ควบคุมไฟ AC 
     
     digitalWrite(ac_control, 0);//ปิดไฟ AC
    timer.setInterval(1000L, check_sensortask);//
    timer.setInterval(1000L, check_voltage);//

  Blynk.syncAll();      

}
void check_voltage()
{

  
    //vcc_voltage 
    int b =analogRead(A0);
    delay(100);
    Serial.print("analogRead(A0)=");          
    Serial.println(b);          
    Serial.print("vcc_voltage=");  
    vcc_voltage = (4.67/306)*(b);
    Serial.println(vcc_voltage);          
    Blynk.virtualWrite(V25,b);
    Blynk.virtualWrite(V24,vcc_voltage);
    delay(100);
}
void check_sensortask()
  {
  //D4(upper_tank_sensor ถังบนD4 = GPIO 2,upper_tank_sensor_val),D3(rhodes_tank_sensor"ถังอาหารไก่โร้ดส์"D3 = GPIO 0,rhodes_tank_sensor_val),D6(local_tank_sensor ไก่บ้านD6 = GPIO 12,local_tank_sensor_val),
//       digitalWrite(switch_sensor_upper_tank, 0);//active low 24 มิย. 65
  upper_tank_sensor_duration = pulseIn(upper_tank_sensor, LOW,10000);
  delay(100);
  Serial.println(upper_tank_sensor_duration);
//   Blynk.virtualWrite(V18, upper_tank_sensor_duration);
   if(upper_tank_sensor_duration!=0)
     {
     digitalWrite(switch_sensor_upper_tank, 1);//active low 24 มิย. 65
     upper_tank_sensor_val_high_blynkled_v15.on();
     Blynk.virtualWrite(V14, "ค่าความถี่="+String(upper_tank_sensor_duration)+","+string_close);
     delay(100);
     }
     else
     {
     upper_tank_sensor_val_high_blynkled_v15.off();
     Blynk.virtualWrite(V4, "ค่าความถี่="+String(upper_tank_sensor_duration)+","+string_open);
     digitalWrite(switch_sensor_upper_tank, 0);//active low 24 มิย. 65
     delay(100);
 
      }
  rhodes_tank_sensor_duration = pulseIn(rhodes_tank_sensor, LOW,10000);
  delay(100);
  Serial.println(rhodes_tank_sensor_duration);
   Blynk.virtualWrite(V19, rhodes_tank_sensor_duration);
  if(rhodes_tank_sensor_duration!=0)
    {
     rhodes_tank_sensor_val_high_blynkled_v16.on(); 
     digitalWrite(switch_sensor_rhodes_tank, 1);//active low 24 มิย. 65
     rhodes_tank_sensor_val = 0; //0 คิอ อาหารยังเต็ม , ไฟเซ็นเซอร์สว่าง. แจ้งหลอกให้เต็มก่อนมิฉะนั้นมอเตอร์จะหมุน
     Blynk.setProperty(V1,"color","#2EFE2E");// สีเขียว
     digitalWrite(motor_rhodes, 1);//ปิดมอเตอร์ตามเข็ม , active low
     Blynk.virtualWrite(V6, "ค่าความถี่="+String(rhodes_tank_sensor_duration)+","+string_close);
     delay(100);
     }
     else
     {
     rhodes_tank_sensor_val_high_blynkled_v16.off(); 
     digitalWrite(switch_sensor_rhodes_tank, 0);//active low 24 มิย. 65
     delay(100);
     Blynk.virtualWrite(V5, "ค่าความถี่="+String(rhodes_tank_sensor_duration)+","+string_open);
      }
  local_tank_sensor_duration = pulseIn(local_tank_sensor, LOW,10000);
  delay(100);
  Serial.println(local_tank_sensor_duration);
   Blynk.virtualWrite(V20, local_tank_sensor_duration);
  if(local_tank_sensor_duration!=0 )
    {
     digitalWrite(switch_sensor_local_tank, 1);//active low 24 มิย. 65
     local_tank_sensor_val = 0; //0 คิอ อาหารยังเต็ม , ไฟเซ็นเซอร์สว่าง. แจ้งหลอกให้เต็มก่อนมิฉะนั้นมอเตอร์จะหมุน
     Blynk.setProperty(V2,"color","#2EFE2E");// สีเขียว
     local_tank_sensor_val_high_blynkled_v17.on();
     digitalWrite(motor_local, 1);//ปิดมอเตอร์ทวนเข็ม , active low
      Blynk.virtualWrite(V22, string_close);
     Blynk.virtualWrite(V3, "ค่าความถี่="+String(local_tank_sensor_duration)+","+string_close);
     }
     else
     {
     local_tank_sensor_val_high_blynkled_v17.off(); 
     digitalWrite(switch_sensor_local_tank, 0);//active low 24 มิย. 65
     delay(100);
     Blynk.virtualWrite(V9, "ค่าความถี่="+String(local_tank_sensor_duration)+","+string_open);
      }
    Blynk.syncAll();            
  }
void loop() {
     ///
     check_time();
      mcp.digitalWrite(lamp, 0);//active low

     string_close="ปิดเวลา"+String(currentHour)+":"+String(currentMinute)+","+String(monthDay) + "/" + String(currentMonth);
     string_open= "เปิดเวลา"+String(currentHour)+":"+String(currentMinute)+","+String(monthDay) + "/" + String(currentMonth);
     feeding();
//    //vcc_voltage 
//    int b =analogRead(A0);
//    Serial.print("analogRead(A0)=");          
//    Serial.println(b);          
//    Serial.print("vcc_voltage=");   
//    vcc_voltage = (4.69/321)*(b);
//    Serial.println(vcc_voltage);          
//    Blynk.virtualWrite(V24,vcc_voltage);
    delay(100); 
    Blynk.run();
  Blynk.syncAll();          
     timer.run();
}


BLYNK_WRITE(V23) 
{
if (param.asInt()==1) {
   digitalWrite(ac_control, 0);//เปิดไฟ AC
   digitalWrite(motor_rhodes, 0);//เปิดมอเตอร์ตามเเข็ม , active low
   delay(100);
    Blynk.virtualWrite(V10, string_open);
   digitalWrite(motor_local, 1);//ปิดมอเตอร์ทวนเข็ม , active low
     Blynk.virtualWrite(V22, string_close);
   motor_rhodes_button_v23.on();
   Blynk.setProperty(V7,"color","#FF4000");// สีแดง
  }
else
  {
  digitalWrite(ac_control, 1);//ปิดไฟ AC
   motor_rhodes_button_v23.off();
  delay(100);
  digitalWrite(motor_rhodes, 1);//ปิดมอเตอร์ตามเเข็ม , active low
  Blynk.virtualWrite(V21, string_close);
     
  Blynk.setProperty(V7,"color","#2EFE2E");// สีเขียว
  }
}


BLYNK_WRITE(V8) 
{
  delay(200);
if (param.asInt()==1) {
   digitalWrite(ac_control, 0);//เปิดไฟ AC
   digitalWrite(motor_rhodes, 1);//ปิดมอเตอร์ตามเเข็ม , active low
    Blynk.virtualWrite(V21, string_close);
   digitalWrite(motor_local, 0);//เปิดมอเตอร์ทวนเข็ม , active low
    Blynk.virtualWrite(V11, string_open);

   Blynk.setProperty(V7,"color","#FF4000");// สีแดง
  }
else
  {
  digitalWrite(ac_control, 1);//ปิดไฟ AC
  digitalWrite(motor_local, 1);//ปิดมอเตอร์ทวนเข็ม , active low
  Blynk.virtualWrite(V22, string_close);
  Blynk.setProperty(V7,"color","#2EFE2E");// สีเขียว
  delay(100);
  }
}




void feeding()
{
//Serial.println("เป็นเวลากลางวัน");
//Blynk.setProperty(V3,"color","#F8ECE0");// สีครีม
//ให้มอเตอร์ทำงานได้ แต่ต้องเช็คว่าอาหารถัง1 มีไหม และ ในถัง2 หมดแล้วยัง 
//ถ้าครบ2 เงื่อนไข  มอเตอร์ทำงาน
upper_tank_sensor_val = digitalRead(upper_tank_sensor); // ถ้ามีอาหาร =1‚ ถ้าไม่มีอาหาร = 0 ถังอาหารบน
delay(200);
Serial.print("upper_tank_sensor_val: ");
Serial.println(upper_tank_sensor_val);
if (upper_tank_sensor_val == 1) // ถ้ามีอาหาร =0‚ ถ้าไม่มีอาหาร = 1 ถังอาหารบน
   { 
   Serial.print("อาหารถังบนใกล้หมด ");
   Serial.println("ปิดมอเตอร์");
   Blynk.setProperty(V0,"color","#FF4000");// สีแดง
   LINE.notify("อาหารไก่ใกล้หมด");
   digitalWrite(motor_rhodes, 1);//ปิดมอเตอร์ตามเข็ม , active low
   Blynk.virtualWrite(V21, string_close);

   digitalWrite(motor_local, 1);//ปิดมอเตอร์ทวนเข็ม , active low
   Blynk.virtualWrite(V22, string_close);

   digitalWrite(ac_control, 0);//ปิดไฟ AC
   delay(1000);
   } //(upper_tank_sensor_val == 1) // ถ้ามีอาหาร =0‚ ถ้าไม่มีอาหาร = 1 ถังอาหารบน
else //(upper_tank_sensor_val == 1) // ถ้ามีอาหาร =0‚ ถ้าไม่มีอาหาร = 1 ถังอาหารบน
   { //else (upper_tank_sensor_val == 1) // ถ้ามีอาหาร =0‚ ถ้าไม่มีอาหาร = 1 ถังอาหารบน
    //เงื่อนไข2  ถัง2 ถ้า rhodes_tank_sensor_val== 1 คือถังไก่โร้ดส์ใกล้หมด
   Blynk.setProperty(V0,"color","#2EFE2E");// สีเขียว
    rhodes_tank_sensor_val = digitalRead(rhodes_tank_sensor); //"ถังอาหารไก่โร้ดส์"ในการอ่านค่าสวิตช์ที่ต่ออยู่กับ ขาD3 มาเก็บในสตัวแปล rhodes_tank_sensor_val ผ่านD3 ถ้าอาหารถัง2หมด ไฟสว่าง จะต่อวงจร จะทำให้rhodes_tank_sensor_val=0 
    delay(200);
    Blynk.setProperty(V1,"color","#2EFE2E");// สีเขียว
    Serial.print("ถังอาหารไก่โร้ดส์: ");
    Serial.println(rhodes_tank_sensor_val);
    if (rhodes_tank_sensor_val == 0) // 0=อาหารไก่โร้ดส์ยังมีอีกคิอ อาหารยังเต็ม , ไฟเซ็นเซอร์สว่าง
       { //(rhodes_tank_sensor_val == 0) // 0=อาหารไก่โร้ดส์ยังมีอีกคิอ อาหารยังเต็ม , ไฟเซ็นเซอร์สว่าง
       Serial.print("อาหารไก่โรดยังมีอีก ");
       Serial.println("ปิดมอเตอร์");
       Blynk.setProperty(V1,"color","#2EFE2E");// สีเขียว
       digitalWrite(motor_rhodes, 1);//ปิดมอเตอร์ตามเข็ม , active low
       Blynk.virtualWrite(V21, string_close);
       digitalWrite(motor_local, 1);//ปิดมอเตอร์ทวนเข็ม , active low
       Blynk.virtualWrite(V22, string_close);
      digitalWrite(ac_control, 0);// ปิดไฟ AC
       delay(5000);
       }//(rhodes_tank_sensor_val == 0)  0=อาหารไก่โร้ดส์ยังมีอีกคิอ อาหารยังเต็ม , ไฟเซ็นเซอร์สว่าง
   else
      { //else (rhodes_tank_sensor_val == 0)  0=อาหารไก่โร้ดส์ยังมีอีกคิอ อาหารยังเต็ม , ไฟเซ็นเซอร์สว่าง
      Serial.print("อาหารถังไก่โรดส์ใกล้หมด ");
      Blynk.setProperty(V1,"color","#FF4000");// สีแดง
      Serial.println("เปิดมอเตอร์");
      digitalWrite(ac_control, 0);// เปิดไฟ AC
      digitalWrite(motor_local, 1);//ปิดมอเตอร์ทวนเข็ม , active low
      Blynk.virtualWrite(V22, string_close);
      digitalWrite(motor_rhodes, 0);//เปิดมอเตอร์ตามเข็ม , active low
      Blynk.virtualWrite(V10, string_open);
      Blynk.setProperty(V7,"color","#FF4000");// สีแดง
      delay(5000);//เปิดมอเตอร์ทวนเข็ม 5 วินาที
      digitalWrite(motor_local, 1);//ปิดมอเตอร์ทวนเข็ม , active low
      Blynk.virtualWrite(V22, string_close);
      Blynk.setProperty(V7,"color","#2EFE2E");// สีเขียว
      delay(5000);//เปิดมอเตอร์ทวนเข็ม 5 วินาที
      }//else (rhodes_tank_sensor_val == 0)  0=อาหารไก่โร้ดส์ยังมีอีกคิอ อาหารยังเต็ม , ไฟเซ็นเซอร์สว่าง
    // เริ่มตรวจถัง 3 โดยใช้ capacitive  proximity sensor ยี่ห้อ CNTD
    local_tank_sensor_val = digitalRead(local_tank_sensor); //ในการอ่านค่าสวิตช์ที่ต่ออยู่กับ ขาD6 มาเก็บในสตัวแปล local_tank_sensor_val ผ่านD6 ถ้าอาหารถังไก่บ้านหมด ไฟสว่าง จะต่อวงจร จะทำให้local_tank_sensor_val=0 
    delay(200);
    Serial.print("ถังอาหารไก่บ้าน: ");
    Serial.print("local_tank_sensor_val: ");
    Serial.println(local_tank_sensor_val);
    if (local_tank_sensor_val == 0) //0 คิอ อาหารยังเต็ม , ไฟเซ็นเซอร์สว่าง
       { //(if (local_tank_sensor_val == 0) //0 คิอ อาหารยังเต็ม , ไฟเซ็นเซอร์สว่าง
       Serial.print("อาหารไก่บ้านยังมีอีก ");
       Serial.println("ปิดมอเตอร์");
       Blynk.setProperty(V2,"color","#2EFE2E");// สีเขียว
       digitalWrite(motor_rhodes, 1);//ปิดมอเตอร์ตามเข็ม , active low
       Blynk.virtualWrite(V21, string_close);

       digitalWrite(motor_local, 1);//ปิดมอเตอร์ทวนเข็ม , active low
       Blynk.virtualWrite(V22,string_close);

       digitalWrite(ac_control, 0);// ปิดไฟ AC
       } //if (local_tank_sensor_val == 0) //0 คิอ อาหารยังเต็ม , ไฟเซ็นเซอร์สว่าง
   else //if (local_tank_sensor_val == 0) //0 คิอ อาหารยังเต็ม , ไฟเซ็นเซอร์สว่าง
      {//else if (local_tank_sensor_val == 0) //0 คิอ อาหารยังเต็ม , ไฟเซ็นเซอร์สว่าง
      Serial.print("อาหารถังไก่บ้านใกล้หมด ");
      Blynk.setProperty(V2,"color","#FF4000");// สีแดง
      Serial.print("อาหารถังบนยังมีอีก ");
      digitalWrite(ac_control, 0);// เปิดไฟ AC
      digitalWrite(motor_rhodes, 1);//ปิดมอเตอร์ตามเเข็ม , active low
     Blynk.virtualWrite(V21, string_close);
      digitalWrite(motor_local, 0);//เปิดมอเตอร์ทวนเข็ม , active low
     Blynk.virtualWrite(V11, string_open);
      Blynk.setProperty(V7,"color","#FF4000");// สีแดง
      delay(5000);//เปิดมอเตอร์ทวนเข็ม 5 วินาที
      digitalWrite(motor_local, 1);//ปิดมอเตอร์ทวนเข็ม , active low
     Blynk.virtualWrite(V22, string_close);
      Blynk.setProperty(V7,"color","#2EFE2E");// สีเขียว
      }//else if (local_tank_sensor_val == 0) //0 คิอ อาหารยังเต็ม , ไฟเซ็นเซอร์สว่าง
   } //(upper_tank_sensor_val == 1) // ถ้ามีอาหาร =0‚ ถ้าไม่มีอาหาร = 1 ถังอาหารบน
}

  void check_time()
  {
//     //configTime(timezone, dst, "pool.ntp.org", "time.nist.gov"); //แสดงเวลาปัจจุบัน
//     time_t now = time(nullptr);
//     struct tm* p_tm = localtime(&now);
//1 
  
  timeClient.update();
  delay(100);
  time_t epochTime = timeClient.getEpochTime();
  delay(100);
  formattedTime = timeClient.getFormattedTime();
//  String formattedTime2 = 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);

  String 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:
  currentDate = String(weekDay) + "-" +String(monthDay) + "-" + String(currentMonth) + "-" + String(currentYear) ;
  Serial.print("Current date: ");
  Serial.println(currentDate);
//1
     Serial.print("current Time=");
     Serial.println(formattedTime);
  Blynk.virtualWrite(V12, currentDate);
    Blynk.virtualWrite(V13, formattedTime);
  Blynk.syncAll();      
  }

ผลคือ ไม่สามารถสั่งให้ mcp ทำงานผ่าน pin 2 ของ mcp
โดยไม่ทราบสาเหตุ อยากถามเพื่อนๆว่าเป็นเพราะอะไรบ้างครับ