สงสารผมหน่อยครับ หลายคนมาซื้อของคงเป็นในระดับหนึ่ง สงสารผมหน่อยครับ
ลงทุนซื้อบอร์ด arduino + RTC d3231 น่าจะเสียเงินป่าว
จุดประส่งค์ ผมเขียนเช็คไฟบ้าน ถ้าไฟดับให้หน่วงเวลา 10 นาทีแล้วจาก relay ถ้าไฟมาหน่วงเวลา 2 นาที ต่อ relay
ใช้ millis() ตามเนต ผมทดลองแล้ว เจอปัญหาเวลาไม่ตรง และถ้าไฟติดดับบ่อยๆ มันรวนไม่หน่วงเวลาแล้ว
ใช้ rtc เจอปัญหา ไม่มีโค้ดตัวอย่าง การแปลงเวลาเป็น timestamp เพื่อคำนวณเวลาไฟมาและไฟดับ
ค
ถ้าไฟดับแนะนำให้ใช้ RTC โคดตัวอย่างสำหรับ Arduino มีหลายตัวอย่าง
ในตัวอย่างที่หน้าบทความก็มีนะครับ ศึกษาอีกซักนิดหน่อย ค่าที่ได้เป็น ชั่วโมง นาที วินาทีอยู่แล้ว ยิ่งถ้าหน่วง 2 นาที ใช้ if เช็คแค่ค่านาทีก็ใช้ได้แล้ว เขียนประมาณ 5 บรรทัดก็ได้แล้ว ไม่มีอะไรยากเกินความพยายามครับ
ผมลองแล้วครับ เอา วินาที มันวิ่ง 0 -59 แล้วก็วิ่งกลับมาเหมือนเดิมครับ
ผลคือ realay เปิด-เปิด ตามเวลาที่วิ่ง
เพราะตัวแปรที่ได้มาเก็บค่าเวลาที่วน
ผมพยายามแก้ โดยเปลี่ยนเป็น timestamp เพื่อให้เดินตลอด แล้วพยายามหาโคด loop ที่ loop รอเวลา
จากเวลาเดิมแล้วเพิ่มไปจนถึงเวลาที่ต้องการแล้วหลุดออกจาก loop แล้วค่อยไปทำงานตามโค๊ดที่เหลือ
ตอนนี้ยังหาตัวอย่างไม่ได้ครับ
ลองดูตัวอย่างที่ให้ไปครับ ตรงบรรทัด
/* ตั้งเวลา ในตัวอย่างนี้ เซตค่าเป็นเวลา 23:09 ถ้าถึงเวลานี้จะให้ทำงานที่ฟังก์ชัน RTC.setAlarm1Simple(23, 9); if (RTC.checkIfAlarm(1)) { Serial.println("Alarm Triggered"); }*/
กับอีกคำสั่งสำหรับยกเลิกการตั้งเตือน
RTC.turnOffAlarm();
จากโค๊ด เป็นการตั้งเวลาที่แน่นอน ไฟดับหรือไฟตก เป็นเวลาที่ไม่แน่นอน
ถ้าใช้ฟังชั่นนี้จริง ต้องเก็บเวลาปัจจุบัน แล้วบวกเวลาที่ต้องการหน่วง ซึ่งตรงนี้ต้องเขียนฟังชั่น บวกเวลาในรูปแบบ 0-24 น. ถ้าเขียนฟังชั่นใน arduino ยากพอควร เพราะผมพึ่งห้ด
แต่ถ้าเป็นภาษาอื่นเช่น php จะง่ายมาก แค่เปลี่ยนเป็น timestamp แล้ว บวกเวลาที่ต้องการ แล่วแปลงเป็นรูปแบบเวลาที่ต้องการ แล้าเอาไปใส่ ตรง RTC.setAlarm1Simple(23, 9); ตรงนี้ได้เลย ปัญหาคือไม่สามารถคำนวณเวลามาใส่ได้
ผมลองทำ loop รอแล้ว แต่เจอปัญหาอีก ถ้าเหตุการณ์เปลี่ยนก่อนจบ loop แล้ว ไม่สามารถออกจาก loop ได้ทันที คงต้องพยายาม เอาเวลาจาก D3231 ให้ได้เพราะ เวลายังไม่ได้ เปลี่ยน เหตุการณ์ ก็ไปทำตามเงือ่นไขใหม่ ที่จริง ถ้าเปลี่ยนเวลาเเหมือน php ได่ ก็ง่ายครับ
unsigned long timer; // the timer
unsigned long INTERVAL_5 = 60000*2;// 2 นาที
void setup() {
Serial.begin(9600);
}
void loop() {
Serial.println("Wait.....");
// ส่วน loop จะไปเช็ค input ไฟดับไฟมา ก้ได้ครับ
if(ไฟดับ)
{
/////////////////////// ทุกๆ 2 นาที จะพิมพ์ INTERVAL_1
if( (millis() - timer) > INTERVAL_5 )
{
Serial.println("INTERVAL_1");
timer = millis(); // สั่งให้ start timer
}
////////////////////////////////////////////////////
}//end if(ไฟดับ)
}
เพื่อมีประโยชน์ครับ น่าจะนึกออกแล้วนะ
ขอบคุณมากครับ
เผื่อเป็นประโยชน์ กับผู้มาอ่านต่อไป
โค้ดข้างตอน ผมลองในตอนแรกครับ คือ แรกๆ ก็จะทำงานได้ถูก แต่ถ้าทิ้งไว้นานๆ millis เวลา มันเดินตลอด เมื่อเช็คเหตุการณ์ใหม่ เวลาก็ไม่ได้ เหมือนที่ต้องการ นี้คือที่ผมบอกเวลาไม่ตรง
ตอนนี้แก้ได้แล้วครับ ใช้ loop วินาทีเอาครับ
if(checkPower== 1){
for(int i = 60; i > 0; i--) {
delay(1000);// ถ้าปรับเกิน 1 วินาที เวลาจะค่อยๆคลาดเคลื่อนทีละน้อย 1000 ตรงที่สุด
if(i > 1){
Serial.print("Count Down ");
Serial.println(i);
}else Serial.println("");
if(int a= digitalRead(inPin) == 0 && (millis() - lastDebounceTime) > debounceDelay ){ //ถ้าไม่มีการเช็คเวลา ถ้าเช็คแล้วมีการเปลี่ยน ระหว่าง 1 หรือ 0 อย่างรวดเร็ว โปรแกรมค้าง แล้ะถ้ามีการเปลี่ยนแปลงเหตุการณ์ให้ออกจาก loop ไปทำเงื่อนไขใหม่ ตามที่ต้องการ
Serial.print("Interrup=");
Serial.println(a);
lastDebounceTime = millis();
break;
}
}
if(int a= digitalRead(inPin) == 1 && (millis() - lastDebounceTime) > debounceDelay){
digitalWrite(ledPin, HIGH);
digitalWrite(R, LOW);
Serial.println("On");
lastDebounceTime = millis();
}
delay(1000);
}
เจ้าของร้านนี้ดีมากครับ ตอบทุกคำถาม เอาใจใส่ ไม่ห่วงความรู้ ขอบคุณมากครับ ฝากคนอ่านอุดเหนุนร้านนี้หน่อยนะครั
ครับจากปัญหาที่บอกมาแต่ตอนแรก ว่า คำสั่ง delay กับ mills ใช้ไม่ได้เพราะต้องการความแม่นยำ และมี RTC อยู่ในมือแล้ว จึงแนะนำให้ใช้โคดจาก RTC และชี้จุดให้ลองเล่นแล้ว ถ้าทำได้แล้วก็ยินดีด้วยครับ : )