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

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

17กค65
วันนี้แก้ โค้ด ที่ผมเข้าใจผิด ระหว่าง while และ if
ผมต้องการเปิด โซลินอยด์รดน้ำผัก ตามเงื่อนไข ตอนแรกใช้ if แต่ผมอยากให้มันทำงานแบบจริงจัง
เลยใช้ while แล้ว มันจะเปิดซ้ำๆ จนครบเวลา ซึ่งไม่จำเป็น เหมือนกับเพิ่มภาระให้ระบบ arduinoทำงานมากเกินไป
แค่ให้เปิดครั้งเดียวก็พอ เลยเปลี่ยนกลับใช้ if เหมือนเดิม

18กค65
เมื่อวานกับวันนี้ ได้ปรึกษากับแอดมินและเพื่อนๆ เพื่อทำ โค้ดเกี่ยวกับbutton switch ใน Blynk
โดยให้ button switch 2อัน เปิดสวิทช์ไฟ 2 ดวง หลอดไฟใหญ่ และหลอดไฟไก่เล็ก โดยทำงานอิสระต่อกัน
ก็ทำโค้ดแยกกัน
และให้รับค่า หน่วงเวลา(step H)สำหรับ ปิด button switch นี้ พอครบเวลาที่หน่วงไว้ ให้มันปิดเอง เปลี่ยน button จาก ON เป็น
OFF เอง
ถ้าหากเราปิดเองก่อนที่จะหมดเวลาก็ได้
ข้อสังเกตุ
-ให้หลีกเลี่ยง การใช้ while เพราะ ทำให้การทำงานช้าลงมากๆ โดยจะทำในwhile loop ให้เสร็จก่อนแล้ว จะ
รันโค้ดที่ต่อจากนั้น
-พยายาม ตั้ง หาตำแหน่ง จุด รีเซ็ต เวลา start_millis ให้ถูกตำแหน่ง มิฉะนั้น หลอดไฟจะเปิดตลอดเวลา
ตอนนี้พอจะเวิร์ก
แล้ว แต่มี stack overflow เกิดขึ้นครับ
ผมก๊อปจาก serial monitorบางส่วน

11:25:53.855 -> รดน้ำตอนเย็น: 10นาที
11:25:53.964 -> รดน้ำตอนเย็น: 10นาที
11:25:53.964 -> ห่างกัน: 32นาที
11:25:54.027 -> ห่างกัน: 32นาที
11:25:54.073 -> เริ่มเวลาตอนเช้า: 6น.
11:25:54.136 -> เริ่มเวลาตอนเช้า: 6น.
11:25:54.183 -> เสร็จตอนเช้า: 7น.
11:25:54.229 -> เสร็จตอนเช้า: 7น.
11:25:54.292 -> เริ่มเวลารดน้ำตอนเย็น: 17น.
11:25:54.339 -> เริ่มเวลารดน้ำตอนเย็น: 17น.
11:25:54.463 -> เสร็จเวลารblrblblrrlblr⸮b⸮br⸮l`а⸮ð⸮ð⸮⸮Ȱ⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮ð⸮⸮⸮⸮а⸮⸮⸮⸮⸮⸮⸮⸮⸮```
   



เห็นว่าเป็นปัญหา เรื่อง millis()
ลองย้ายค่า ในสมการ < ตามที่เขาว่า

sketch node2 18กค65


#include <Wire.h>
//-1·แจ้งทางไลน์
#include <TridentTD_LineNotify.h>
#define LINE_TOKEN  "xx"
// HIGH คือ หมด LOW คือมี
//0.ดึงเวลาจากเน็ตมาใช้
#include <NTPClient.h>
#include <time.h>
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
//1 ขึ้น Blynk
#include <BlynkSimpleEsp8266.h>
#define BLYNK_PRINT Serial;
 float temperature;
 float humidity;
 String formattedTime;
 String currentDate;
 int monthDay;
 int currentMonth;
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[]="vvvv";//หัวข้ออีเมล์ blynk token ไก่-ผัก

const char *ssid     = "zzz";
const char *password = "ggg";
int a=0;

///lamp_hen
int lamp_hen = D5;
WidgetLED lamp_hen_blynk(V9);
WidgetLED lamp_hen_button_V8(V8);
bool lamp_hen_maxtemp=1;
bool lamp_hen_blynkV8=0;//1คือ เปิด  0คือปิด
bool lamp_chicken_blynkV14=0;//1คือ เปิด  0คือปิด
int open_hen_lamp_period=2;//2hrs
unsigned long  start_hen_lamp=millis();
///-lamp_hen

///pump hen
int hen_water_cooling_pump = D8;// 10กค65
WidgetLED pump_hen_blynk_button_v26(V26);
WidgetLED pump_hen_blynk_led_v27(V27);
//bool pump_hen_hightemp=1;
//bool pump_hen_blynkV26=1;
int open_hen_pump_period=5;//5min.
unsigned long  start_hen_pump=millis();
float temp_start_hen_pump=30;
///-pump hen

///lamp_chicken
int lamp_chick = D4;// 24มิย65
WidgetLED lamp_chick_button_V14(V14);
WidgetLED lamp_chick_led_v10(V10);
int open_chicken_lamp_period=2;//2hrs
unsigned long  start_chicken_lamp=millis();
///-lamp_chicken

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

#define switch_sensor_upper_tank  22
//int switch_sensor_upper_tank = 22//D1;
float maxtemp = -9999; // init with absurdly low value
float mintemp = 9999; // init with absurdly high value
float min_soil_moisture = 9999; // init with absurdly high value
float max_soil_moisture =-9999; // init with absurdly low value
unsigned long start_millis_soil_check;
////-w

///l
int vegetable_soil_dryness = 0;
float vegetable_soil_dryness_blynk=910;
int analogPin = A0; 
bool soil_dryness_state = 0;//ดินเปียกlow active module  0คือแห้ง  1คือเปียก

///-l
unsigned long startMillisTemp;                        
unsigned long startMillismorning_watering=0;                    
unsigned long lastMillismorning_watering; 
int periodMinmorning_watering=3;//min
unsigned long startMillisevening_watering=0;                    
unsigned long lastMillisevening_watering; 
int periodMinevening_watering=3; //min
int not_within_min=3; //min
int start_am=6; //oclock
int end_am=7; //oclock
int start_pm=16; //oclock
int end_pm=18; //oclock
unsigned long start2;
int duration_morning=1; //min
int duration_evening=1; //min
unsigned long startMillisReadData;                    
unsigned long currentMillisReadData;                  
const unsigned long periodReadData = 1000;            
unsigned long start_millis_temp; 
BlynkTimer timer;
//0  ตรวจสอบอุณหภูมิ
#include "DHT.h"
DHT dht;
DHT dht_chick;//29 มิย. 65
// เก็บข้อมูลอุณหภูมิ ทุกครึ่งชั่วโมง
///ผัก///
int solenoid_vegetable=D7;
WidgetLED solenoid_vegetable_led_blynk_v21(V21);
WidgetLED solenoid_vegetable_button_blynk_v22(V22);
///-ผัก///
 
BLYNK_WRITE(V0)
{
  open_hen_lamp_period = param.asInt(); // assigning incoming value from pin V1 to a variable
  Serial.print("open_hen_lamp_period: ");
  Serial.print(open_hen_lamp_period);
  Serial.println("นาที");
//  periodMinevening_watering = open_hen_lamp_period;
}

BLYNK_WRITE(V1)
{
  open_chicken_lamp_period = param.asInt(); // assigning incoming value from pin V1 to a variable
  Serial.print("open_chicken_lamp_period: ");
  Serial.print(open_chicken_lamp_period);
  Serial.println("นาที");
//  periodMinevening_watering = open_hen_lamp_period;
}


BLYNK_WRITE(V11)
{
  int pinValue = param.asInt(); // assigning incoming value from pin V1 to a variable
  // You can also use:
  // String i = param.asStr();
  // double d = param.asDouble();
  Serial.print("รดน้ำตอนเช้า: ");
  Serial.print(pinValue);
  Serial.println("นาที");
  periodMinmorning_watering = pinValue;
}

BLYNK_WRITE(V15)
{
  int pin2Value = param.asInt(); // assigning incoming value from pin V1 to a variable
  // You can also use:
  // String i = param.asStr();
  // double d = param.asDouble();
  Serial.print("รดน้ำตอนเย็น: ");
  Serial.print(pin2Value);
  Serial.println("นาที");
  periodMinevening_watering = pin2Value;
}
BLYNK_WRITE(V16)
{
  int pin3Value = param.asInt(); // assigning incoming value from pin V1 to a variable
  // You can also use:
  // String i = param.asStr();
  // double d = param.asDouble();
  Serial.print("ห่างกัน: ");
  Serial.print(pin3Value);
  Serial.println("นาที");
  not_within_min = pin3Value;
}

BLYNK_WRITE(V17)
{
  int pin4Value = param.asInt(); // assigning incoming value from pin V1 to a variable
  // You can also use:
  // String i = param.asStr();
  // double d = param.asDouble();
  Serial.print("เริ่มเวลาตอนเช้า: ");
  Serial.print(pin4Value);
  Serial.println("น.");
  start_am = pin4Value;
}
BLYNK_WRITE(V18)
{
  int pin5Value = param.asInt(); // assigning incoming value from pin V1 to a variable
  // You can also use:
  // String i = param.asStr();
  // double d = param.asDouble();
  Serial.print("เสร็จตอนเช้า: ");
  Serial.print(pin5Value);
  Serial.println("น.");
  end_am = pin5Value;
}

BLYNK_WRITE(V19)
{
  int pin6Value = param.asInt(); // assigning incoming value from pin V1 to a variable
  // You can also use:
  // String i = param.asStr();
  // double d = param.asDouble();
  Serial.print("เริ่มเวลารดน้ำตอนเย็น: ");
  Serial.print(pin6Value);
  Serial.println("น.");
  start_pm = pin6Value;
}

BLYNK_WRITE(V20)
{
  int pin7Value = param.asInt(); // assigning incoming value from pin V1 to a variable
  // You can also use:
  // String i = param.asStr();
  // double d = param.asDouble();
  Serial.print("เสร็จเวลารดน้ำตอนเย็น: ");
  Serial.print(pin7Value);
  Serial.println("น.");
  end_pm = pin7Value;
}

BLYNK_WRITE(V25)
{
  vegetable_soil_dryness_blynk = param.asInt(); // assigning incoming value from pin V1 to a variable
  // You can also use:
  // String i = param.asStr();
  // double d = param.asDouble();
  Serial.print("ความแห้งของดิน: ");
  Serial.println(vegetable_soil_dryness_blynk);
//  periodMinevening_watering = pin2Value;
}


void setup()
{
         Serial.begin(9600);
     //dht11
     dht.setup(D3); // ขาD3
     dht_chick.setup(D6); // ขาD6

     //-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("");
    Blynk.begin(auth, ssid, password, "oasiskit.com", 8080);  

     pinMode(lamp_hen, OUTPUT);
     digitalWrite(lamp_hen, 1);//active low
     pinMode(lamp_chick, OUTPUT);//D4(lamp_chick)  24 มิย. 65
     digitalWrite(lamp_chick, 1);//active low 24 มิย. 65
     pinMode(hen_water_cooling_pump, OUTPUT);//D8
     digitalWrite(hen_water_cooling_pump, 1);//active low 24 มิย. 65
     Blynk.virtualWrite(V31,"=เวลา"+String(currentHour)+":"+String(currentMinute)+","+String(monthDay) + "/" + String(currentMonth));
     Blynk.virtualWrite(V8,0);
      
     ///ผัก///
     pinMode(solenoid_vegetable, OUTPUT);
     digitalWrite(solenoid_vegetable, 1);//active low 24 มิย. 65
     Blynk.virtualWrite(V33,"=เวลา"+String(currentHour)+":"+String(currentMinute)+","+String(monthDay) + "/" + String(currentMonth));
    solenoid_vegetable_button_blynk_v22.off();
     solenoid_vegetable_led_blynk_v21.off();
//   solenoid_vegetable_led_blynk_v21.on();
   Blynk.virtualWrite(V25,vegetable_soil_dryness_blynk);
     ///-ผัก///
//    timer.setInterval(180000L, Temptask);
    timer.setInterval(12000000L, lamp_hen_maxtemp_task);//12000000L=20min
//    timer.setInterval(1000L, hen_water_cooling_pump_task);//6000000L=10min

 // Blynk.syncAll();      

}


void Temptask(){
     delay(dht.getMinimumSamplingPeriod());
     temperature = dht.getTemperature(); // ดึงค่าอุณหภูมิ
     humidity = dht.getHumidity(); // ดึงค่าความชื้น
     Serial.print("อุณหภูมิ");
     Serial.println(temperature, 1);
     Serial.print("ความชื้นของอากาศ");
     Serial.println(humidity, 1);
    Blynk.virtualWrite(V4, temperature);
    Blynk.virtualWrite(V5, humidity);

  if ((millis()-start_millis_temp)<86400000)// ในวันเดียวกัน 86400000=1d;
    { 
    if (maxtemp<temperature)   
      {
        maxtemp=temperature;//+String(currentHour)+":"+String(currentMinute)+","+String(monthDay) + "/" + String(currentMonth);
      Blynk.virtualWrite(V6, String(maxtemp)+",เวลา("+String(currentHour)+":"+String(currentMinute)+","+String(monthDay) + "/" + String(currentMonth)+")");
//        Blynk.virtualWrite(V6, maxtemp);
//        start_millis_temp=(millis());
      }//if (temperature>maxtemp)   
    if (mintemp>temperature) 
        { 
        mintemp = temperature;//+String(currentHour)+":"+String(currentMinute)+","+String(monthDay) + "/" + String(currentMonth);
      Blynk.virtualWrite(V7, String(mintemp)+",เวลา("+String(currentHour)+":"+String(currentMinute)+","+String(monthDay) + "/" + String(currentMonth)+")");
 //       start_millis_temp=(millis());
        } // record new min value

      }
  else // วันใหม่
      {
        maxtemp = -999;
        mintemp = 999;
      
       start_millis_temp = millis();
    }
    
    Blynk.syncAll();      
    }

void lamp_hen_maxtemp_task()
{
if ((maxtemp > 33) &&( currentHour>18) && ( currentHour<21))
{
     Serial.print("อุณหภูมิ");
     Serial.println(temperature, 1);
  
lamp_hen_maxtemp=0;
lamp_hen_blynk.on();
}
else
{
lamp_hen_maxtemp=1;
  lamp_hen_blynk.off();  
  }
}




  void check_time()
  {
  
  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);  
  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:
  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(V12, currentDate);
    Blynk.virtualWrite(V13, formattedTime);
  Blynk.syncAll();      
  }



void loop() 
{
   check_soil_dryness();
   Temptask();
   check_time();
   check_time_for_watering();   
  if ((temperature > temp_start_hen_pump) &&(millis() <(start_hen_pump +(open_hen_pump_period*60*1000))))
  {
  digitalWrite(hen_water_cooling_pump, 0);
  Blynk.virtualWrite(V26,1);
  Blynk.virtualWrite(V30,"=เวลา"+String(currentHour)+":"+String(currentMinute)+","+String(monthDay) + "/" + String(currentMonth));
  pump_hen_blynk_led_v27.on();
  }
else
{
  start_hen_pump=millis() ;
//pump_hen_hightemp=1;
  pump_hen_blynk_led_v27.off();  
  Blynk.virtualWrite(V31,"=เวลา"+String(currentHour)+":"+String(currentMinute)+","+String(monthDay) + "/" + String(currentMonth));
  }

  delay(100);
  //lamp_hen_task();
    Blynk.run();
  Blynk.syncAll();          
     timer.run();
       
}

void check_soil_dryness()
{
    vegetable_soil_dryness = analogRead(analogPin);
    Blynk.virtualWrite(V2,vegetable_soil_dryness);
  if (vegetable_soil_dryness > vegetable_soil_dryness_blynk) 
      {
       soil_dryness_state = 0;//ดินแห้ง low active module
       Blynk.virtualWrite(V3,"แห้ง");//low active module
      }
  else
  {
       soil_dryness_state = 1;//ดินเปียก low active module
       Blynk.virtualWrite(V3,"เปียก");//low active module
      }

  if ((millis()-start_millis_soil_check)<86400000)// ในวันเดียวกัน 86400000=1d;
    { 
    if (max_soil_moisture<vegetable_soil_dryness)   
      {
        max_soil_moisture=vegetable_soil_dryness;
      Blynk.virtualWrite(V24, String(max_soil_moisture)+",เวลา("+String(currentHour)+":"+String(currentMinute)+","+String(monthDay) + "/" + String(currentMonth)+")");
      }
    if (min_soil_moisture>vegetable_soil_dryness) 
        { 
        min_soil_moisture=vegetable_soil_dryness;
      Blynk.virtualWrite(V23, String(min_soil_moisture)+",เวลา("+String(currentHour)+":"+String(currentMinute)+","+String(monthDay) + "/" + String(currentMonth)+")");
        } // record new min value

      }
  else // วันใหม่
      {
        max_soil_moisture = -9999;
        min_soil_moisture = 9999;
      
       start_millis_soil_check = millis();
       }
}

void   check_time_for_watering()
  {
   lastMillismorning_watering=millis()-startMillismorning_watering;
   lastMillisevening_watering=millis()-startMillisevening_watering;
   
     if ((currentHour >start_am) && (currentHour<end_am) &&  (lastMillismorning_watering>=(not_within_min*60*1000)))//  10800000ms=3hrs.                  

        { //if ((currentHour >5) && (currentHour<7)) &&  lastMillismorning_watering>=(not_within_min*60*1000);//  10800000ms=3hrs.                  

         check_soil_dryness();
          start2=millis();
          if ((millis()-start2) <(periodMinmorning_watering*60*1000))  //900000=15min//60000=1min
          {
           Blynk.virtualWrite(V32,"=เวลา"+String(currentHour)+":"+String(currentMinute)+","+String(monthDay) + "/" + String(currentMonth));
         digitalWrite(solenoid_vegetable, soil_dryness_state); //low active
         Blynk.virtualWrite(V22,!soil_dryness_state);
         Blynk.virtualWrite(V21,!soil_dryness_state);
           if (soil_dryness_state==0)
           {
           Serial.println("รดน้ำตอนเช้า"+String(periodMinevening_watering)+"นาที");            
           }
         }
         
         else // (millis() >= start2 +(periodMinmorning_watering*60*1000))  //900000=15min//60000=1min
         {
          startMillismorning_watering=millis();
         digitalWrite(solenoid_vegetable, 1); //low active
           Blynk.virtualWrite(V33,"=เวลา"+String(currentHour)+":"+String(currentMinute)+","+String(monthDay) + "/" + String(currentMonth));
         solenoid_vegetable_button_blynk_v22.off();
         solenoid_vegetable_led_blynk_v21.off();
         } //if (millis() >= start2 +(periodMinmorning_watering*60*1000))  //900000=15min//60000=1min
         }     
          
       if ((currentHour >=start_pm) && (currentHour<=end_pm)&&  (lastMillisevening_watering>=(not_within_min*60*1000)))//  10800000ms=3hrs. 
         { //if ((currentHour >=17) && (currentHour<=18)&&  (lastMillisevening_watering>=(not_within_min*60*1000)))//  10800000ms=3hrs. 
       //   periodMillisevening_watering=millis()-startMillisevening_watering;
           check_soil_dryness();

          start2=millis();
          if ((millis()-start2) <(periodMinevening_watering*60*1000))  //900000=15min//60000=1min
          {
           digitalWrite(solenoid_vegetable, soil_dryness_state); //low active
           if (soil_dryness_state==0)
           {
           Serial.println("รดน้ำตอนเย็น"+String(periodMinevening_watering)+"นาที");            
           }
           Blynk.virtualWrite(V32,"=เวลา"+String(currentHour)+":"+String(currentMinute)+","+String(monthDay) + "/" + String(currentMonth));
           Blynk.virtualWrite(V22,!soil_dryness_state);
           Blynk.virtualWrite(V21,!soil_dryness_state);
          }
         
         else// (millis() >= start2 +(periodMinevening_watering*60*1000))  //900000=15min//60000=1min
         {
          startMillisevening_watering=millis();
         digitalWrite(solenoid_vegetable, 1); //low active
         Blynk.virtualWrite(V33,"=เวลา"+String(currentHour)+":"+String(currentMinute)+","+String(monthDay) + "/" + String(currentMonth));
        solenoid_vegetable_button_blynk_v22.off();
         solenoid_vegetable_led_blynk_v21.off();
         } //if((currentHour >17) && (currentHour<18) &&  (periodMillisevening_watering>=10800000));//  10800000ms=3hrs. 
       }
  }
 
         

BLYNK_WRITE(V8) 
  {
   if (param.asInt()==1) 
    {
      if (lamp_hen_blynkV8=0)
         {
          start_hen_lamp=millis() ;
         }  
      if ((millis()-start_hen_lamp) <(open_hen_lamp_period*60*1000))  //900000=15min//60000=1min
         {
           digitalWrite(lamp_hen,0);
          if ((millis()-start_hen_lamp) <(open_hen_lamp_period*60*1000))  //900000=15min//60000=1min
          {
           Blynk.virtualWrite(V34,"*****เหลือเวลาอีก=");
           Blynk.virtualWrite(V34,String((start_hen_lamp +(open_hen_lamp_period*60*1000)-millis())/(1000) )+"วินาที---------------");
            
          }
           lamp_hen_blynk.on();
           lamp_hen_blynkV8=1;
          }
      else
         {
           start_hen_lamp=millis() ;
           digitalWrite(lamp_hen, 1);
           lamp_hen_blynkV8=0;
//         lamp_hen_blynk.off();
           Blynk.virtualWrite(V9,0);
           Blynk.virtualWrite(V8,0);
           Blynk.setProperty(V8,"offLabel","OFF");
         }
           
    }
  else
  {
     start_hen_lamp=millis() ;
     digitalWrite(lamp_hen, 1);
     lamp_hen_blynkV8=0;
//   lamp_hen_blynk.off();
     Blynk.virtualWrite(V9,0);
 //    Blynk.virtualWrite(V8,1);
      
  }

  }
  


BLYNK_WRITE(V26) 
{
if (param.asInt()==1) 
  {
      start_hen_pump=millis() ;
      if ((millis()-start_hen_pump) <(open_hen_pump_period*60*1000))  //
         {
         digitalWrite(hen_water_cooling_pump, 0);
         Blynk.virtualWrite(V30,"=เวลา"+String(currentHour)+":"+String(currentMinute)+","+String(monthDay) + "/" + String(currentMonth));
          pump_hen_blynk_led_v27.on();
         }
  }
 else 
 {     
         digitalWrite(hen_water_cooling_pump, 1);
//         pump_hen_blynkV26=0;
         pump_hen_blynk_led_v27.off();
         Blynk.virtualWrite(V31,"=เวลา"+String(currentHour)+":"+String(currentMinute)+","+String(monthDay) + "/" + String(currentMonth));
 
  }
}

BLYNK_WRITE(V28)
{
  open_hen_pump_period = param.asInt(); // assigning incoming value from pin V1 to a variable
  Serial.print("open_hen_pump_period is: ");
  Serial.println(open_hen_pump_period);
//  open_hen_pump_period = pump_period_Value;
}

BLYNK_WRITE(V29)
{
  temp_start_hen_pump = param.asInt(); // assigning incoming value from pin V1 to a variable
  Serial.print("temp_start_hen_pump is: ");
  Serial.println(temp_start_hen_pump);
//  open_hen_pump_period = pump_period_Value;
}

BLYNK_WRITE(V14) //หลอดไฟไก่เล็ก
{
if (param.asInt()==1)
   
  {
    if (lamp_chicken_blynkV14=0)
    {
        start_chicken_lamp=millis() ;
      
    }  
    if ((millis()-start_chicken_lamp) <(open_chicken_lamp_period*60*1000))  //900000=15min//60000=1min
         {
         digitalWrite(lamp_chick, 0);//เปิด active low}
         lamp_chick_led_v10.on();
          if ((millis()-start_chicken_lamp) <(open_chicken_lamp_period*60*1000))  //900000=15min//60000=1min 
          {
            Blynk.virtualWrite(V35,"*****เหลือเวลาอีก=");
            Blynk.virtualWrite(V35,String((start_chicken_lamp +(open_chicken_lamp_period*60*1000)-millis())/(1000) )+"วินาที---------------");
          }
         lamp_chicken_blynkV14=1;//bool
         }
    else
       {  
         digitalWrite(lamp_chick, 1);
         Blynk.virtualWrite(V10,0);
//         lamp_chick_led_v10.off();
        Blynk.virtualWrite(V14,0);//ใส่//เพื่อให้สามารถรับงานครั้งต่อไปได้อีก
         Blynk.setProperty(V14,"offLabel","OFF");
         lamp_chicken_blynkV14=0;//bool
        start_chicken_lamp=millis() ;
        }
  }
  else
    {
     digitalWrite(lamp_chick, 1);
      Blynk.virtualWrite(V10,0);
    lamp_chick_led_v10.off();
     Blynk.virtualWrite(V14,0);//ใส่//เพื่อให้สามารถรับงานครั้งต่อไปได้อีก
     lamp_chicken_blynkV14=0;//bool
     start_chicken_lamp=millis() ;
      
    }
}

BLYNK_WRITE(V22) 
{
if (param.asInt()==1) {
   digitalWrite(solenoid_vegetable, 0);//active low 24 มิย. 65
   solenoid_vegetable_led_blynk_v21.on();
   Blynk.virtualWrite(V32,"=เวลา"+String(currentHour)+":"+String(currentMinute)+","+String(monthDay) + "/" + String(currentMonth));
  }
else
  {
   digitalWrite(solenoid_vegetable, 1);//active low 24 มิย. 65
   solenoid_vegetable_led_blynk_v21.off();
   Blynk.virtualWrite(V33,"=เวลา"+String(currentHour)+":"+String(currentMinute)+","+String(monthDay) + "/" + String(currentMonth));
  
  }
}

ถ้ามีปัญหา stack overflow จะถามเพื่อนๆอีกทีครับ

ผมได้ใส่การนับเวลาถอยหลังด้วย โดยแสดงใน terminal widget ใน Blynkด้วย

19กค65
มีเรื่องที่กวนใจเดิมๆ คือ มีการหยุดการทำงานของ node1 เมื่อวานตอน 16.50 น. ผมไม่อยู่ที่หน้างาน
เลยไม่ทราบสาเหตุอะไร เรื่อง(1)หนูตอนนี้เข้ามาไม่ได้แล้ว,(2)ไฟเลี้ยง(vcc)จากกราฟก็stableดี,(3)สายไฟทุกจุดเชื่อมต่อผมบัดกรีหมดแล้ว
ดูจากlog มีการทำงานของมอเตอร์ และ pulsein ก็แสดงออกมาเหมือนกัน ก่อนจะค้าง
วันนี้มาดู ทุกอย่างปกติ มีการค้างของไฟเซ็นเซอร์อยู่ น่าจะเป็นจาก stack overflow จากการทำงานที่ถี่เกินไป
สาเหตุเป็นไปได้คือ bounce จาก proximity sensor ที่มากระทำกับ relay ซึ่งทำหน้าที่สวิทช์ตัวหนึ่ง
เรื่องนี้ผมก็รอฟังคำตอบอยู่เหมือนกัน
จริงๆแล้วผมดัก ค่า ด้วย pulsein() น่าจะแก้เรื่อง การกระตุ้นถี่ ได้บ้าง แต่ อาจไม่มีประสิทธิภาพพอ(หรือเปล่า?)
ผมจะลองทำตามกระทู้นี้ตามกระทู้นี้พลางๆ
โดยจะเน้นที่ swithch คือ รีเลย์ที่ส่งสัญญาณ input_pullup แบบผมก็ยอมรับว่า ตอนนี้ งงๆอยู่นะครับ ถ้าจะถามให้ถามแอดมินดีกว่าครับ
สิ่งที่ผมต้องทำความเข้าใจคือรูปนี้


จากรูปนี้ D1 คือไดโอดหรือledใช่ไหมครับ
รูปสวิทช์ ของผมคือรีเลย์ ขา com กับ NO ส่วน คอยล์รีเลย์ ผมต่อไดโอดกันย้อนแล้ว ซึ่งไม่ได้แสดงในรูปนี้



Hardware Debouncing
อันนี้ขอบาย ก่อน, ยากจริงๆ และไม่มี ic ที่ว่า


R-C-Debouncing
R-C Debouncing
อันนี้ พอรู้เรื่องนิดๆ
ลองตัวนี้ดู


20220719_134127
ขอถามว่า 1 ต่อvccไหมครับ 2และ3 มีค่า 10K ใช่ไหมครับ และ 6คือสายที่ต่อ pin ของnodeMCU ที่เรากำหนดเป็น input_PULLUP ใช่ไหมครับ
ขอบคุณครับ


พอดีเจอรูปนี้พอดี น่าจะใช้กันได้


ผมได้ต่อตามนั้นยกเว้น ค่าC ใช้47uF เพราะ1uFไม่มี
ผลปรากฎว่า
มีการจับได้ ของ pulsein() ทุกเซ็นเซอร์ ทำให้มีการปิดเซ็นเซอร์ ทั้งๆที่ ไม่มีเสียงรีเลย์ทำงานผิดปกติ
ผมจึงเอาโค้ด pulsein ออก โดยเปิดเซ็นเซอร์ตลอดเวลา ปรากฎว่า เซ็นเซอร์ทำงานปกติ แต่ ทำงานเพี้ยน คือ เซ็นเซอร์ส่งว่ามีอาหาร(ดูจากไฟled ที่เซ็นเซอร์) แต่ node อ่านผลว่า อาหารหมดครับ
และเซ็นเซอร์อีกถังอาหารมันหมด ไฟled ดับ แต่จากarduino อ่านว่ามี
คือผลเป็นตรงข้ามครับ
สงสัยจากค่า Cที่สูงกว่าที่ระบุ หรือเปล่า …แต่ปรึกษาแล้วไม่น่าเกี่ยว
สรุปแล้ว การต่อ RC debounce วันนี้ของผม ไม่เวอร์ก
อาจมีผิดพลาดตรงไหนสักจุด ผมต้องใช้แบบเดิมไปก่อนครับ คือเอา RC debounce ออกก่อน
ถ้าเพื่อนคนไหนได้ลองทำ RC debounceแล้วใช้งานได้ กรุณาแนะนำผมด้วย…

1 Likes

20กค65
เมื่อวานหลังจากเอาวงจร RC debounce ออก และใส่โค้ดpulsein กลับ ให้เหมือนเดิมทุกอย่าง ถึงวันนี้ node1 ทำงานได้ไม่แฮ้งค์
วันนี้ได้เพิ่ม delay(100) ถัดจากคำส่ง digitalRead, analogread,และ delay(200)สำหรับBlynk_write เพราะผมคิดว่า จะใช้เวลาในการรับข้อมูลบ้าง

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
โดยไม่ทราบสาเหตุ อยากถามเพื่อนๆว่าเป็นเพราะอะไรบ้างครับ

21กค65
วันนี้ผมลอง mcp23017 กับ nodeMCU ตัวใหม่
ครั้งที่1
โดยใช้โค้ดตัวนี้ โดยไม่ได้ต่อ IC mcp23017 เพื่ออยากรู้ว่ามันจะโชว์error ไหม ถ้ามันหา IC mcp23017
ตามหลักแล้ว จะต้องโชว์error เพราะผมไม่ต่อ ใดๆเลย มีแค่ nodeMCU ต่อกับสาย USB

`   /*
Modified on Dec 15, 2020
Modified by MehranMaleki from Arduino Examples
Home
*/



#include <Wire.h>
#include <Adafruit_MCP23X17.h>

// Basic pin reading and pullup test for the MCP23017 I/O expander
// public domain!

// Connect pin #12 of the expander to Analog 5 (i2c clock)
// Connect pin #13 of the expander to Analog 4 (i2c data)
// Connect pins #15, 16 and 17 of the expander to ground (address selection)
// Connect pin #9 of the expander to 5V (power)
// Connect pin #10 of the expander to ground (common ground)
// Connect pin #18 through a ~10kohm resistor to 5V (reset pin, active low)

// Output #0 is on pin 23 so connect an LED or whatever from that to ground
Adafruit_MCP23X17 mcp;
#define lamp 23     // MCP23XXX pin LED is attached to  
void setup() {  
  mcp.begin_I2C();      // use default address 0

  mcp.pinMode(lamp, OUTPUT);

  Serial.begin(9600);
}


// flip the pin #2 up and down

void loop() {
  

  mcp.digitalWrite(lamp, HIGH);
     Serial.println("HIGH");
delay(2000);
  mcp.digitalWrite(lamp, LOW);
     Serial.println("low");
delay(2000);
  }`

เป็นโค้ดสั้นๆ
ผลคือดังรูปครับ
elec10Capture
มันทำงานครับ ไม่โชว์ error เลย
แสดงว่า library ไม่ตรวจสอบให้เราว่า มี mcp ต่อหรือไม่


ครั้งที่2
ใช้โค้ดใหม่

// Blinks an LED 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 LED_PIN 0     // MCP23XXX pin LED 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 Blink Test!");

  // uncomment appropriate mcp.begin
  if (!mcp.begin_I2C()) {
  //if (!mcp.begin_SPI(CS_PIN)) {
    Serial.println("Error.");
    while (1);
  }

  // configure pin for output
  mcp.pinMode(LED_PIN, OUTPUT);

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

void loop() {
  mcp.digitalWrite(LED_PIN, HIGH);
  delay(500);
  mcp.digitalWrite(LED_PIN, LOW);
  delay(500);
}


ถ้าผมไม่ต่อmcp23017จะโชว์ stack overflow และแสดงข้อความ Error

elec11Capture


ถ้าต่อ mcp23017 ก็จะแสดง looping
elec12Capture
ผมเช็กมันจะปล่อย 0 V ที่ขา 0 หรือ GPAO 0 หรือขาลำดับที่ 21(จากรูป) ตอนแรกที่ผมสับสนก็การกำหนดขานี่แหละครับ
สำเร็จแล้วคร้าบบบบบ


ผมลองมาใช้โมดูล mcp23017 สีเขียวที่เคยทำคราวก่อนไม่สำเร็จนั้น
ตอนนี้สำเร็จเหมือนกันครับ(คลิป)
ตอนนี้ดวงเฮงมาเรื่อยๆ 555


เรื่องการกำหนดขา 0-15 ผมเจออีกรูป


เดี๋ยวว่างๆจะลองกำหนด ฝั่ง B บ้าง(8-15)

1 Likes

แต่ต้องระวังนะครับ
ขาของ mcp203017บอบบางมาก หลังจากบัดกรีแล้ว ขามันหักที่โคนแล้ว เสียไปแล้ว 3 ขา

ต่อไปคงไม่เหมาะกับบัดกรีนะครับ…
ผมพยายามบัดกรีต่อขาที่หักก็ไม่ติดครับ …
เสียดาย…

1 Likes

23กค65
หลังจากที่ต่อmcpสำเร็จ แต่ปัญหากวนใจเดิมๆคือ node แฮงค์ ทั้ง2node
node1หลังจากทำงานได้ 1ชั่วโมงกว่าๆ หลังจากนั้น1ชั่มโมง node2 ก็แฮงค์ตาม
mcp ต่อกับnode1 แต่node2 ไม่ได้ต่อกับmcp แต่ใช้แบต จาก 18650 ร่วมกัน
จากดูกราฟ โวลต์ในแอป ไม่ตกครับ อยู่ที่ 3.9-4.1V
เลยไม่รู้ว่าจากสาเหตุใด โดยเฉพาะอย่างยิ่ง node2 ไม่ได้ต่อกับ mcpเลย
วันนี้ลองถอด mcp ออกดูก่อน ดูซิว่าจะแฮงค์ไหม
อัพเดท
ผมไม่ได้ถอดmcp ผมลองปิดสวิทช์ที่ต่อทุกpinกับnodeMCU แล้วผมก็ต่อสายusb จากโน้ตบุก แล้วกดปุ่มรีเซ็ต เพื่อดูใน serial monitor ปรากฎว่า ไม่มีข้อความใดๆ แต่ผมถอดnodeMCU ออกจาก Base ที่นี้หลังกดปุ่มรีเซ็ต มีการโชว์ข้อความการทำงานของ
nodemcu แสดงว่า บอร์ดขยายขาหรือ base มีปัญหา ปัญหาบอร์ดขยายขา นี้ไม่ใช่ครั้งแรก อันนี้ครั้งที่ 3 แล้ว

1 Likes

ลองดูเรื่อง sleep mode ครับ ผมเคยแก้ปัญหากรารีเซตบ่อยๆ โดยที่ ตั้งเวลา ช่วงที่ไม่ได้ใช้งานคือ 18:00 ถึง 5:00 เลย ให้มันหลับไปก่อน มันช่วยเรื่องยืดอายุการทำงาน และ ลดการกินไฟจากแบต ช่วงที่มัน sleep มันจะกินกระแสน้อยกว่า

ขอบคุณครับ

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

ขอบคุณครับ

กำลัง test หาบอร์ดระดับเดียวกัน เพื่อรันแบบยาวๆ เพื่อจบปัญหานี้อยู่เหมือนกันครับ ยังไงก็จะมาอัพเดทในนี้แหละ

ขอบคุณมากครับ

25กค65
2 วันมานี้ โน้คบุคที่เคยใช้ มันเสีย เลยหาโน้ตบุคตัวใหม่ ไม่ได้ใช้นานแล้ว ต้อง update ลง user account windowsใหม่ ซึ่งต้องลงโปรแกรม arduino,library สำหรับ nodeMCU8266 และ esp32 เสี ยเวลาไปครึ่งวัน เหมือนต้องจัดบ้านใหม่หมด

รุ่นไหนเสียครับ อาการเป็นอย่างไร ใช้งานมากี่ปี อยากเก็บเป็นข้อมูลหน่อย

ที่ผมเคยใช้มาก็มี

acer ก็ถือว่าทดทานทีเดียวแต่ผมเป็นคนใช้งานหนักมาก ไม่ใช่เล่นเกมส์ แนวเขียนบอท เขียนโปรแกรมรันสุดๆ 24 ชม เป็นอันว่ารวนๆ ไป

Hp omen ตัวปัจจุบัน ก็ใช้งานมา 5 ปีแล้ว มีปัญหาเรื่องแบตบวมก็ถอดออกเลย ลำโพงแตกอีก แต่ยังใช้งานได้ดีรวดเร็วทันใจ

toshiba รุ่น satellite k20, intel core2 duo , windows7 ครับ
ใช้งานมาหลายปีแล้ว ซื้อมือ2 เมื่อ 5ปีที่แล้ว ใช้งานจริงๆ ใน6เดือนมานี้
ปัญหาคือ คีย์บอร์ดค้าง port usb เสีย เลยสั่งใหม่ มือสอง เป็น core i5 ram8gb ssd128gb ของnec
ราคา5พันกว่าบาท

1 Likes

ถือว่าทนใช้ได้อยู่นะครับ

ผมมี core i7 lenovo ideapad ใส่ ssd1tb(win10) เสียดาย usb port น่าจะมีปัญหา เพราะ มันไม่รู้จัก node mcu เลย ทั้งๆที่ใส่ driver , arduino ide ถูกต้องทุกอย่าง เลยอด
ใช้ ของเกรดต่ำกว่า เก่ากว่า แต่ดันเสียตอนนี้ 555
อย่างตอนนี้ใช้เครื่องที่เสียอยู่ เครื่องมือ2ที่สั่งคงได้มะรืน
เครื่องที่เสียนี้ มันค้างปุ่ม ALT ขนาดผมแกะปุ่มคีย์บอร์ดเดิมจนเกลี้ยงก็ยังไม่หาย ใช้คีย์บอร์ดusbไป ก่อน พลางๆ

1 Likes