ไอเดียนี้ได้แรงบันดาลใจมาจาก Arduino Solar tracker วัยรุ่นทุกคนคงรู้ดีว่าดอกทานตะวันเนี่ยมัน 'ตาม' ดวงอาทิตย์ใช่ปะ? ตัวติดตามแสงของพี่ก็จะทำงานคล้ายๆ กันเลย ตามแสงไปซะ!

อุปกรณ์ที่ต้องใช้ (Hardware components)

- Arduino Uno/ Nano
- Solderless Breadboard - Mini
- Servo Motor SG-90
- LDR (Light Dependent Resistor) (x2)
- ตัวต้านทาน (Resistor) (x2) - 10kΩ
- สายจัมเปอร์ผู้ชาย-ผู้ชาย (Male-to-Male Jumper wire) (x9) - 10cm
- สายจัมเปอร์ผู้หญิง-ผู้หญิง 2 ขา (2 pin Female-to-Female Jumper wire) (x2) - 70cm
- ตัวกั้นที่พิมพ์จากเครื่องพิมพ์ 3D หรือทำจากกระดาษแข็ง (ดูรายละเอียดในส่วน 'Setup')
การจัดตั้ง (Setup)


การจัดตั้งของน้องต้องออกมาคล้ายๆ ในรูปข้างบนนะ อย่าให้เพี้ยน!
การต่อวงจร (Connections)
Servo Motor (SG-90)
- ขา S (สายสีเหลือง/ส้ม) - ต่อกับ D9
- ขา (+) (สายสีแดง) - ต่อกับ 5V
- ขา ( - ) (สายสีดำ/น้ำตาล) - ต่อกับ Ground (GND)
LDR
- ตัวแรก - ต่อกับ A0
- ตัวที่สอง - ต่อกับ A1
ต่อขาหนึ่งของ LDR กับไฟ 5V และอีกขากับตัวต้านทาน 10kΩ อีกขาของตัวต้านทานต้องต่อกับกราวด์ ส่วนจุดที่ต่อกับพอร์ต (A0/A1) ต้องอยู่ตรงรอยต่อระหว่างตัวต้านทานกับ LDR นะ ห้ามช็อตนะตัวนี้!
เขียนโค้ด (Coding)
สำหรับโปรเจคนี้ น้องต้อง include library ชื่อ 'Servo' เข้ามาในสเก็ตช์ด้วย ใครยังไม่เคยใช้หรืออยากรู้ว่ามีฟังก์ชันอะไรบ้าง ก็ลองไปหาอ่านเพิ่มเติมได้
ขั้นแรกให้สร้าง Servo object ขึ้นมาควบคุมเซอร์โว และสร้างตัวแปรชื่อ 'pos' ไว้เก็บตำแหน่งเซอร์โว ตำแหน่งเริ่มต้นของมอเตอร์เซอร์โวต้องเป็น 90° นะ เพราะงั้นกำหนดค่าเริ่มต้นให้ 'pos' เป็น 90 สร้างตัวแปรแบบ global สำหรับ LDR ทั้งสองตัว และสร้างตัวแปรชื่อ 'limit' แล้วกำหนดค่าเป็น 2
ภายใน void setup( ) ให้ใช้ฟังก์ชัน pinMode( ) เพื่อกำหนดให้ขาพอร์ตของ LDR เป็น INPUT ใช้ฟังก์ชัน attach( ) เพื่อเชื่อม Servo object กับขาพินที่กำหนด แล้วใช้ write( ) ตั้งตำแหน่งเซอร์โวที่ 90° ตั้งดีเลย์ไว้ 1 วินาทีก่อนจะเข้าไปใน void loop( )
ภายใน void loop( ) ให้สร้างตัวแปร local ขึ้นมาเพื่อเก็บค่าดิจิทัลจาก LDR ทั้งสองตัว โดยใช้ analogRead( ) จากนั้นคำนวณหาผลต่างสัมบูรณ์ระหว่างสองค่านั้นด้วยฟังก์ชัน abs() ถ้าผลต่างสัมบูรณ์เกินค่า 'limit' (ซึ่งคือ 2) ตำแหน่งเซอร์โวต้องเปลี่ยนทันที ถ้าค่าจาก LDR ตัวแรกมากกว่าตัวที่สอง ให้ลดค่าที่เก็บในตัวแปร 'pos' ลง แต่ถ้าค่าจาก LDR ตัวที่สองมากกว่าตัวแรก ให้เพิ่มค่าที่เก็บใน 'pos' ขึ้น
ถ้าค่าใน 'pos' เกิน 180 ให้รีเซ็ตกลับมาเป็น 180 ซะ ทำแบบเดียวกันถ้าค่าลดลงต่ำกว่า 0 สุดท้ายให้ใช้ฟังก์ชัน write( ) เพื่อตั้งตำแหน่งเซอร์โวไปที่ค่าที่เก็บอยู่ใน 'pos' ในตอนนี้ แล้วตั้งดีเลย์ไว้ 50 ไมโครวินาที
ใครมีข้อสงสัยเกี่ยวกับโค้ด จัดคอมเมนต์มาถามใต้โพสต์ได้เลย ไม่ต้องเกรงใจ สู้งานนะน้อง!
รายละเอียดทางเทคนิค
โปรเจกต์นี้จำลองการเคลื่อนไหวแบบ Bi-Axial Heliotropic ของดอกทานตะวัน โดยให้เซ็นเซอร์หรือแผงโซลาร์เซลล์ขนาดเล็กหันหน้าไปยังแหล่งกำเนิดแสงที่สว่างที่สุดเสมอ หลักการทำงานหลักคือการใช้ Differential Opto-Matrix ที่ประกอบด้วย LDR (Light Dependent Resistors) 2 ตัว Arduino จะเปรียบเทียบระดับแสงทางด้านซ้ายและด้านขวา จากนั้นเฟิร์มแวร์จะสั่งให้เซอร์โวขยับทีละนิดจนกว่าระดับแสงที่ตกกระทบ LDR ทั้งสองข้างจะเท่ากัน ซึ่งเป็นการทำให้แน่ใจว่าอุปกรณ์จะหันหน้าไปทางแหล่งแสงได้แม่นยำ
เพื่อเพิ่ม ประสิทธิภาพ โค้ดได้รวมฟังก์ชัน "Hysteresis" หรือเกณฑ์การตัดสินใจ (ตัวแปร 'limit') เข้าไปด้วย เพื่อป้องกันไม่ให้มอเตอร์ขยับตามแสงสะท้อนเล็กน้อยหรือเงาที่กระพริบ หลักการนี้ทำหน้าที่เป็นกลไก Cloud-Shadow Filtering ซึ่งช่วยยืดอายุการใช้งานของเซอร์โวและลดอาการสั่นกระตุกได้
ลุคสุดท้าย
ถ้าใครมีคำถามหรือข้อเสนอแนะเกี่ยวกับโปรเจกต์นี้ จัดคอมเมนต์มาได้เลยนะวัยรุ่น