
โปรเจกต์นี้ใช้ ADC บนชิปเพื่อจับและแสดงภาพสัญญาณคลื่นรูปคลื่น (waveform) รองรับโหมดทริกเกอร์หลากหลาย (รวมถึงการทริกเกอร์จากภายนอก) อนุญาตให้ผู้ใช้เลือกช่อง Analog Input, Reference Voltage และควบคุมขา MCU ได้ด้วย แอปพลิเคชันบน PC ที่ใช้ในโปรเจกต์นี้สร้างขึ้นบนแพลตฟอร์มโอเพ่นซอร์ส Simple Device Model (ต้องบอกเลยว่าเป็นฝีมือพี่เอง) รองรับทั้ง Windows และ Linux โปรเจกต์นี้ทดสอบบนบอร์ด [Arduino](https://s.shopee.co.th/7fUgFAWSki) Uno แล้ว อาจจะทำงานบน Arduino รุ่นอื่นๆ ที่ใช้ AVR ได้หรือไม่ได้ก็ได้นะ
**หมายเหตุ:** ด้วยความถี่ในการสุ่มตัวอย่าง (sampling frequency) ที่ 4808 Hz โปรเจกต์นี้ถือว่า**ไม่ใช่**เครื่องมือทดแทนออสซิลโลสโคปจริงๆ นะจ๊ะน้องๆ
เริ่มต้นกันเลย
1. เชื่อมต่อ [Arduino](https://s.shopee.co.th/7fUgFAWSki) ของคุณกับคอมด้วยสาย USB แล้วอัปโหลด Sketch นี้ ผ่าน Arduino IDE อย่าลืมจดชื่อพอร์ตอนุกรม (Serial Port) ที่บอร์ดใช้ไว้ (เช่น COM3 บน Windows หรือ /dev/ttyACM0 บน Linux) หล่อเท่เลยงานนี้
2. ดาวน์โหลดและติดตั้ง Simple Device Model framework
3. เปิดโปรแกรม sdmconsole ขึ้นมา แล้วกดปุ่ม Open plugin เลือก UART demo เป็น plugin และเลือก [Arduino](https://s.shopee.co.th/7fUgFAWSki) Uno เป็น device
4. ในพื้นที่ด้านบนซ้ายของหน้าต่าง sdmconsole ให้คลิกขวาที่รายการ [Arduino](https://s.shopee.co.th/7fUgFAWSki) Uno แล้วเลือก Connect พิมพ์ชื่อพอร์ตอนุกรมที่จดไว้ตอนแรกเข้าไป
5. ตอนนี้ออสซิลโลสโคปควรทำงานบนช่อง Analog A0 แล้ว ถ้ายังไม่ได้ต่ออะไรเข้าไป น้องอาจจะเห็นสัญญาณรบกวนจากไฟบ้าน 50 Hz (หรือ 60 Hz แล้วแต่ประเทศ) โผล่มาให้ดูเล่นๆ
6. ใช้สายไฟต่อ Digital Pin 3 เข้ากับ Analog Input A0 ในพื้นที่ด้านบนขวา ตั้งค่า Pin 3 mode เป็น PWM และตั้งค่า Pin3 PWM value เป็น 100 ดับเบิลคลิกในพื้นที่แสดงผล (viewport) เพื่อรีเซ็ตสเกล ตอนนี้ควรเห็นคลื่นรูปสี่เหลี่ยม PWM แล้ว:

7. ถ้าอยากได้สัญญาณที่เรียบเนียนขึ้น ให้ต่อวงจร RC ระหว่างขาออกและขาเข้า ใช้ตัวต้านทาน ~100 kOhm กับตัวเก็บประจุเซรามิก ~1 uF ก็พอแล้วจ้า
ฟีเจอร์พื้นฐาน
ในแผงตั้งค่าด้านบนขวา สามารถเลือกช่อง ADC Input และ Reference Voltage ได้ อีกทั้งยังสามารถเซ็ตเซ็นเซอร์วัดอุณหภูมิในตัว (built-in temperature [sensor](https://s.shopee.co.th/7VBG2rX65j)) เป็นช่องอินพุตได้ด้วย (แต่บอกเลยว่าเซ็นเซอร์นี้ความแม่นยำไม่ค่อยดีนะ)

Packet size กำหนดจำนวนตัวอย่าง (samples) ในคลื่นรูปคลื่นที่แสดงผล และส่งผลต่ออัตรารีเฟรชด้วย สำหรับสัญญาณที่เป็นคาบ การตั้ง packet size ให้พอดีกับจำนวนคาบเต็มๆ จะทำให้มองเห็นภาพดีขึ้น แม้จะไม่มีการซิงค์ก็ตาม
ส่วน Pin settings อนุญาตให้ตั้งสถานะของขา MCU หมายเลข 2-13 สถานะที่เป็นไปได้คือ Input, Input with pullup, Force low และ Force high ขาที่รองรับ PWM ก็สามารถตั้งค่าเป็นโหมดนั้นได้เช่นกัน
โหมดการแสดงผล
นอกจากโหมดพื้นฐานแบบ "ออสซิลโลสโคป" แล้ว sdmconsole ยังสามารถแสดงข้อมูลเป็นแผนภูมิแท่ง (bar chart), ภาพ (ที่ความสว่างของพิกเซลแทนค่าตัวอย่าง) หรือแผนภูมิไบนารี (ที่ความสว่างของพิกเซลแทนบิตเดียว) ได้ด้วย สามารถเปลี่ยนโหมดการแสดงผลผ่านเมนูแบบเลื่อนลง Mode

น้องสามารถเลื่อนดูพื้นที่แสดงผลโดยการลากเมาส์ เปลี่ยนสเกลแนวตั้งด้วย Ctrl+ล้อเลื่อนเมาส์ และเปลี่ยนสเกลแนวนอนด้วย Ctrl+Shift+ล้อเลื่อนเมาส์ ดับเบิลคลิกในพื้นที่แสดงผลจะรีเซ็ตสเกลให้พอดีกับภาพทั้งหมด
การทริกเกอร์
Sync mode ตั้งค่าโหมดทริกเกอร์: Off, Rising edge หรือ Falling edge โดยค่าเริ่มต้น ออสซิลโลสโคปจะถูกทริกเกอร์โดยสัญญาณเดียวกันกับที่เลือกเป็น Analog Input หรือจะทริกเกอร์โดย Digital Pin ก็ได้ โดยเลือกจากรายการแบบเลื่อนลง Sync source
เมื่อใช้ Analog Input เป็นแหล่งซิงค์ ออสซิลโลสโคปจะถูกทริกเกอร์เมื่อสัญญาณข้ามระดับ Sync level (ขึ้นหรือลงแล้วแต่ขอบซิงค์) Sync level จะถูกละเว้นเมื่อใช้ Digital Pin เป็นแหล่งซิงค์
Sync offset กำหนดจำนวนตัวอย่างก่อนจุดทริกเกอร์ที่จะถูกแสดงผล
ระบบทริกเกอร์นี้ค่อนข้างพื้นฐานและทำงานได้ดีพอสมควรสำหรับเหตุการณ์เดียวและสัญญาณความถี่ต่ำ สำหรับสัญญาณความถี่สูง บางครั้งการตั้ง packet size ที่เหมาะสมอาจให้ผลลัพธ์ที่ดีกว่า
เจาะลึกเบื้องหลัง
เพื่อให้ได้ความถี่ในการสุ่มตัวอย่างที่เสถียร สัญญาณจะถูกสุ่มตัวอย่างโดยการตั้งค่า ADC ให้อยู่ในโหมด free running ซึ่งจะทำการแปลงค่าตลอดเวลาและสร้างอินเตอร์รัปต์เมื่อข้อมูลพร้อม เนื่องจาก throughput ของพอร์ตอนุกรมมีจำกัด จึงใช้เพียงหนึ่งในทุกๆ สองตัวอย่าง วิธีนี้ช่วยหลีกเลี่ยงปัญหา jitter ที่จะเกิดขึ้นหากการแปลงค่าแต่ละครั้งถูกเริ่มโดย CPU
การควบคุมออสซิลโลสโคปทำผ่านพื้นที่แอดเดรสเสมือน (virtual address space): การเขียนค่าไปยังแอดเดรสรีจิสเตอร์ที่กำหนดจะถูกตีความว่าเป็นคำสั่งหรือข้อมูลการคอนฟิก ตัวอย่างเช่น การเขียนค่า 3 ไปยังแอดเดรสรีจิสเตอร์ 0 จะเลือกช่อง Analog Input A3
การคอนฟิกพอร์ตอนุกรมคือ: 115200 baud, 8 data bits, 1 stop bit, no parity, no flow control
โปรโตคอลการสื่อสารใช้เฟรมสี่ประเภท:
Write register (PC -> [Arduino](https://s.shopee.co.th/7fUgFAWSki)):
01010000 ADDR[7:0] DATA[7:0]
Read register (PC -> [Arduino](https://s.shopee.co.th/7fUgFAWSki)):
01010001 ADDR[7:0]
Register data ([Arduino](https://s.shopee.co.th/7fUgFAWSki) -> PC):
1000 DATA[7:4] 0000 DATA[3:0]
Stream data ([Arduino](https://s.shopee.co.th/7fUgFAWSki) -> PC):
11 SOP DATA[9:5] 000 DATA[4:0]
(SOP คือฟลัก "start of frame")
ด้วยโปรโตคอลนี้ แต่ละตัวอย่างต้องการการส่งข้อมูลเพียง 2 ไบต์ ในขณะที่ยังสามารถแยกแยะระหว่างเฟรมข้อมูลรีจิสเตอร์และสตรีมได้
ฝั่ง PC โปรโตคอลถูกนำไปใช้โดยปลั๊กอิน uartdemo ที่ทำให้ sdmconsole สามารถสื่อสารกับออสซิลโลสโคปได้ ซอร์สโค้ดของปลั๊กอินนี้มาพร้อมกับ SDM (ในไดเรกทอรี examples) ปลั๊กอินเขียนด้วย C++ และมีฟังก์ชันสำหรับเขียน/อ่านค่ารีจิสเตอร์และอ่านข้อมูลสตรีมจากออสซิลโลสโคป
วิธีที่ง่ายที่สุดในการขยายฟีเจอร์ของออสซิลโลสโคปคือการปรับเปลี่ยนพื้นที่แอดเดรสเสมือนของมัน (นั่นคือฟังก์ชัน writeVirtualRegister และ readVirtualRegister) จากนั้นก็สามารถเพิ่มรีจิสเตอร์ใหม่ลงในแผนที่รีจิสเตอร์ซึ่งผู้ใช้แก้ไขได้เต็มที่ (แต่อย่าลืมเซฟนะ) หากต้องการเปลี่ยนโปรโตคอลการสื่อสาร น้องจะต้องแก้ไขและคอมไพล์ซอร์สโค้ดของปลั๊กอิน uartdemo ใหม่ด้วย สู้งานนะน้อง!