นาฬิกาปลุก Oplà
#cloudgames2022
โปรเจคนี้จะเปลี่ยน Arduino Oplà IoT kit ของคุณให้กลายเป็นนาฬิกา ผ่าน Arduino Cloud คุณสามารถเปิด/ปิดการปลุก และเลือกเวลาให้ปลุกได้
การผสานกับสมาร์ทดิสเพลย์แบบโมเดิร์น
นาฬิกาปลุก Oplà ใช้ Arduino Oplà IoT Kit ที่มีความละเอียดสูง มาสร้างเป็นเพื่อนข้างเตียงที่ซิงค์เวลาผ่านอินเทอร์เน็ตและมีฟีเจอร์เพียบ
- การซิงค์เวลาผ่าน NTP: แทนที่จะใช้คริสตัลฮาร์ดแวร์ที่อาจคลาดเวลา Oplà จะเชื่อมต่อกับ เซิร์ฟเวอร์ Network Time Protocol (NTP) ผ่าน WiFi นี่ทำให้มั่นใจว่านาฬิกาจะแม่นยำภายในมิลลิวินาที และปรับเวลาออมแสงอัตโนมัติ
- UI แบบ Capacitive Touch: ควบคุมการตั้งปลุกและค่าต่างๆ ผ่านเซ็นเซอร์สัมผัสวงกลมแบบ capacitive ของ Oplà ตัวทริกเกอร์เหล่านี้ถูกแมปในซอฟต์แวร์เพื่อเปลี่ยนสีวงแหวน RGB และแสดงสถานะการปลุกบน หน้าจอ OLED ขนาด 1.3 นิ้ว ที่คมชัด
การปรับแต่ง
- ผสานกับ Weather API: ตอนตื่นนอน นาฬิกาสามารถแสดงข้อมูลสภาพอากาศปัจจุบันที่ดึงมาจาก API ได้ ให้ประสบการณ์ "สมาร์ทข้างเตียง" ที่ลื่นไหลโดยไม่ต้องพึ่งสมาร์ทโฟน
ตั้งค่าใน Cloud
โปรเจคนี้ใช้ Arduino Cloud ในการตั้งเวลาปลุก ขั้นแรกเลยน้องต้องสร้าง "Thing" ใหม่ขึ้นมาและเพิ่มตัวแปรสองตัวลงไป:
- alarmTime เป็นอ็อบเจ็กต์ประเภท CloudTime มันคือเวลาที่นาฬิกาปลุกจะดัง CloudTime เป็นวิธีติดตามเวลาในหน่วยวินาทีสะสม โดยเริ่มนับจากเที่ยงคืน
- switchAlarm เป็นตัวแปรประเภท bool เป็น True ถ้าตั้งปลุกไว้ และเป็น False ถ้าปิดการปลุก
ด้านล่างน้องจะเห็นภาพตัวอย่างว่า "Thing" ของน้องควรหน้าตาเป็นยังไง ก่อนไปต่อ อย่าลืมแน่ใจว่าได้เชื่อมบอร์ดกับ Thing นี้แล้วนะ

สร้าง Dashboard
เมื่อตั้งค่า "Thing" เสร็จแล้ว น้องก็สามารถสร้าง Dashboard ขึ้นมาได้เลย นี่คือหน้าตาที่ควรจะเป็น:

คอมโพเนนต์ทั้งสองตัวนี้ต้องถูกเชื่อมโยงกับตัวแปรที่พึ่งสร้างไปในขั้นตอน "create Thing" นะตัวนี้
ติดตั้งไลบรารีเพิ่มเติม
ก่อนคอมไพล์โค้ด อย่าลืมติดตั้งไลบรารีและ dependencies ของมันใน Arduino IDE ให้ครบ:
- Arduino_MKRIoTCarrier
- RTCZero
ตั้งค่า Secrets
เปิดไฟล์ arduino_secrets.h แล้วกรอกข้อมูลลงในช่องเหล่านี้:
- SECRET_SSID
- SECRET_PASS
ด้วยข้อมูลเครือข่าย Wi-Fi ของน้อง
น้องยังต้องเชื่อมบอร์ดเข้ากับ Arduino Cloud ด้วย ต้องกรอกข้อมูลในช่องต่อไปนี้:
- THING_ID
- BOARD_ID
ด้วยโทเค็น "Thing ID" และ "Device ID" ที่หาได้จากหน้า "Thing"
คอมไพล์ Sketch
เตรียมตัวให้พร้อมแล้วน้อง เชื่อมต่อ Oplà กับคอม แล้วอัปโหลดโค้ดไปเลย!
อธิบายซอฟต์แวร์แบบย่อๆ
โค้ดนี้ใช้ Real-Time Clock (RTC) ภายในบอร์ดเพื่อจับเวลาอย่างแม่นยำ เวลาที่ถูกต้องจะถูกดึงมาจากเซิร์ฟเวอร์ Network Time Protocol (NTP) หลังจากที่เชื่อมต่อ Wi-Fi ได้แล้ว พอตั้งเวลาเสร็จก็ไม่ต้องต่อ Wi-Fi แล้วก็ได้ โปรแกรมจะคอยตรวจสอบว่าเวลายังตรงอยู่หรือเปล่า โดยจะไปถามเซิร์ฟเวอร์ NTP เป็นระยะๆ
Arduino Cloud จะเป็นตัวให้เราปิด/เปิดนาฬิกาปลุก และเปลี่ยนเวลาปลุกได้
ในรูปด้านล่างจะเห็นสถานะต่างๆ ของบอร์ด: เปิด/ปิดนาฬิกาปลุก และเปิด/ปิด Wi-Fi เวลาสีแดงคือเวลาปลุกที่ตั้งจาก Arduino Cloud

โปรแกรมใช้ time interrupts เพื่อให้ปลุกตรงเวลาเป๊ะๆ ฟังก์ชันนี้มาจาก RTC ภายในเลย:
void setAlarm() {
rtclock.disableAlarm();
rtclock.detachInterrupt();
if (switchAlarm) {
uint alarm_time_second = alarmTime;
uint raw_minutes = alarm_time_second / 60;
uint8_t clock_hour = raw_minutes / 60 - GMT;
uint8_t clock_minute = raw_minutes % 60;
if (clock_hour >= 24) {
clock_hour -= 24;
} else if (clock_hour < 0) {
clock_hour += 24;
}
rtclock.setAlarmTime(clock_hour, clock_minute, 0);
rtclock.enableAlarm(rtclock.MATCH_HHMMSS);
rtclock.attachInterrupt(alarmMatch);
Serial.println("Alarm set");
return;
}
Serial.println("Alarm UNset");
}
ฟังก์ชัน setAlarm จะทำงานทุกครั้งที่มีการเปลี่ยนเวลาปลุก สองคำสั่งแรกที่เรียก RTC:
rtclock.disableAlarm();
rtclock.detachInterrupt();
คือการล้าง interrupt ที่อาจจะค้างอยู่ก่อนหน้า
จากนั้น ถ้านาฬิกาปลุกถูกเปิด:
rtclock.setAlarmTime(clock_hour, clock_minute, 0);
rtclock.enableAlarm(rtclock.MATCH_HHMMSS);
rtclock.attachInterrupt(alarmMatch);
interrupt จะถูกตั้งให้ทำงานเมื่อเวลาตรงกับชั่วโมง นาที และวินาทีที่กำหนด แบบนี้มันจะปลุกซ้ำทุกวันเลย
เสียงปลุกมาจากบัซเซอร์ที่อยู่บน Oplà carrier board (ใช่แล้ว! บอร์ดมันมีบัซเซอร์ด้วย!) วิธีสั่งให้มันดังแบบนี้:
if (play_alarm) {
if ((current_millis - prev_sound > 1000)) {
prev_sound = current_millis;
tone(carrier.Buzzer.getPin(), 500, 500);// async
}
}
บัซเซอร์จะหยุดดังเมื่อกดปุ่มใดก็ได้บน Oplà carrier:
carrier.Buttons.update();
if (carrier.Buttons.onTouchUp(TOUCH0) or
carrier.Buttons.onTouchUp(TOUCH1) or
carrier.Buttons.onTouchUp(TOUCH2) or
carrier.Buttons.onTouchUp(TOUCH3) or
carrier.Buttons.onTouchUp(TOUCH4)
) {
Serial.println("Touched Down a button");
play_alarm = false;
}
สุดท้าย จอ Oplà จะถูกอัปเดตโดยออบเจกต์ที่รับผิดชอบในการพิมพ์เวลาและเลื่อนแถบวินาที ไม่ต้องลงรายละเอียดมาก สิ่งสำคัญคือมันจะถูกอัปเดตในลูปหลักทุกๆ วินาที:
if ((current_millis - date_previous_millis) >= date_interval) {
date_previous_millis = current_millis;
screen.render();
}
ตั้งค่าโซนเวลาของคุณ (Set your timezone)
นาฬิกา RTC ข้างในนี่มันตั้งเวลาเป็น Greenwich Mean Time (GMT) นะน้อง บางทีเราก็ต้องปรับให้ตรงกับประเทศเราซักหน่อย วิธีปรับก็ง่ายๆ แก้ไขในไฟล์หลัก opla_alarm.ino แบบนี้เลย:
const int GMT = +7; // ตัวอย่างสำหรับประเทศไทย (UTC+7)
ขอบคุณพี่ๆ ทุกคน (Special Thanks)
โปรเจคนี้พี่ทำส่งเข้าประกวด Arduino Cloud Challenge 2022 ครับ ขอบคุณ Arduino ที่ให้โอกาสได้ลงสนามด้วยนะ!
อยากช่วยพัฒนาต่อ (Contribution)
สเก็ตช์โค้ดเต็มๆ และโปรเจคอื่นๆ ที่เกี่ยวข้อง พี่เก็บไว้ในที่เก็บโค้ดส่วนตัวนะ (บน GitHub) ใครอยากฟอร์กไปเล่นต่อ หรือช่วยพัฒนาก็เชิญตามสบายเลยจ้า