เลี้ยงไก่ด้วย nodemcu (ตอนที่1)

ครับ
แต่เนื้อหาเยอะมาก ผมทยอยทำไปแก้ไป…
เดี๋ยวจะย้ายมาในนี้ครับ
ขอบคุณ​ครับ​

//Digital pins 0—15 can be INPUT, OUTPUT, or INPUT_PULLUP
//
//D0(motor1- ไก่โร้ดส์- D0/GPIO16,INPUT_PULLDOWN),D1((24 มิย.sensor ถังบน)lamp_chickไฟสำหรับลูกไก่),D2(lamp),D3(cntd2"ถังอาหารไก่โร้ดส์"D3 = GPIO 0),D4(cntd1 ถังบนD4 = GPIO 2),
//D5((24 มิย.sensor ถังไก่บ้าน)(dht_chick ลูกไก่),D6(cntd ไก่บ้านD6 = GPIO 12),D7(ac control),D8(motor2),D9(dht),D10((24 มิย.เปิดปิดไฟsensor ถังไก่โร้ดส์)
//(24 มิย.)ขอยืม /D5((24 มิย.เปิดปิดไฟsensor ถังไก่บ้าน)sensor dht2,D1((24 มิย.เปิดปิดไฟsensor ถังบน)หลอดไฟลูกเจี๊ยบ เพราะpinไม่พอ(24 มิย.)
//D1((24 มิย.เปิดปิดไฟsensor ถังบน-swith_sensor_upper_tank)
//D5(24 มิย.).เปิดปิดไฟsensor ถังไก่บ้าน-swith_sensor_local_tank)
//D10((24 มิย.เปิดปิดไฟsensor ถังไก่โร้ดส์-swith_sensor_rhodes_tank)
//ให้ได้อุณหภูมิ32องศา ถ้าเกินให้ดับไฟ
#include <Wire.h>
//-1·แจ้งทางไลน์
#include <TridentTD_LineNotify.h>
#define LINE_TOKEN  "xxxx"   //  ใส่ รหัส TOKEN  // 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 DAYNIGHT(V3);
WidgetLED motorled(V7);
WidgetLED lampblynk(V9);
WidgetLED lampchickblynk(V10);
 float temperature;
 float humidity;
 String formattedTime;
 String currentDate;
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[]="xxxxp-ggfv";

const char *ssid     = "xxx";
const char *password = "xxxx";
//char* ssid[] = {"xxxx","xxxxx","xxxx","xxx"};    //Array containing any wifi networks the device can use
//char* pass[] = {"xxx","x","x","x"};    //Array containing associated wifi passwords
//int i = 0;
//int w = 0;
//int wifi_timeout = 10;    //Timeout for each connection attempt (seconds)
//#define SSID_COUNT (sizeof(ssid)/sizeof(ssid[0]))  //Determines the number of SSIDs in ssid[] array
//
int a=0;

/////////
int timezone = 7 * 3600; //ตั้งค่า TimeZone ตามเวลาประเทศไทย
int dst = 0; //กำหนดค่า Date Swing Time
int currentHour = 0;
// กำหนดค่า offset time เนื่องจากเวลาของเซิฟเวอร์นี้เป็นเวลา UTC เราต้องทำให้เป็นเวลาของประเทศไทย
// เวลาของประเทศไทย = UTC+7 ชั่วโมง ต้องกำหนด offset time = 7 ชั่วโมง

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

int motor1 = D0;//หมุนมอเตอร์ไปตามเข็ม ให้ไก่โรดส์
int motor2 = D8;//หมุนมอเตอร์ไปทวนเข็ม ให้ไก่บ้าน
int cntd1 = D4;
int switch_sensor_upper_tank = D1;
//int lamp_chick = D1;// 24มิย65
//D1((24 มิย.เปิดปิดไฟsensor ถังบน-swith_sensor_upper_tank)
int switch_sensor_local_tank  =D5;
//D5(24 มิย.).เปิดปิดไฟsensor ถังไก่บ้าน-swith_sensor_local_tank)
int switch_sensor_rhodes_tank =D10;
//D10((24 มิย.เปิดปิดไฟsensor ถังไก่โร้ดส์-swith_sensor_rhodes_tank)

int lamp = D2;
int val = 0;


//int a=0;

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

//ถัง2
int cntd2 = D3; //"ถังอาหารไก่โร้ดส์"
int d2 = 0;


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

//ถัง3
int cntd = D6; 
int val3 = 0;
////w
float maxtemp = -9999; // init with absurdly low value
float mintemp = 9999; // init with absurdly high value

////-w
float currenttemp=0;
   unsigned long startMillisTemp;                        
        unsigned long currentMillisTemp;                      
        unsigned long startMillisReadData;                    
        unsigned long currentMillisReadData;                  
        const unsigned long periodReadData = 1000;            
        int ResetEnergy = 0;                                  
        unsigned long startMillis1; 
        BlynkTimer timer;
//0  ตรวจสอบอุณหภูมิ
#include "DHT.h"
DHT dht;
//DHT dht_chick;24 มิย. 65
// เก็บข้อมูลอุณหภูมิ ทุกครึ่งชั่วโมง
 
void setup()
{
    startMillis1 = millis();
         Serial.begin(9600);
     //dht11
     dht.setup(D9); // ขาD9
//24 มิย. 65     dht_chick.setup(D5); // ขาD5
//    Blynk.begin(auth, ssid, password);
  Blynk.begin(auth, ssid, password, "oasiskit.com", 8080);  
     //widget ใน blynk
     TANK1.on();
     TANK2.on();
     TANK3.on();
     DAYNIGHT.on();
     motorled.on();
//     lampblynk.off();
//     lampchickblynk.off();


     //-1·แจ้งทางไลน์
     Serial.println();
     Serial.println(LINE.getVersion());
     //0.ดึงเวลาจากเน็ตมาใช้
     Serial.setDebugOutput(true);
     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);
      }
     //-1·แจ้งทางไลน์
     // กำหนด Line Token
     LINE.setToken(LINE_TOKEN);
// 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(100);
     }
     Serial.println("");

     //1.ถังอาหารที่1 คือถังอาหารบนที่เติมอาหารครั้งละ20ลิตร
     pinMode(motor1, OUTPUT);
     pinMode(motor2, OUTPUT);
     pinMode(cntd1, INPUT_PULLUP);
 //    pinMode(cntd2, INPUT_PULLUP);
//     pinMode(cntd, INPUT_PULLUP);
     pinMode(switch_sensor_upper_tank, OUTPUT);
      //int switch_sensor_upper_tank = D1;
      //D1((24 มิย.เปิดปิดไฟsensor ถังบน-swith_sensor_upper_tank)
      digitalWrite(switch_sensor_upper_tank, 1);//active low 24 มิย. 65
     pinMode(swith_sensor_local_tank, OUTPUT);
      //int switch_sensor_local_tank  =D5;
      //D5(24 มิย.).เปิดปิดไฟsensor ถังไก่บ้าน-swith_sensor_local_tank)
      digitalWrite(swith_sensor_local_tank, 1);//active low 24 มิย. 65
     pinMode(switch_sensor_rhodes_tank, OUTPUT);
      //int switch_sensor_rhodes_tank =D10;
      //D10((24 มิย.เปิดปิดไฟsensor ถังไก่โร้ดส์-swith_sensor_rhodes_tank)
      digitalWrite(switch_sensor_rhodes_tank, 1);//active low 24 มิย. 65
     
     //2.ถังอาหารที่2 คือถังที่ให้อาหารไก่โรดส์กิน
     pinMode(cntd2, INPUT_PULLUP);// กำหนดขาทำหน้าที่ให้ขา D3 เป็น INPUT รับค่าจากเซ็นเซอิร์cntd "ถังอาหารไก่โร้ดส์: "   //แทนpinMode(infrared3, INPUT);
 
      //3.ถังอาหารที่3 คือถังที่ให้อาหารไก่บ้านกิน
     pinMode(cntd, INPUT_PULLUP);// กำหนดขาทำหน้าที่ให้ขา D6 เป็น INPUT รับค่าจากเซ็นเซอิร์cntd    //แทนpinMode(infrared3, INPUT);

     
     digitalWrite(motor1, 1);//ปิดมอเตอร์
     digitalWrite(motor2, 1);//ปิดมอเตอร์
     pinMode(ac_control, OUTPUT); //ควบคุมไฟ AC 
     pinMode(lamp, OUTPUT);
      digitalWrite(lamp, 1);//active low
 //    pinMode(lamp_chick, OUTPUT);//D1(lamp_chick)  24 มิย. 65
 //     digitalWrite(lamp_chick, 1);//active low 24 มิย. 65
     
     digitalWrite(ac_control, 1);//ปิดไฟ AC
           delay(5000);
//    timer.setInterval(180000L, Temptask);
//    timer.setInterval(180000L, lamptask);
    timer.setInterval(180000L, Temptask);
    timer.setInterval(1000L, check_sensortask);
//    timer.setInterval(30000L, Tempchicktask);24 มิย. 65
//    timer.setInterval(180000L, lamptask);

  Blynk.syncAll();      

}

void check_sensortask()
  {
    
  }


void Temptask(){
     delay(dht.getMinimumSamplingPeriod());
  float temperature = dht.getTemperature(); // ดึงค่าอุณหภูมิ
  Serial.print("อุณหภูมิ");
  Serial.println(temperature, 1);
  currenttemp = temperature;
    Blynk.virtualWrite(V4, temperature);
  Blynk.virtualWrite(V5, humidity);

  currentMillisTemp = millis();
  if ((currentMillisTemp-startMillis1)<86400)// ในวันเดียวกัน 
  { if (currenttemp>maxtemp)   {maxtemp=currenttemp;}//if (value > maxval) { maxval = value; } // record new max value
    if (currenttemp<mintemp) { mintemp = currenttemp; } // record new min value

   }
  
  else // วันใหม่
  {maxtemp = currenttemp;
  startMillis1 = currentMillisTemp;
    }
    
    Blynk.virtualWrite(V6, maxtemp);
  
    }

//24 มิย. 65
//void Tempchicktask()
//    {
//     delay(dht_chick.getMinimumSamplingPeriod());
//    float temperature2 = dht_chick.getTemperature(); // ดึงค่าอุณหภูมิ
//    Serial.print("อุณหภูมิรังลูกไก่");
//    Serial.println(temperature2, 1);
//    Blynk.virtualWrite(V11, temperature2);
//  //ให้ได้อุณหภูมิ32องศา ถ้าเกิน35ให้ดับไฟ
//   if (temperature2<=31)//
//    { 
//  //เปิดหลอดไฟ
//      digitalWrite(lamp_chick, 0);//active low
//     Serial.println("เปิดไฟรังลูกไก่");
//      lampchickblynk.on();
//     }
//   if (temperature2>=35)// 
//    { 
//  //ปิดหลอดไฟ
//      digitalWrite(lamp_chick, 1);//active low
//     Serial.println("ปิดไฟรังลูกไก่");
//      lampchickblynk.off();
//     }
//    
//  
//   }
//  



void lamptask()
{
if((maxtemp > 33) &&( currentHour>18) && ( currentHour<21))
{digitalWrite(lamp, 0);//เปิด active low}
}
else
{
  digitalWrite(lamp, 1);// ปิด active low
  }
}


void loop() {
     ///
     check_temp();
     check_time();
     
     if ((currentHour >5) && (currentHour<14))
        { //if ((currentHour >5) && (currentHour<14))
          daytime();
         } //if ((currentHour >5) && (currentHour<14))

      else  //if ((currentHour >5) && (currentHour<14))
       {  // else ((currentHour >5) && (currentHour<14))
        nighttime();
     } // else ((currentHour >5) && (currentHour<14))
    
  delay(100);
  lamptask();
    Blynk.run();
     timer.run();
       
}

BLYNK_WRITE(V8) 
{
if (param.asInt()==1) {
   digitalWrite(ac_control, 0);//เปิดไฟ AC
   digitalWrite(motor1, 1);//ปิดมอเตอร์ตามเเข็ม , active low
   digitalWrite(motor2, 0);//เปิดมอเตอร์ทวนเข็ม , active low
   Blynk.setProperty(V7,"color","#FF4000");// สีแดง
  }
else
  {
  digitalWrite(ac_control, 1);//ปิดไฟ AC
  delay(5000);
  digitalWrite(motor2, 1);//ปิดมอเตอร์ทวนเข็ม , active low
  Blynk.setProperty(V7,"color","#2EFE2E");// สีเขียว
  }
}

void daytime()
{
Serial.println("เป็นเวลากลางวัน");
Blynk.setProperty(V3,"color","#F8ECE0");// สีครีม
//ให้มอเตอร์ทำงานได้ แต่ต้องเช็คว่าอาหารถัง1 มีไหม และ ในถัง2 หมดแล้วยัง 
//ถ้าครบ2 เงื่อนไข  มอเตอร์ทำงาน
val = digitalRead(cntd1); // ถ้ามีอาหาร =1‚ ถ้าไม่มีอาหาร = 0 ถังอาหารบน
Serial.print("val: ");
Serial.println(val);
if (val == 1) // ถ้ามีอาหาร =0‚ ถ้าไม่มีอาหาร = 1 ถังอาหารบน
   { 
   Serial.print("อาหารถังบนใกล้หมด ");
   Serial.println("ปิดมอเตอร์");
   Blynk.setProperty(V0,"color","#FF4000");// สีแดง
   LINE.notify("อาหารไก่ใกล้หมด");
   digitalWrite(motor1, 1);//ปิดมอเตอร์ตามเข็ม , active low
   digitalWrite(motor2, 1);//ปิดมอเตอร์ทวนเข็ม , active low
   digitalWrite(ac_control, 1);//ปิดไฟ AC
   delay(5000);
   } //(val == 1) // ถ้ามีอาหาร =0‚ ถ้าไม่มีอาหาร = 1 ถังอาหารบน
else //(val == 1) // ถ้ามีอาหาร =0‚ ถ้าไม่มีอาหาร = 1 ถังอาหารบน
   { //else (val == 1) // ถ้ามีอาหาร =0‚ ถ้าไม่มีอาหาร = 1 ถังอาหารบน
    //เงื่อนไข2  ถัง2 ถ้า d2== 1 คือถังไก่โร้ดส์ใกล้หมด
    d2 = digitalRead(cntd2); //"ถังอาหารไก่โร้ดส์"ในการอ่านค่าสวิตช์ที่ต่ออยู่กับ ขาD3 มาเก็บในสตัวแปล d2 ผ่านD3 ถ้าอาหารถัง2หมด ไฟสว่าง จะต่อวงจร จะทำให้d2=0 
    Blynk.setProperty(V0,"color","#2EFE2E");// สีเขียว
    Serial.print("ถังอาหารไก่โร้ดส์: ");
    Serial.println(d2);
    if (d2 == 0) // 0=อาหารไก่โร้ดส์ยังมีอีกคิอ อาหารยังเต็ม , ไฟเซ็นเซอร์สว่าง
       { //(d2 == 0) // 0=อาหารไก่โร้ดส์ยังมีอีกคิอ อาหารยังเต็ม , ไฟเซ็นเซอร์สว่าง
       Serial.print("อาหารไก่โรดยังมีอีก ");
       Serial.println("ปิดมอเตอร์");
       Blynk.setProperty(V1,"color","#2EFE2E");// สีเขียว
       delay(2000);
       digitalWrite(motor1, 1);//ปิดมอเตอร์ตามเข็ม , active low
       digitalWrite(motor2, 1);//ปิดมอเตอร์ทวนเข็ม , active low
       digitalWrite(ac_control, 1);// ปิดไฟ AC
       delay(5000);
       }//(d2 == 0)  0=อาหารไก่โร้ดส์ยังมีอีกคิอ อาหารยังเต็ม , ไฟเซ็นเซอร์สว่าง
   else
      { //else (d2 == 0)  0=อาหารไก่โร้ดส์ยังมีอีกคิอ อาหารยังเต็ม , ไฟเซ็นเซอร์สว่าง
      Serial.print("อาหารถังไก่โรดส์ใกล้หมด ");
      Blynk.setProperty(V1,"color","#FF4000");// สีแดง
      Serial.println("เปิดมอเตอร์");
      digitalWrite(ac_control, 0);// เปิดไฟ AC
      delay(2000);
      digitalWrite(motor2, 1);//ปิดมอเตอร์ทวนเข็ม , active low
      digitalWrite(motor1, 0);//เปิดมอเตอร์ตามเข็ม , active low
      Blynk.setProperty(V7,"color","#FF4000");// สีแดง
      delay(5000);//เปิดมอเตอร์ทวนเข็ม 5 วินาที
      digitalWrite(motor2, 1);//ปิดมอเตอร์ทวนเข็ม , active low
      Blynk.setProperty(V7,"color","#2EFE2E");// สีเขียว
      delay(5000);//เปิดมอเตอร์ทวนเข็ม 5 วินาที
      }//else (d2 == 0)  0=อาหารไก่โร้ดส์ยังมีอีกคิอ อาหารยังเต็ม , ไฟเซ็นเซอร์สว่าง
    // เริ่มตรวจถัง 3 โดยใช้ capacitive  proximity sensor ยี่ห้อ CNTD
    val3 = digitalRead(cntd); //ในการอ่านค่าสวิตช์ที่ต่ออยู่กับ ขาD6 มาเก็บในสตัวแปล val3 ผ่านD6 ถ้าอาหารถังไก่บ้านหมด ไฟสว่าง จะต่อวงจร จะทำให้val3=0 
    Serial.print("ถังอาหารไก่บ้าน: ");
    Serial.print("val3: ");
    Serial.println(val3);
    if (val3 == 0) //0 คิอ อาหารยังเต็ม , ไฟเซ็นเซอร์สว่าง
       { //(if (val3 == 0) //0 คิอ อาหารยังเต็ม , ไฟเซ็นเซอร์สว่าง
       Serial.print("อาหารไก่บ้านยังมีอีก ");
       Serial.println("ปิดมอเตอร์");
       Blynk.setProperty(V2,"color","#2EFE2E");// สีเขียว
       delay(2000);
       digitalWrite(motor1, 1);//ปิดมอเตอร์ตามเข็ม , active low
       digitalWrite(motor2, 1);//ปิดมอเตอร์ทวนเข็ม , active low
       digitalWrite(ac_control, 1);// ปิดไฟ AC
       delay(5000);
       } //if (val3 == 0) //0 คิอ อาหารยังเต็ม , ไฟเซ็นเซอร์สว่าง
   else //if (val3 == 0) //0 คิอ อาหารยังเต็ม , ไฟเซ็นเซอร์สว่าง
      {//else if (val3 == 0) //0 คิอ อาหารยังเต็ม , ไฟเซ็นเซอร์สว่าง
      Serial.print("อาหารถังไก่บ้านใกล้หมด ");
      Blynk.setProperty(V2,"color","#FF4000");// สีแดง
      Serial.print("อาหารถังบนยังมีอีก ");
      digitalWrite(ac_control, 0);// เปิดไฟ AC
      delay(2000);
      digitalWrite(motor1, 1);//ปิดมอเตอร์ตามเเข็ม , active low
      digitalWrite(motor2, 0);//เปิดมอเตอร์ทวนเข็ม , active low
      Blynk.setProperty(V7,"color","#FF4000");// สีแดง
      delay(5000);//เปิดมอเตอร์ทวนเข็ม 5 วินาที
      digitalWrite(motor2, 1);//ปิดมอเตอร์ทวนเข็ม , active low
      Blynk.setProperty(V7,"color","#2EFE2E");// สีเขียว
      }//else if (val3 == 0) //0 คิอ อาหารยังเต็ม , ไฟเซ็นเซอร์สว่าง
   } //(val == 1) // ถ้ามีอาหาร =0‚ ถ้าไม่มีอาหาร = 1 ถังอาหารบน
}


void nighttime()
{
  Serial.println("เป็นเวลากลางคืน");// จะปิดอาหารไก่บ้าน   แต่ไก่โรดส์เปิดตลอด
  Blynk.setProperty(V3,"color","#6E6E6E");//Grey
  //ให้มอเตอร์หยุดทำงาน
  digitalWrite(motor1, 1);//ปิดมอเตอร์ตามเข็ม , active low
 digitalWrite(motor2, 1);//ปิดมอเตอร์ทวนเข็ม , active low
 //ให้มอเตอร์ทำงานได้ แต่ต้องเช็คว่าอาหารถัง1 มีไหม และ ในถัง2 หมดแล้วยัง 
 //ถ้าครบ2 เงื่อนไข  มอเตอร์ทำงาน
 val = digitalRead(cntd1);
 Serial.print("val: ");
 Serial.println(val);
 if (val == 1) //if (val == 1) // ถ้ามีอาหาร =0‚ ถ้าไม่มีอาหาร = 1 ถังอาหารบน
    { //if (val == 1) // ถ้ามีอาหาร =0‚ ถ้าไม่มีอาหาร = 1 ถังอาหารบน
    Serial.print("อาหารถังบนใกล้หมด ");
    Serial.println("ปิดมอเตอร์");
    Blynk.setProperty(V0,"color","#FF4000");// สีแดง
    LINE.notify("อาหารไก่ใกล้หมด");
    digitalWrite(motor1, 1);//ปิดมอเตอร์ตามเข็ม , active low
    digitalWrite(motor2, 1);//ปิดมอเตอร์ทวนเข็ม , active low
    digitalWrite(ac_control, 1);//ปิดไฟ AC
    delay(5000);
    //break;
    }//if (val == 1) // ถ้ามีอาหาร =0‚ ถ้าไม่มีอาหาร = 1 ถังอาหารบน 
 else //if (val == 1) // ถ้ามีอาหาร =0‚ ถ้าไม่มีอาหาร = 1 ถังอาหารบน
     { //else if (val == 1) // ถ้ามีอาหาร =0‚ ถ้าไม่มีอาหาร = 1 ถังอาหารบน
     // เริ่มตรวจถัง 2 โดยใช้ capacitive  proximity sensor แบบสีเหลือง
     //เงื่อนไข2  d2=1 คือถังไก่โร้ดส์ใกล้หมด
     delay(2000);
     d2 = digitalRead(cntd2); //ในการอ่านค่าสวิตช์ที่ต่ออยู่กับ ขาD3 มาเก็บในสตัวแปล d2 ผ่านD3 ถ้าอาหารถัง2หมด ไฟสว่าง จะต่อวงจร จะทำให้d2=0 
     Blynk.setProperty(V0,"color","#2EFE2E");// สีเขียว
     Serial.print("ถังอาหารไก่โร้ดส์: ");
     Serial.println(d2);
     if (d2 == 0) // ถังไก่โร้ดส์ 0=มีอีก , 1= หมด, ใช้แบบ input_pullup
         //อาหารไก่โร้ดส์ยังมีอีกคิอ อาหารยังเต็ม , ไฟเซ็นเซอร์ดับ, ไม่มีไฟมาที่ ขา cntd2 ,HIGH คือเต็ม  ยกเว้นในไก่โร้ดเพราะสลับขาที่ relay AC ที่ออกเป็น NC แต่ไก่บ้านออก NO
         { //(d2 == 0) // ถังไก่โร้ดส์ 0=มีอีก , 1= หมด, ใช้แบบ input_pullup
         Serial.print("อาหารไก่โรดยังมีอีก ");
         Serial.println("ปิดมอเตอร์");
         Blynk.setProperty(V1,"color","#2EFE2E");// สีเขียว
         delay(2000);
         digitalWrite(motor1, 1);//ปิดมอเตอร์ตามเข็ม , active low
         digitalWrite(motor2, 1);//ปิดมอเตอร์ทวนเข็ม , active low
         digitalWrite(ac_control, 1);// ปิดไฟ AC
         delay(5000);
         }//(d2 == 0) // ถังไก่โร้ดส์ 0=มีอีก , 1= หมด, ใช้แบบ input_pullup
     else
         { //else if(d2 == 0) // ถังไก่โร้ดส์ 0=มีอีก , 1= หมด, ใช้แบบ input_pullup
         Serial.print("อาหารถังไก่โรดส์ใกล้หมด ");
         Blynk.setProperty(V1,"color","#FF4000");// สีแดง
         Serial.print("อาหารถังบนยังมีอีก ");
         Serial.println("เปิดมอเตอร์");
         digitalWrite(ac_control, 0);// เปิดไฟ AC
         delay(2000);
         digitalWrite(motor2, 1);//ปิดมอเตอร์ทวนเข็ม , active low
         digitalWrite(motor1, 0);//เปิดมอเตอร์ตามเข็ม , active low,motor1=motor_rhode
         Blynk.setProperty(V7,"color","#FF4000");// สีแดง
         //motor3=20;
         delay(5000);//เปิดมอเตอร์ทวนเข็ม 5 วินาที
         digitalWrite(motor2, 1);//ปิดมอเตอร์ทวนเข็ม , active low
         Blynk.setProperty(V7,"color","#2EFE2E");// สีเขียว
         }//else if(d2 == 0) // ถังไก่โร้ดส์ 0=มีอีก , 1= หมด, ใช้แบบ input_pullup

     } //if (val == 1) // ถ้ามีอาหาร =0‚ ถ้าไม่มีอาหาร = 1 ถังอาหารบน

}



  void check_temp()
  {
           //0  ตรวจสอบอุณหภูมิ
     delay(dht.getMinimumSamplingPeriod());
//    float motor3 = 0;
  float humidity = dht.getHumidity(); // ดึงค่าความชื้น
  float temperature = dht.getTemperature(); // ดึงค่าอุณหภูมิ
  Serial.print("ความชื้น");
  Serial.print("\t");
  Serial.print(humidity, 1);
  Serial.print("\t");
  Serial.print("อุณหภูมิ");
  Serial.println(temperature, 1);
  Blynk.virtualWrite(V4, temperature);
  Blynk.virtualWrite(V5, humidity);


  }

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

  time_t epochTime = timeClient.getEpochTime();
  
  String formattedTime = timeClient.getFormattedTime();
  Serial.print("Formatted Time: ");
  Serial.println(formattedTime);  

  currentHour = timeClient.getHours();// int currentHour อยู่ด้านบนแล้ว เพื่อประกาศเป็น global var
  Serial.print("Hour: ");
  Serial.println(currentHour);  
  int 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); 

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

  int 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:
  String 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);

    
  }

โค้ดข้างบนใช้งานได้แล้ว
แต่ผมมีpin ไม่พอ เลย ตัดการทำงานบางอย่างออกเพื่อใช้ในการเปิดปิดเซ็นเซอร์ proximity
ปัญหาเซ็นเซอร์ทำงานรัวๆ
กำลังแก้อยู่ถ้าไม่ได้จะปรึกษากับพี่ๆครับ


โมดูลชาร์จร้อนมาก
พอดึงปลั๊ก220vac ,bat 16850ปล่อยไฟสัก3นาที ก็ไฟหมดแล้ว

1 Likes


ผมลองจับที่ชาร์จโมดูล ไม่ร้อนแล้วครับ
ผมลองถอดไฟบ้านที่ชาร์จ/สายusbจากโน้ตบุกออก
จะดูว่า แบตเก่า18650 2ก้อนนี้ สามารถเลี้ยงบอร์ดและระบบตามเซ็นเซอร์​ต่าง ได้กี่นาที

5นาที(13.15น.)

1ชม.(14.15น.) ยังไม่ดับ

2ชม.(15.11น.)ยังไม่ดับ
+++++
หมดเวลา
ผมขอหยุดการทดลองก่อน
จะเสียบไฟชาร์จเข้าแล้ว
++.+
สรุปได้ผลน่าพอใจครับ
++++
หลังเสียบไฟชาร์จ จะมีไฟสีแดงขึ้น แสดงว่ากำลังชาร์จไฟเข้าแบต.

ถ้าเต็ม จะดับ
++++

1 Likes


ตอนนี้​board nodemcu i/oของผมใช้หมดทุกขา10pin
แต่ผมนับๆ ใช้ได้สูงสุด10pin อีก2งานต้องหยุดใช้งานชั่วคราว เพราะจะเป็น12pin
เลยสั่งตัวนี้ mcp23017 เพิ่มได้อีก 16ขา ผมยังไม่เคยใช้เลย
ขอคำแนะนำเกี่ยวกับ​การใช้ mcp23017ด้วยครับ
เพราะ​ผมมีโปรเจค ปลูกผักแปลงทึ่2ด้วย อยู่​ใกล้ๆกันเลยจะเอาโปรเจคนี้ใช้กับnodemcuเดียวกันกับที่เลี้ยงไก่ครับ

1 Likes

ต้องการใช้เพิ่มอีกกี่ pin ครับ ปกติเราจะใช้วิธีเพิ่ม โมดูล IC ขึ้นมาเพื่อขยาย port IO ออกไปอีกโดย ต่อจาก pin เดิมออกไป

น่าจะเอาอีก10-15pin
เพราะมีเรื่อง
คุมแปลงผัก
คุมอุณหภูมิเล้าไก่
คุมความชื้นอาหารไก่
ครับ…
ไม่รู้ว่า nodemcu รับไหวไหมครับ

สบายๆ ครับ ใช้ PCF8574 PCF8574T Module ขยายขา

ขอบคุณ​ครับ

เสียดายสั่ง ic mcp23017แล้ว

PCF8574 PCF8574T Moduleดีกว่าอบ่างไรครับ

ก็ใช้ได้ไม่ได้ต่างกันครับ ขอแค่ขยายขาได้ ก็โอเค

ขอบคุณครับ

ได้ติดตั้ง library Adafruit_MCP23017.h

และได้ลอง verify code ตัวอย่าง
เสริมความรู้เรื่อง mcp23017 ได้ที่ 1,2,3,4,5,7,

// Reads a button attached to a MCP23XXX pin.

// ok to include only the one needed
// both included here to make things simple for example
#include <Adafruit_MCP23X08.h>
#include <Adafruit_MCP23X17.h>

#define BUTTON_PIN 1  // MCP23XXX pin button is attached to

// only used for SPI
#define CS_PIN 6

// uncomment appropriate line
Adafruit_MCP23X08 mcp;
//Adafruit_MCP23X17 mcp;

void setup() {
  Serial.begin(9600);
  //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);
  }

  // configure pin for input with pull up
  mcp.pinMode(BUTTON_PIN, INPUT_PULLUP);

  Serial.println("Looping...");
}

void loop() {
  // LOW = pressed, HIGH = not pressed
  if (!mcp.digitalRead(BUTTON_PIN)) {
    Serial.println("Button Pressed!");
    delay(250);
  }
}

ไม่มีปัญหา และลอง upload ก็ผ่านครับ
ทีนี้ผมลองเอาโค้ดข้างบนมาปรับเข้ากับของผม verify ผ่าน
แต่ upload แล้ว error แบบนี้

"C:\\Users\\abee\\AppData\\Local\\Temp\\arduino_build_285349/chicken_feeding22_mcp23017.ino.elf"

Sketch uses 377444 bytes (36%) of program storage space. Maximum is 1044464 bytes.

Global variables use 35992 bytes (43%) of dynamic memory, leaving 45928 bytes for local variables. Maximum is 81920 bytes.

An error occurred while uploading the sketch

error: Failed to open COM5

error: espcomm_open failed

error: espcomm_upload_mem failed

ทำไม fail comm5 ทั้งๆที่ได้ upload ไฟล์ตัวอย่างสำเร็จ ,แต่ไฟล์โปรเจ็คผม verify ผ่าน แต่upload ไม่ผ่าน
ใช้ สาย usb และ nodemcu เดียวกัน…
ผมกดปุ่มรีเซ็ต และถอดสายและเสียบusb ใหม่ uploadใหม่
สำเร็จแล้วครับ

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

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


2200uF/16V เชื่อมระหว่าง GND และ Vusbครับ

เขาใช้กันตัวเล็กๆ ครับโถ่ววว สายก็เน้นเส้นละ 100 ขึ้น กำลังดีของถูกมักจะใช้ทอดแดงผสมหรือไม่เต็มไม่เหมาะกับการอ่านหรือเขียนข้อมูลครับ เดียวจะถ่ายที่ใช้ให้ดู

555 คาปาใหญ่ใหญ่พอกับ nodemcu ละ

1 Likes

วันนี้ไก่ได้กินข้าวยังครับ

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

1 Likes

ตอน 2
ตอนที่3