กลับไปหน้ารวมไฟล์
the-arduino-clever-plotter-86ad66.md

ความจำเป็นของพล็อตเตอร์เจ๋งๆ

Arduino สามารถใช้เป็นระบบเก็บข้อมูล (data acquisition) ในงานวิทยาศาสตร์ได้นะ น้องอยากเก็บข้อมูลลงไฟล์เพื่อเอาไปประมวลผลต่อ หรือดูกราฟแบบเรียลไทม์ใช่ไหม? Serial Plotter ใน Arduino IDE มันค่อนข้างจำกัดอะ ควบคุมยาก อยากแสดงอะไรก็ลำบาก แต่กับ Arduino Clever Plotter (ACP) นี่จัดไปวัยรุ่น! พล็อตข้อมูลได้เหมือนเดิม แต่เราคุมได้ทั้งแกน x และขอบเขตของแกน y ตั้งชื่อกราฟให้มันมีความหมาย เลือกการแสดงผลที่เหมาะกับงานได้ แถม ACP ยังเก็บข้อมูลลงไฟล์ให้อีกด้วย สบายมาก

สำหรับคนใจร้อน (Impatient)

  1. โหลดแอปพลิเคชันมาเลย (ลิงก์เดิมหายไปแล้ว น้องลองหาใน GitHub ดูนะ)
  2. อัพโหลดสเก็ตช์ลงบอร์ด Arduino ที่น้องชอบ โดยให้มันส่งข้อมูลออกมาเป็นค่าที่คั่นด้วยจุลภาค (comma separated values)
  3. รัน ACP ได้เลยจ้า

ด้านล่างนี้คือตัวอย่างที่เห็นได้เมื่อเก็บข้อมูลจากการทดลองวัดแรงดันไฟฟ้าตกคร่อมตัวเก็บประจุ (capacitor) ในวงจร RC

เตรียมสเก็ตช์ Arduino ของน้องให้พร้อม

ACP ทำงานคล้ายๆ กับ Serial Plotter ใน IDE นะ ถ้าน้องพิมพ์ค่าออกมาแค่ค่าเดียวแบบนี้

Serial.println(mydata)

ACP ก็จะพล็อตข้อมูลเป็นฟังก์ชันของจำนวนลูป (loop) แต่ถ้าน้องพิมพ์ค่าออกมาหลายค่า คั่นด้วยจุลภาค แบบนี้

Serial.print(x_data);

Serial.print(",");

Serial.print(y_data);

Serial.print(",");

Serial.println(z_data);

ACP จะสร้างกราฟสามอันในพล็อตเดียวกัน แบบที่เห็นด้านล่างนี้เลย:

ผลลัพธ์จาก ACP ที่มีกราฟสามอันในพล็อตเดียวกัน

แต่ละกราฟจะถูกตั้งชื่อให้อัตโนมัติ และจะมีคำอธิบาย (legend) ปรากฏที่มุมซ้ายบน แกน x จะตรงกับจำนวนลูป

ขอบอกไว้หน่อยนะ ถ้า ACP หาบอร์ด Arduino ไม่เจอ มันจะจำลองการมีอยู่ของบอร์ดด้วยการเขียนข้อมูลสุ่มลงพอร์ตให้ดูแทน เก๋ไก๋มาก

ถ้าน้องอยากพล็อตข้อมูลเป็นฟังก์ชันของปริมาณอื่นที่เก็บมาได้ระหว่างรัน (เช่น เวลา) น้องสามารถประกาศมันในฟังก์ชัน setup() ได้ โดยเขียนโครงสร้าง XML ลงพอร์ตอนุกรมแบบนี้

Serial.println("<header><x>t [$\\mu$s]</x></header>");

เมื่อ ACP ตรวจพบสตริงนี้ มันจะตีความตัวเลขตัวแรกในลิสต์ที่คั่นด้วยจุลภาคว่าเป็นตัวแปรที่จะพล็อตบนแกน x แกนก็จะถูกตั้งชื่อตามเนื้อหาในแท็ก <x> ด้วย ในตัวอย่างนี้คือ "t [𝜇s]" ($\\mu$ จะแสดงผลเป็น 𝜇)

น้องสามารถตั้งชื่อให้ข้อมูลบนแกน y ได้ด้วยการเพิ่มป้ายกำกับ (label) ที่ตรงกัน ตัวอย่างเช่น:

Serial.println("<header><x>t [$\\mu$s]</x><y>V_C [V]</y></header>");

ถ้ามีข้อมูลที่จะพล็อตในลิสต์ที่คั่นด้วยจุลภาคมากกว่าหนึ่งค่า น้องก็แค่ให้ลิสต์ป้ายกำกับที่คั่นด้วยจุลภาคใน XML ภายในแท็ก <y>:

Serial.println("<header><x>t [$\\mu$s]</x><y>V_C [V],V_R [V]</y></header>");

สเกลของแกน y จะถูกปรับอัตโนมัติเพื่อให้พอดีกับพล็อต ถ้าน้องอยากกำหนดมันตายตัวเลย ก็แค่เพิ่มค่าขอบล่างและ/หรือขอบบน โดยใช้แท็ก <ylim>:

Serial.println("<header><x>t [$\\mu$s]</x><y>V_C [V]</y><ylim>0,None</ylim></header>");

หรือ

Serial.println("<header><x>t [$\\mu$s]</x><y>V_C [V]</y><ylim>0,1023</ylim></header>");

หรือ อีกแบบ

Serial.println("<header><x>t [$\\mu$s]</x><y>V_C [V]</y><ylim>None,10</ylim></header>");

ตัว ACP มันจะเซฟข้อมูลลงไฟล์ CSV ชื่อ acp.csv ให้อัตโนมัติเป็นค่าเริ่มต้น วิธีนี้จะทำให้น้องสามารถเอาไปวิเคราะห์แบบออฟไลน์ได้ ถ้าต้องการ

โครงสร้างทางเทคนิค & โปรโตคอล Serial

  • Python Backend: ACP ถูกเขียนด้วย Python ใช้ไลบรารีเทพๆ อย่าง matplotlib สำหรับเรนเดอร์กราฟคุณภาพสูง และ pyserial สำหรับคุยกับฮาร์ดแวร์ระดับลึก ทำให้มีฟีเจอร์เด็ดอย่างการเรนเดอร์ LaTeX สำหรับป้ายแกน (เช่น ใช้ $\mu$ แทนหน่วยไมโคร)
  • XML Metadata Handshake: ACP มีโปรโตคอลเมตาดาต้าที่ฉลาดมาก โดยการส่งสตริงพิเศษอย่าง <header><x>t [$\mu$s]</x><y>V_C [V]</y></header> ระหว่าง setup() น้องสามารถตั้งค่ากราฟฟิกของโปรแกรมพล็อตเตอร์ได้จากโค้ด Arduino เลย เรียกว่าเป็น "self-describing" data stream ซึ่งเป็นแพตเทิร์นที่เจอในโปรโตคอล IoT แบบขั้นสูงในอุตสาหกรรม
  • Zero-Jitter Logging: ในขณะที่พล็อตแบบเรียลไทม์เป็นสิ่งสำคัญ ACP ก็ยังดันข้อมูลทุกแพ็กเก็ตที่เข้ามาทาง Serial ลงไฟล์ CSV (acp.csv) พร้อมกันไปด้วย วิธีนี้รับประกันว่าแม้เธรดเรนเดอร์ของคอมจะล้าหลัง ความสมบูรณ์ของข้อมูลจะยังคงอยู่สำหรับเอาไปประมวลผลต่อใน Excel, MATLAB หรือ Pandas ของ Python ได้
  • Virtual Hardware Simulation: ACP มีโหมดจำลองฮาร์ดแวร์ที่แข็งแกร่ง (ใช้สวิตช์ -s และ -p) ถ้าไม่เจอ Arduino สคริปต์จะสร้างข้อมูลสังเคราะห์ขึ้นมา (เช่น สัญญาณรบกวนสุ่ม หรือเส้นโค้งทางคณิตศาสตร์) ทำให้นักพัฒนาสามารถทดสอบลอจิกการแสดงผลและสภาพแวดล้อม Python ได้โดยไม่ต้องต่อฮาร์ดแวร์จริง

วิธีควบคุมแอปพลิเคชัน

เริ่มต้น ACP แค่รันไฟล์ acp.py ไม่ต้องใส่ argument อะไร สวิตช์ -h จะแสดงข้อความช่วยเหลือ

> python3 acp.py -h

น้องสามารถเลือกพอร์ตที่จะอ่านข้อมูลโดยใช้สวิตช์ -p ชื่อไฟล์ที่ใช้เก็บข้อมูลคือ acp.csv เป็นค่าเริ่มต้น แต่เปลี่ยนได้ด้วยสวิตช์ -f

ถ้าไม่เจอบอร์ด Arduino ตัว ACP จะจำลองว่ามีบอร์ดอยู่ น้องสามารถจำลองการส่ง header ได้ด้วยสวิตช์ -s ในกรณีนี้ข้อมูลจะถูกติดป้ายว่า "x (m)", "y (m/s$^2$)" และ "z (kg)" ถ้าอยากเพิ่มคอลัมน์ x แบบจำลอง ก็แค่เพิ่มสวิตช์ -t ไปในคำสั่งรัน acp.py

ACP จะรันไปเรื่อยๆ จนกว่าจะใช้สวิตช์ -n เพื่อบอกว่าจะเก็บข้อมูลกี่ลูป เมื่อจำนวนแถวที่อ่านจาก Arduino เท่ากับจำนวนนี้ ACP จะหยุดและรอให้น้องปิดหน้าต่างพล็อต

แกน x จะแสดงข้อมูล 100 ตัวล่าสุดที่เก็บมาเป็นค่าเริ่มต้น เปลี่ยนจำนวนนี้ได้ด้วยสวิตช์ -r

สวิตช์ -m ให้น้องเลือกมาร์กเกอร์สำหรับพล็อตข้อมูลที่ต่างออกไป ใช้ฟอร์แมตตามไลบรารี matplotlib.pyplot เช่น "-m o-" จะพล็อตข้อมูลด้วยวงกลมเล็กๆ เชื่อมด้วยเส้น

สวิตช์ -b ใช้ตั้งค่าอัตราบอด (baud rate) ซึ่งค่าเริ่มต้นคือ 9600 ACP จะพิมพ์ข้อมูลออกมาเยอะขึ้นถ้าเปิดสวิตช์ -v

วิศวกรรมและการใช้งาน

  • Dynamic Scaling: การใช้แท็ก <ylim> วิศวกรสามารถป้องกันปัญหากวนตีนของ Serial Plotter ทั่วไป ที่สัญญาณรบกวนเล็กๆ ทำให้กราฟซูมออกจนมองไม่เห็นสัญญาณจริง การตั้งลิมิต เช่น 0, 1023 (สำหรับ ADC 10-bit) จะช่วยให้ภาพกราฟคงที่
  • Command Line Flexibility: เครื่องมือนี้ถูกออกแบบมาสำหรับ "ผู้ใช้ขั้นเทพ" ด้วยฟลัก CLI สำหรับควบคุมอัตราบอด (-b), เลือกพอร์ต (-p), และกำหนดขนาดหน้าต่างแบบโรลลิ่ง (-r) ซึ่งควบคุมว่าข้อมูลย้อนหลังกี่จุดจะแสดงบนหน้าจอในเวลาเดียวกัน
  • Marker Customization: ผ่านสวิตช์ -m ผู้ใช้สามารถเลือกระหว่างพล็อตแบบเส้น, แบบจุดกระจาย หรือมาร์กเกอร์ผสมกันได้ ช่วยให้แยกแยะระหว่างข้อมูลแบบไม่ต่อเนื่องกับคลื่นสัญญาณต่อเนื่องได้ง่ายขึ้น

สัญญาอนุญาต (Licensing)

ACP อยู่ภายใต้สัญญาอนุญาต GNU General Public License เวอร์ชัน 3 สำหรับรายละเอียดเพิ่มเติม ให้รันสคริปต์พร้อมกับสวิตช์ -l

ข้อมูล Frontmatter ดั้งเดิม

apps:
  - "1x Mac OSX"
  - "1x Linux (any flavour)"
  - "1x Windows"
author: "organtin"
category: "Lab Stuff"
components:
  - "1x Any Arduino or Arduino compatible board"
  - "1x Laptop or computer"
description: "มาสร้างพล็อตเตอร์สุดตึงๆ ที่ปรับแต่งได้ตามใจ ไว้พล็อตข้อมูลจากเซนเซอร์และ Arduino แบบเทพๆ กันเถอะ วัยรุ่นวิศวะจัดไป!"
difficulty: "Easy"
documentationLinks: []
downloadableFiles:
  - "https://github.com/organtin/physics/blob/413ce51619bf7979d301cf324114f2cf2b2cdfd5/Springer/physWArduinoSmartphones/acp.py"
encryptedPayload: "U2FsdGVkX19Y9h7HvDJXexQPEFvQamuVq1+R0siAKwuODlu9PZ0wQQWAjDZsFmQ3ZS2zsai7Jn9FoMtRW5lAXgtIRhmJT34cbBYe9Wb5tzFPMswknNu6D/BtUSAhYutqhfvAWHvV8oaq+1vHgrLbCw=="
heroImage: "https://cdn.jsdelivr.net/gh/bigboxthailand/arduino-assets@main/images/projects/the-arduino-clever-plotter-86ad66_cover.jpg"
lang: "en"
likes: 1
passwordHash: "5603f213ea4fa10ea528c7fff282f233a983493ea5ef41e0bd1ee73923210933"
price: 1499
seoDescription: "Build the Arduino Clever Plotter, a flexible tool for visualizing data collected with Arduino microcontrollers."
tags:
  - "Data Collection"
title: "โปรเจกต์พล็อตเตอร์สายช่าง ฉบับ Arduino งานง่ายแต่หล่อ!"
tools: []
videoLinks:
  - "https://youtu.be/fCVVjacNQgE"
views: 829