CAT LoRa Starter Kit ตอนที่ 8 เปิด-ปิดหลอด LED ผ่านเครือข่าย LoRa by CAT
บทความนี้จะเป็นการประยุกต์การใช้งานโมดูล RTC (DS3231) จากบทที่แล้ว โดยเราจะเขียนโปรแกรมกำหนดช่วงเวลาเริ่มต้นและสิ้นสุดสำหรับการเปิด-ปิดหลอดไฟ LED โดยช่วงเวลาการเปิด-ปิดจะถูกส่งมาจากเครือข่าย LoRa by CAT
ความต้องการของระบบ
ตั้งเวลาเปิด-ปิดหลอดไฟ LED ผ่านเครือข่าย LoRa by CAT ได้
อุปกรณ์
- CAT LoRa Starter Kit
- DS3231 Module
- Red LED
- Green LED
- 330 ohm resistor
การต่อวงจร
Library ที่จำเป็น
- SmartEverything HTS221 : https://github.com/ameltech/sme-hts221-library
(เนื่องจากมีการใช้ CatLoRaS76S จากตอนที่ 4 ) - DS3231 Real-Time Clock : https://github.com/jarzebski/Arduino-DS3231
ออกแบบ Payload Format
Payload ที่เราจะใช้สำหรับการตั้งค่าวันและเวลาในการเปิด-ปิดหลอด LED เพื่อให้เข้าใจได้ง่าย เราจะออกแบบ Format โดยใช้เลขฐานสิบทั้งหมดโดยมีขนาดข้อมูลรวมทั้งสิ้น 14 บิตโดยมี Format ดังนี้
- เริ่มต้น (7 บิต) → 2020–01–24 12:10:59 →
20200124121059
- สิ้นสุด (7 บิต) → 2020–01–24 14:30:00 →
20200124143000
- จากนั้นนำวันและเวลาทั้งสองมาต่อกันจะได้ Payload คือ
2020012412105920200124143000
เขียนโปรแกรม
ทดลองส่งข้อมูล Downlink จาก LoRa by CAT
กำหนดให้
- เริ่มเปิดเวลา 2020–01–23 09:10:59 ถึง 2020–01–23 14:30:00
- Payload คือ
2020012309105920200123143000
เราสามารถทดลองส่ง Payload มายัง Node ของเราได้ที่
Test Downlink : https://loraiot.cattelecom.com/portal/home/downlink
อธิบายการทำงาน
ในการเขียนโปรแกรมนี้ผมได้นำ Library จากบทความเก่าเข้ามาใช้งาน ประกอบด้วย
- CatLoRaS76S.h ที่ใช้สำหรับการเชื่อมต่อกับเครือข่าย LoRa by CAT
- LedModule.h ที่ใช้ในการควบคุมหลอดไฟ LED
และทำการสร้าง DateTimeLib.h ขึ้นใหม่เพื่อใช้ในการเปลี่ยนวันที่และเวลาให้อยู่ในรูปแบบของ UNIX TIME ทำให้ง่ายต่อการเปรียบเทียบวันที่เพราะมีค่าเป็นตัวเลขจำนวนเต็ม (uint32_t)
ไฟล์หลัก content-catlora-lab8.ino
ในส่วนของฟังก์ชั่น setup() เราจะทำการตั้งค่าและเปิดใช้งานอุปกรณ์
1.เปิดใช้งาน LED Module และเริ่มการตั้งค่าระบบด้วยการเปิดไฟ Red Led
// Initialize LED
redLed.begin();
greenLed.begin(); redLed.on();
2.เปิดใช้งานตัวควบคุมเวลา RTC Module (DS3231) และตั้งเวลาใหม่ทุกครั้งที่มีการเชื่อมต่อกับคอมพิวเตอร์เพื่อให้ได้เวลาปัจจุบัน แต่ถ้าต่อจากแหล่งจ่ายไฟโดยตรงจะไม่มีการตั้งเวลาใหม่ ตัวโมดูลจะใช้เวลาที่เดินอยู่ในตัวโมดูลทันที
// Initialize DS3231
Serial.println("Initialize DS3231");
clock.begin(); if (clock.isReady() && Serial) {
clock.setDateTime(__DATE__, __TIME__);
}
3.เปิดใช้งานและเชื่อมต่อ LoRa by CAT
// Initialize LoRa
Serial.println("-> Lora Setting...");
lora.begin(115200);
Serial.println("-> Lora ABP Join...");
lora.joinABP(String(LORA_ABP_CLASS),
String(LORA_DEV_EUI),
String(LORA_DEV_ADDR),
String(LORA_NWKS_KEY),
String(LORA_APPS_KEY));
4.ทำการแปลงค่าวันเวลาการเปิดปิดหลอดไฟที่ได้ตั้งไว้เริ่มต้นให้อยู่ในรูปแบบของ UNIX TIME ด้วย DateTimeLib.h เพื่อให้ง่ายต่อการเปรียบเทียบเวลาปัจจุบันกับ RTC Module และการแปลงค่ารอไว้นี้มีผลต่อความเร็วในการทำงาน เพราะไม่ต้องแปลงค่าทุกครั้งที่มีการเปรียบเทียบทำให้สามารถทำงานได้เร็วขึ้น
// Convert datetime setup led to unixtime
startLedUnixtime = DateTimeLib::unixtime(startLedTime);
stopLedUnixtime = DateTimeLib::unixtime(stopLedTime);
5.เมื่อการตั้งค่าเสร็จสิ้นจะทำการปิดหลอดไฟ Red Led
redLed.off();
Serial.println("-> Ready Go.");
ในส่วนของฟังก์ชั่น loop() เป็นส่วนของการทำงานหลักทั้งหมดของระบบประกอบ
เราจะทำการควบคุมเวลาให้ระบบทำงานทุก ๆ 1 วินาที โดยใช้เวลาจาก DS3231 และแสดงค่าเวลาปัจจุบันบนหน้าจอ Terminal
void loop() {
dt = clock.getDateTime();
if (dt.second != seconds) {
seconds = dt.second; // ----- Show current datetime on terminal
String datetime = String(clock.dateFormat("Y-m-d H:i:s", dt));
Serial.println(datetime);
// Main Code Area
}
}
ในส่วนของ //Main Code Area
จะมีการทำงานหลัก ๆ ด้วยกัน 3 แบบคือ
1.ควบคุมการเปิด-ปิดหลอดไฟ LED โดยเช็คจากเวลาปัจจุบัน ถ้าอยู่ระหว่าง startLedUnixtime และ stopLedUnixtime ให้ทำการเปิดไฟ
// ----- Convert current datetime to unixtime -----
uint32_t utNow = DateTimeLib::unixtime(
dt.year,
dt.month,
dt.day,
dt.hour,
dt.minute,
dt.second);// ----- Check datetime for action -----
if (utNow >= startLedUnixtime && utNow <= stopLedUnixtime) {
greenLed.on();
} else {
greenLed.off();
}
2.ส่งข้อมูลบางอย่างไปยัง Network Server ผ่านเครือข่าย LoRa by CAT เนื่องจากถ้าเราไม่ส่งข้อมูลอะไรเข้าระบบเราจะไม่สามารถรับค่าที่เก็บไว้ใน Downlink ได้ แต่เนื่องจากข้อกำหนดของเครือข่าย LoRa by CAT ได้มีข้อกำหนดว่าการส่งข้อมูลขึ้นระบบในแต่ละครั้งต้องมีระยะห่างไม่น้อยกว่า 20 วินาที ดังนั้นในที่นี้จึงเขียนควบคุมให้ส่งทุก ๆ วินาทีที่ 30 และ 60 uint8_t intervalLoraTX = 30;
// ----- LoRa TX -----
if (seconds % intervalLoraTX == 0) {
loraTransmit();
}
3.อ่านค่าตอบกลับจาก Network Server ผ่านเครือข่าย LoRa by CAT (ที่เราได้ส่งไว้ในข้อที่ 2) เพื่อรับข้อมูล Payload ของ Downlink ที่ใช้สำหรับการตั้งค่าวันเวลาเริ่มต้นและสิ้นสุด แล้วทำการแตกข้อมูลตาม Format ที่เราออกแบบไว้ เก็บค่าข้อมูลที่ได้เข้าสู่ตัวแปล startLedUnixtime และ stopLedUnixtime
// ----- LoRa RX -----
if (seconds % intervalLoraRX == 0) {
loraReceive();
}
ดาวน์โหลดไฟล์ตัวอย่าง
บทความนี้ก็ขอจบเพี่ยงเท่านี้ครับ ในบทความหน้าจะเป็นการเปลี่ยนจากหลอด LED เป็น Relay Module เพื่อใช้สำหรับการควบคุมเครื่องใช้ไฟฟ้าบ้านครับ