Firmata เป็นโปรโตคอลที่ใช้สำหรับการสื่อสารระหว่างไมโครคอนโทรลเลอร์ เช่น Arduino กับคอมพิวเตอร์หรืออุปกรณ์อื่น ๆ ผ่านทาง Serial (UART) หรือการเชื่อมต่อแบบอื่น ๆ Firmata อนุญาตให้คุณควบคุมและอ่านค่าจากพินของ Arduino ได้จากภายนอก โดยไม่จำเป็นต้องเขียนโค้ดเฉพาะสำหรับ Arduino เอง
ตัวอย่างการใช้งาน Firmata คือการควบคุมพินดิจิตอลและแอนะล็อกของ Arduino จากโปรแกรมบนคอมพิวเตอร์ เช่น Python, Processing หรือ JavaScript ผ่านทาง Serial communication ทำให้การพัฒนาและการทดลองกับ Arduino ง่ายขึ้นมาก
การใช้งาน Firmata กับ Arduino
- ติดตั้งไลบรารี Firmata:
- เปิด Arduino IDE
- ไปที่เมนู
Sketch
>Include Library
>Manage Libraries...
- ค้นหา “Firmata” แล้วคลิก
Install
- อัพโหลดโค้ด Firmata ไปยัง Arduino:
- เปิด
File
>Examples
>Firmata
>StandardFirmata
- เปิด
- อัพโหลดโค้ดนี้ไปยังบอร์ด Arduino ของคุณ
*** การทำงานที่คอมพิวเตอร์ ***
1. ติดตั้ง Python 3.10.0
2. ติดตั้งโปรแกรม PyCharm
เลือกติดตั้งตัวฟรี คือ PyCharm Community
3. เพิ่มแพคเก็จ pyFirmata
เปิดโปรแกรม PyCharm Community เลือก New Project ตั้งชื่อชื่อโปรเจคตามตัวอย่างคือ FirmataProject -> Create
สร้างไฟล์ใหม่
ในตัวอย่างชื่อ test.py
สำหรับ Python, คุณสามารถใช้ไลบรารี pyFirmata
เพื่อสื่อสารกับบอร์ด Arduino
ตัวอย่างโค้ด Python:
from pyfirmata import Arduino, util
import time
board = Arduino('COM3') # หรือพอร์ตที่ Arduino ของคุณเชื่อมต่อ
it = util.Iterator(board)
it.start()
pin = board.get_pin('d:13:o') # ใช้พินดิจิตอล 13 เป็น output
while True:
pin.write(1) # เปิด LED
time.sleep(1)
pin.write(0) # ปิด LED
time.sleep(1)
เพิ่มแพคเก็จ Firmata โดยไปที่ File -> Settings…
ไปที่ Python Interpreter เลือก แล้ว คลิกเครื่องหมาย +
ที่ช่องค้นหา พิมพ์ pyfirmata -> คลิกที่ pyFirmata-> Install Package
จะพบแพคเก็จ pyFirmata และ pyserial เพิ่มเข้ามา -> OK
เชื่อมต่อสาย USB จาก คอมพิวเตอร์ ไปที่บอร์ด Arduino UNO ที่อัพโหลดโค้ด Firmata เรียบร้อยแล้ว
ทดสอบ Run
ไม่พบ Error ใดๆ
หลอดไฟ LED กระพริบติด-ดับ แสดงว่า พร้อมที่จะทำงานในขั้นตอนต่อไปแล้ว
4. ติดตั้งแพคเก็จ numpy , opencv-python mediapipe และ controller
ติดตั้งแพคเก็จ numpy
NumPy เป็นแพ็คเกจ (package) ในภาษา Python ที่ถูกพัฒนาขึ้นมาเพื่อการคำนวณเชิงตัวเลขและวิทยาศาสตร์ข้อมูล ซึ่งมีความสามารถหลากหลายในการจัดการกับอาเรย์ (arrays) และเมทริกซ์ (matrices) รวมถึงฟังก์ชันทางคณิตศาสตร์ที่สามารถใช้กับอาเรย์ได้อย่างมีประสิทธิภาพ
ติดตั้งแพคเก็จ opencv-python
opencv-python เป็นแพ็คเกจในภาษา Python ที่ใช้สำหรับการประมวลผลภาพและวิดีโอ เป็นเวอร์ชันของ OpenCV (Open Source Computer Vision Library) ซึ่งเป็นไลบรารีโอเพนซอร์สที่มีฟังก์ชันมากมายสำหรับการวิเคราะห์ภาพและวิดีโอ
ติดตั้งแพคเก็จ mediapipe
MediaPipe เป็นแพ็คเกจใน Python ที่พัฒนาโดย Google ซึ่งใช้สำหรับการประมวลผลข้อมูลมัลติโมดัล (multimodal data) โดยเฉพาะการวิเคราะห์ข้อมูลจากภาพ, วิดีโอ, และเสียง โดยแพ็คเกจนี้เน้นไปที่การใช้งานในงานปัญญาประดิษฐ์ (AI) และการเรียนรู้ของเครื่อง (Machine Learning) เพื่อตรวจจับและติดตามวัตถุหรือจุดสนใจในสื่อมัลติมีเดียต่าง ๆ
ติดตั้งแพคเก็จ controller
เป็นเครื่องมือที่ช่วยให้จับเหตุการณ์ UI ทุกประเภทได้ เช่น การแตะหน้าจอโทรศัพท์เคลื่อนที่หรือการเร่งความเร็วของอุปกรณ์โดยตรงในโค้ด Python
5. เขียนโค้ดภาษา Python ในการควบคุม การเปิด-ปิดไฟ โดยใช้ท่าทางมือ
- main.py
import cv2
import mediapipe as mp
import time
import controller as cnt
time.sleep(2.0)
mp_draw=mp.solutions.drawing_utils
mp_hand=mp.solutions.hands
tipIds=[4,8,12,16,20]
video=cv2.VideoCapture(0)
with mp_hand.Hands(min_detection_confidence=0.5,
min_tracking_confidence=0.5) as hands:
while True:
ret,image=video.read()
image=cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
image.flags.writeable=False
results=hands.process(image)
image.flags.writeable=True
image=cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
lmList=[]
if results.multi_hand_landmarks:
for hand_landmark in results.multi_hand_landmarks:
myHands=results.multi_hand_landmarks[0]
for id, lm in enumerate(myHands.landmark):
h,w,c=image.shape
cx,cy= int(lm.x*w), int(lm.y*h)
lmList.append([id,cx,cy])
mp_draw.draw_landmarks(image, hand_landmark, mp_hand.HAND_CONNECTIONS)
fingers=[]
if len(lmList)!=0:
if lmList[tipIds[0]][1] > lmList[tipIds[0]-1][1]:
fingers.append(1)
else:
fingers.append(0)
for id in range(1,5):
if lmList[tipIds[id]][2] < lmList[tipIds[id]-2][2]:
fingers.append(1)
else:
fingers.append(0)
total=fingers.count(1)
cnt.led(total)
if total==0:
cv2.rectangle(image, (20, 300), (270, 425), (0, 255, 0), cv2.FILLED)
cv2.putText(image, "0", (45, 375), cv2.FONT_HERSHEY_SIMPLEX,
2, (255, 0, 0), 5)
cv2.putText(image, "LED", (100, 375), cv2.FONT_HERSHEY_SIMPLEX,
2, (255, 0, 0), 5)
elif total==1:
cv2.rectangle(image, (20, 300), (270, 425), (0, 255, 0), cv2.FILLED)
cv2.putText(image, "1", (45, 375), cv2.FONT_HERSHEY_SIMPLEX,
2, (255, 0, 0), 5)
cv2.putText(image, "LED", (100, 375), cv2.FONT_HERSHEY_SIMPLEX,
2, (255, 0, 0), 5)
elif total==2:
cv2.rectangle(image, (20, 300), (270, 425), (0, 255, 0), cv2.FILLED)
cv2.putText(image, "2", (45, 375), cv2.FONT_HERSHEY_SIMPLEX,
2, (255, 0, 0), 5)
cv2.putText(image, "LED", (100, 375), cv2.FONT_HERSHEY_SIMPLEX,
2, (255, 0, 0), 5)
elif total==3:
cv2.rectangle(image, (20, 300), (270, 425), (0, 255, 0), cv2.FILLED)
cv2.putText(image, "3", (45, 375), cv2.FONT_HERSHEY_SIMPLEX,
2, (255, 0, 0), 5)
cv2.putText(image, "LED", (100, 375), cv2.FONT_HERSHEY_SIMPLEX,
2, (255, 0, 0), 5)
elif total==4:
cv2.rectangle(image, (20, 300), (270, 425), (0, 255, 0), cv2.FILLED)
cv2.putText(image, "4", (45, 375), cv2.FONT_HERSHEY_SIMPLEX,
2, (255, 0, 0), 5)
cv2.putText(image, "LED", (100, 375), cv2.FONT_HERSHEY_SIMPLEX,
2, (255, 0, 0), 5)
elif total==5:
cv2.rectangle(image, (20, 300), (270, 425), (0, 255, 0), cv2.FILLED)
cv2.putText(image, "5", (45, 375), cv2.FONT_HERSHEY_SIMPLEX,
2, (255, 0, 0), 5)
cv2.putText(image, "LED", (100, 375), cv2.FONT_HERSHEY_SIMPLEX,
2, (255, 0, 0), 5)
cv2.imshow("Frame",image)
k=cv2.waitKey(1)
if k==ord('q'):
break
video.release()
cv2.destroyAllWindows()
https://lungmaker.com/code/firmata/main.py
2. controller.py
import pyfirmata
comport='COM3'
board=pyfirmata.Arduino(comport)
led_1=board.get_pin('d:12:o')
led_2=board.get_pin('d:11:o')
led_3=board.get_pin('d:10:o')
led_4=board.get_pin('d:9:o')
led_5=board.get_pin('d:13:o')
def led(total):
if total==0:
led_1.write(0)
led_2.write(0)
led_3.write(0)
led_4.write(0)
led_5.write(0)
elif total==1:
led_1.write(1)
led_2.write(0)
led_3.write(0)
led_4.write(0)
led_5.write(0)
elif total==2:
led_1.write(1)
led_2.write(1)
led_3.write(0)
led_4.write(0)
led_5.write(0)
elif total==3:
led_1.write(1)
led_2.write(1)
led_3.write(1)
led_4.write(0)
led_5.write(0)
elif total==4:
led_1.write(1)
led_2.write(1)
led_3.write(1)
led_4.write(1)
led_5.write(0)
elif total==5:
led_1.write(1)
led_2.write(1)
led_3.write(1)
led_4.write(1)
led_5.write(1)
https://lungmaker.com/code/firmata/controller.py
ทดสอบการทำงาน
*** การสร้าง โปรเจค Arduino ควบคุม การเปิด-ปิดไฟ โดยใช้ท่าทางมือ***
รายการอุปกรณ์
- Arduino UNO R3
- Relay 4 Channel DC 5V High Level Trigger
- Jumper cable wire 20cm Female to Male
- รางถ่าน AA 8 ก้อน 12 โวลต์
- แจ๊กขั้วถ่าน 9 โวลต์ สำหรับ Ardiuno
- แผ่นอะคริลิค ขนาด A4
- สายไฟแดงดำ ขนาด 22AWG
- หลอดแอลอีดี (LED) ดีซี 12 โวลต์ สีแดง
- หลอดแอลอีดี (LED) ดีซี 12 โวลต์ สีเขียว
- หลอดแอลอีดี (LED) ดีซี 12 โวลต์ สีน้ำเงิน
- หลอดแอลอีดี (LED) ดีซี 12 โวลต์ สีเหลือง
- เสารองแผ่นพีซีบีโลหะแบบเหลี่ยม 8 mm
- สกรูหัวกลม+น็อตตัวเมีย ขนาด 3 มม ยาว 25 มม.
ประกอบโปรเจค
1. เชื่อมต่อ Relay 4 Channel เข้ากับบอร์ด Arduino
Relay <-> Arduino
GND <——> GND
IN1 <——-> 12
IN2 <——> 11
IN3 <——> 10
IN4 <——> 9
VCC <——> 5V
2. เชื่อมต่อ รางถ่าน และ หลอดไฟ เข้ากับ Relay
#3 เชื่อมต่อ แจ๊กขั้วถ่านกับรางถ่าน แล้วเสียบเข้าบอร์ด Arduino
4 ภาพรวมการต่อวงจร