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

หลักการคือคาบเวลาของน้ำขึ้นน้ำลงถูกกำหนดโดยการปรากฏโคจรของดวงจันทร์รอบโลก มันเลยค่อนข้างแน่นอนและมีค่าเป๊ะๆ อยู่ที่ 12 ชั่วโมง 25 นาที 14 วินาที ถ้าน้องรู้วันที่และเวลาปัจจุบัน รวมถึงวันที่และเวลาของน้ำขึ้นครั้งก่อนหน้า น้องก็คำนวณสถานะน้ำขึ้นน้ำลงปัจจุบันได้เลย
The Lunar Harmonic Cycle
น้องใช้ millis() แบบปกติทำนายน้ำขึ้นน้ำลงไม่ได้นะ น้ำทะเลไม่ได้เชื่อฟังดวงอาทิตย์รอบ 24 ชั่วโมง มันเชื่อฟังดวงจันทร์ต่างหาก เวลาเฉลี่ยระหว่างน้ำขึ้นสองครั้งคือ 12 ชั่วโมง 25 นาที และ 14 วินาที พอดี (องค์ประกอบน้ำขึ้นครึ่งวันเรียกว่า M2) Arduino จะเชื่อมต่อกับโมดูลนาฬิกาจริง (RTC) เพื่อรับค่าวันที่และเวลาจริงมา ตัวโค้ด C++ จะใช้จุดอ้างอิง "Known High Tide" ที่กำหนดไว้ล่วงหน้า (เช่น น้ำขึ้นเป๊ะๆ เมื่อวันที่และเวลานี้ของเดือนที่แล้ว) จากนั้นเครื่องยนต์ทางคณิตศาสตร์จะคำนวณมอดุลัส: secondsSinceAnchor % (12 * 3600 + 25 * 60 + 14) ผลลัพธ์จากการคำนวณนี้จะบอก Arduino ว่า ณ ตอนนี้ระดับน้ำอยู่ตรงไหนในวัฏจักรน้ำขึ้นน้ำลงของโลกจริงๆ
วิธีใช้นาฬิกาน้ำขึ้นน้ำลง
อินเทอร์เฟซของนาฬิกาประกอบด้วยจอแสดงผลกราฟิกและปุ่มกดสี่ปุ่มที่มีป้ายกำกับว่า Mode, Select, + และ -
ปุ่ม Mode ใช้สำหรับสลับแสดงหน้าจอใดหน้าจอหนึ่งจากทั้งหมดห้าหน้าจอ
หน้าจอแรกแสดงสถานะน้ำขึ้นน้ำลงปัจจุบันบนหน้าปัดนาฬิกากลมที่มีเข็มเดียวหมุนรอบหน้าปัดในเวลา 12h 25m 14s ขีดแบ่งแต่ละขีดประมาณหนึ่งชั่วโมง

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

สองหน้าจอนี้ทำให้น้องไม่เพียงรู้ระดับน้ำขึ้นน้ำลง แต่ยังรู้ด้วยว่าทะเลกำลังขึ้นหรือลง หน้าจอที่สองยังทำให้น้องรู้เวลาน้ำขึ้นและน้ำลงคร่าวๆ อีกด้วย
Graphing the Sine-Wave
การเขียนข้อความมันน่าเบื่อ น้ำขึ้นน้ำลงต้องมีคลื่นให้เห็นสิ ใช้เรขาคณิตพิกัด Arduino จะพล็อตคลื่นไซน์เรียบๆ ผ่านหน้าจอ มันจะแมปเฟสทางคณิตศาสตร์ปัจจุบันไปยังคลื่น และวาดตัวชี้ไว้บนเส้นโค้งพอดี แสดงให้เห็นชัดๆ ว่าตอนนี้น้ำกำลังไหลเข้าหรือไหลออก
หน้าจอที่สามแสดงข้างขึ้นข้างแรมของดวงจันทร์ เนื่องจากมันเกี่ยวข้องกับน้ำขึ้นน้ำลงน้อยมาก มันเลยเป็นตัวเลือกเสริม ถ้าจะเอามันออก ก็แค่คอมเมนต์หรือลบบรรทัดที่ 5 ของโปรแกรมออก (//#define MoonDisplayActive) รุ่นพี่เพิ่มหน้าจอนี้เพราะมีองค์ประกอบทุกอย่างพร้อมแล้ว

หน้าจอที่สี่ให้น้องตั้งค่านาฬิกาจริง (RTC) วันที่และเวลาปัจจุบันจะแสดงขึ้นมา และน้องสามารถปรับค่าต่างๆ (ปี, เดือน, วัน, ชั่วโมง, นาที) ได้โดยเลือกด้วยปุ่ม Select และแก้ไขด้วยปุ่ม + และ -

หน้าจอสุดท้ายใช้สำหรับตั้งวันที่และเวลาของน้ำขึ้นครั้งก่อนหน้า ซึ่งเรียกว่าน้ำขึ้นอ้างอิง (reference high tide) ในวิธีเดียวกัน มันอาจจะเกิดขึ้นเมื่อวานหรือนานกว่านั้นก็ได้ ไม่มีผล เพราะคาบเวลาน้ำขึ้นน้ำลงมันค่อนข้างนิ่งมาก
แต่ต้องระวังกฎ 2 ข้อนะน้อง:
- เวลาน้ำขึ้นอ้างอิง (reference high tide) ต้องเกิดขึ้นที่ตำแหน่งเดียวกับที่เราตั้งนาฬิกาไว้ เพราะน้ำขึ้น-น้ำลงไม่ได้เกิดพร้อมกันทุกจุดบนชายฝั่ง
- การปรับเวลาให้เป็นช่วงฤดูร้อน (summer time correction) ต้องเหมือนกันทั้งเวลาปัจจุบันและเวลาน้ำขึ้นอ้างอิง วิธีที่ง่ายสุดคือไม่ต้องปรับอะไรเลย

สามารถถอดปลั๊กไฟนาฬิกาได้ตลอดเวลา พอจ่ายไฟกลับมา ระดับน้ำปัจจุบันจะอัปเดตถูกต้อง เพราะข้อมูลน้ำขึ้นอ้างอิงถูกบันทึกไว้ใน EEPROM และเวลาปัจจุบันถูกเก็บรักษาไว้โดยแบตเตอรี่ใน RTC
ความแม่นยำ
นาฬิกาน้ำขึ้นตัวนี้มีความเสถียรระยะยาวดีมาก เพราะใช้หลักการการโคจรปรากฏของดวงจันทร์ แต่ว่าดวงจันทร์ไม่ใช่สาเหตุเดียวของน้ำขึ้น-น้ำลง มันเลยมีความแม่นระยะสั้นค่อนข้างต่ำ สาเหตุหลักมี 2 ข้อ:
- ดวงอาทิตย์ก็มีส่วนทำให้เกิดน้ำขึ้น-น้ำลงด้วย และมันรบกวนจังหวะที่ควรจะเป็น
- ดวงจันทร์โคจรเป็นวงรี ความเร็วการโคจรเลยไม่คงที่ (กฎของเคปเลอร์)
ความคลาดเคลื่อนระยะสั้นอาจสูงได้ถึงชั่วโมงครึ่ง แต่ปกติจะน้อยกว่านั้นมาก หวังว่ารุ่นน้องคนเก่งจะคิดสมการมาปรับปรุงความแม่นระยะสั้นได้นะ
ฮาร์ดแวร์ & ฐานชิ้นส่วนทางทะเล
นาฬิกาตัวนี้สร้างขึ้นรอบบอร์ด Arduino Nano Every แต่บอร์ด Arduino รุ่นอื่นก็ใช้ได้ ถ้าจะคำนวณซับซ้อนกว่านี้ ลองมอง Arduino Mega หรือ ESP32 ดู
จอแสดงผลเป็นจอกราฟิกขาวดำควบคุมผ่าน I2C (OLED01 ขนาด 0.96") แต่จะเลือกจอใหญ่กว่านี้ก็ได้ เช่น จอสี TFT LCD แบบ SPI ขนาด 1.8" หรือ 2.4" เพื่อวาดกราฟน้ำขึ้น-น้ำลงให้สวยงาม จะเลือกความละเอียดอื่นก็ได้ โปรแกรมจะปรับให้อัตโนมัติ ต้องใช้ voltage translator ด้วย เพราะแรงดันทำงานของจอต่ำกว่า (3.3V) แรงดันของบอร์ด Arduino (5V) ต้องปรับบรรทัดที่ 12 ของโปรแกรมให้ตรงกับจอของตัวเอง โดยเฉพาะตัวควบคุมจอ (display controller): SH1106, SSD1306...
ใช้ Real Time Clock (RTC) เพื่อรู้วันที่และเวลาปัจจุบัน พี่ใช้ DS1302 ขับด้วยอินเทอร์เฟซอนุกรม 3 สายและมีแบตเตอรี่สำรอง โมดูล DS3231 I2C RTC ก็เป็นอีกตัวเลือกที่ดีมากสำหรับความแม่นยำสูง
สุดท้าย ปุ่มกด 4 ปุ่มให้เลือกจอแสดงผลและปรับนาฬิกา: โหมด, เลือก, + และ - ระบบใช้ Power Bank 5V ที่เชื่อถือได้ เป็นแหล่งจ่ายไฟ เพื่อให้คำนวณได้ต่อเนื่องไม่รู้จบ อยู่ในเคสอะคริลิค
ซอฟต์แวร์
โปรแกรมใช้ไลบรารี 3 ตัวที่ติดตั้งได้ผ่าน Library Manager: u8g2 โดย oliver สำหรับควบคุมจอแสดงผล NeiroN's RTClib สำหรับควบคุม RTC ไลบรารีนี้มีฟังก์ชันคำนวณเวลาที่มีประโยชน์มาก พี่ใช้มันโดยเฉพาะเพื่อคำนวณความแตกต่างระหว่างวันที่ปัจจุบันกับวันที่น้ำขึ้นอ้างอิง arduino fsm โดย Jon Black ไลบรารีนี้ช่วยให้ติดตั้ง Finite State Machine (FSM) ได้ พี่ใช้มันเพื่อสลับผ่าน 5 หน้าจอด้วยปุ่ม Mode และรีเฟรช 2 หน้าจอนาฬิกาทุก 10 วินาที
พี่ใช้ไลบรารีที่สี่ซึ่งติดตั้งมาล่วงหน้าแล้ว: EEPROM เพื่อบันทึกข้อมูลน้ำขึ้นอ้างอิงตอนที่ไฟนาฬิกาน้ำขึ้นดับ
ถ้าอยากเข้าใจว่าโปรแกรมทำงานยังไง มันเป็นแบบ self-documented อยู่แล้ว เพราะชื่อฟังก์ชันและตัวแปรบอกตัวเองได้ และมีคอมเมนต์อธิบายไว้เยอะ
สรุป
ขอให้น้องๆ ลงทะเลแล้วได้ปลาดีๆ กลับบ้านกันทุกคนนะ สู้งานนะน้อง!