แก้ปัญหาใช้งานเซนเซอร์กับ Raspberry Pi ไม่ได้ด้วย Arduino

Cytron Thailand
3 min readApr 22, 2022

เพื่อนๆน่าจะเคยประสบปัญหามีอุปกรณ์หรือเซนเซอร์ที่ต้องการต่อใช้งานร่วมกับ Raspberry Pi แต่ไม่สามารถใช้งานได้ ด้วยหลากหลายสาเหตุ อาทิ ไม่มี driver หรือ libraries ของอุปกรณ์ตัวนี้สำหรับการใช้งานร่วมกับ Raspberry Pi หรือ อุปกรณ์ไม่รองรับการใช้งานร่วมกับ Raspberry Pi เนื่องจากตัวแปรด้านเทคนิค อย่าง Logic Level หรือตัวเซนเซอร์ให้เอาต์พุทเป็นแบบ Analog ซึ่งตัว Raspberry Pi ไม่มี Analog Input จึงทำให้ไม่สามารถอ่านค่าจากเซนเซอร์ได้

ดังนั้นในบทความนี้ เราจะใช้ไมโครคอนโทรลเลอร์ตัวเก่งที่หลายๆคนรู้จักอย่าง Arduino Uno ในการนำมาเป็นคนกลางระหว่าง Raspberry Pi และเซนเซอร์ที่เราต้องการใช้งานโดยอาศัย Serial Communication

หรือใครไม่อยากอ่าน ลองดูเป็นวิดีโอก็ได้นะ

อุปกรณ์ที่ใช้งาน

Arduino Uno (แนะนำเป็น Maker Uno) : https://bit.ly/3rJmcSV

Raspberry Pi 4 Model B : https://bit.ly/3xLSdgP

4-Channel Logic Level Shifter : https://bit.ly/3rNhyDd

Jumper Wire : https://bit.ly/3rKgCj4

หลักการทำงาน

อย่างที่เรารู้กันดีว่าเวลาเราใช้งาน Arduino Uno เราสามารถอ่านค่าที่ได้จากเซนเซอร์ที่ต่ออยู่กับ Arduino Uno ได้ผ่านทาง Serial Monitor ผ่านทางตาของเรา ในทางกลับกัน หากเราต้องการที่จะส่งค่าไปให้ Raspberry Pi ล่ะ Raspberry Pi ก็สามารถที่จะรับรู้ข้อความของเราผ่านทาง Serial Communication ได้เช่นกัน ซึ่งสิ่งหนึ่งที่ Raspberry Pi เหนือกว่าตาของมนุษย์ คือความเร็วในการอ่าน Raspberry Pi สามารถอ่านค่าที่ส่งผ่าน Serial Communication ได้เร็วกว่าตาของมนุษย์มาก

Serial Communication ระหว่าง Raspberry Pi และ Arduino

การสื่อสารผ่าน Serial Communication ระหว่าง Raspberry Pi และ Arduino สามารถทำได้ 2 รูปแบบ โดยแบ่งจากลักษณะการเชื่อมต่อวงจร ดังนี้

ผ่านทางสาย USB

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

  • สำหรับการเชื่อมต่อรูปแบบนี้ จำเป็นที่จะต้องมีการถอดปลายสาย USB อีกฝั่งออกจาก Raspberry Pi เพื่อไปเสียบกับคอมพิวเตอร์หากจำเป็นต้องมีการอัพโหลดโปรแกรมเข้าสู่ตัวบอร์ด Arduino

ผ่านทาง GPIOs

โดยคุณสามารถที่จะใช้สายไฟไม่กี่เส้นในการเชื่อมต่อระหว่าง 2 บอร์ด ดังภาพ

อย่างที่เรารู้กับว่า Raspberry Pi SBC ทุกรุ่นใช้แรงดันไฟฟ้า Logic Level เพียง 3.3V ซึ่งในการนำมาใช้งานร่วมกับ Arduino Uno ที่ใช้แรงดันไฟฟ้า Logic Level ที่ 5V นั้น คุณจำเป็นที่จะต้องใช้อุปกรณ์เสริมอย่าง Logic Level Shifter เพื่อทำหน้าที่แปลงแรงดันไฟฟ้า Logic Level ของ Arduino ที่เป็น 5V ให้เป็น 3.3V สำหรับการสื่อสาร และไม่เป็นการสร้างความเสียหายให้กับ GPIOs ของ Raspberry Pi ด้วย

เตรียมโปรแกรมสำหรับรับค่าจาก Arduino บน Raspberry Pi

ใช้คำสั่งด้านล่างนี้ เพื่อเป็นการป้องกัน Error ที่จะเกิดขึ้นจากการที่ Raspberry Pi ไม่สามารถเชื่อมต่อกับ Arduino ได้

sudo adduser your_username dialout

หลังจากนั้น ทำการ Reboot Raspberry Pi ก่อน 1 ครั้ง

ต่อมาทำการติดตั้ง Pyserial ซึ่งเป็นไลบรารี่ภาษา Python ที่จะมารับค่าจาก Serial Communication จาก Arduino ที่เชื่อมต่ออยู่ โดยใช้คำสั่ง

python3 -m pip install pyserial

แต่สำหรับใครที่เจอ Error ไม่พบ module pip (“/usr/bin/python3: No module named pip”) ให้ทำการติดตั้ง pip module โดยใช้คำสั่ง

sudo apt install python3-pip

ต่อมาเราก็จะมาเขียนโปรแกรมสำหรับอ่านค่าที่ได้จาก Arduino ผ่านทาง Serial Communication กัน

สร้างไฟล์โปรแกรมสำหรับอ่านค่าที่ส่งมาจาก Arduino ด้วยคำสั่ง

sudo nano reader.py

หลังจากนั้นนำโค้ดโปรแกรมด้านล่างนี้ไปวางได้เลย

#!/usr/bin/env python3
import serial

if __name__ == '__main__':
ser = serial.Serial('<..YOUR ARDUINO CONNECTION..>, 9600, timeout=1)
ser.reset_input_buffer()

while True:
if ser.in_waiting > 0:
line = ser.readline().decode('utf-8').rstrip()
print(line)

โดยในโปรแกรมจะเป็นการ import serial library เข้ามาสำหรับการใช้งาน serial communication ของ Raspberry Pi

import serial

หลังจากนั้นจะเป็นการเริ่มการสื่อสารผ่านทาง serial communication โดยจะมีการระบุ

  • serial device name ของ Arduino ที่เรานำมาเชื่อมต่อ (โดยเราสามารถรู้ได้ด้วยคำสั่ง ls /dev/tty* โดยหากปรากฏขึ้นมาหลายชื่อ ให้ลองถอดสายออกแล้วสังเกตว่าชื่อไหนที่หายไป ชื่อนั้นคือ serial device name arduino ของเรา
  • Baud rate ที่ใช้ในการสื่อสารระหว่าง Arduino และ Raspberry Pi ซึ่งต้องตรงกัน (ในส่วนของ Arduino จะระบุอยู่ในส่วนของ void setup() ที่มีการใช้คำสั่ง
Serial.begin(..<Your Baud Rate..>);
  • timeout : ระยะเวลาที่โปรแกรมจะรออ่านค่าที่ส่งมาจาก Arduino ก่อนทำการแสดงผลค่าล่าสุดที่ได้รับซ้ำเมื่อไม่มีข้อมูลใหม่ถูกส่งมา
if __name__ == '__main__':
ser = serial.Serial('<..YOUR ARDUINO CONNECTION..>, 9600, timeout=1)

ใช้คำสั่งด้านล่างในการเคลียร์ค่าใน Buffer ที่อาจค้างอยู่จากการสื่อสารครั้งก่อนหน้า เพื่อให้ได้รับข้อมูลที่ถูกต้องในการสื่อสารครั้งแรก

ser.reset_input_buffer()

และในส่วนสุดท้ายของโปรแกรมจะเป็นการวนอ่านค่าที่ได้รับจาก Arduino และแสดงผลออกมา

while True:
if ser.in_waiting > 0:
line = ser.readline().decode('utf-8').rstrip()
print(line)

เตรียม Arduino ให้พร้อมสำหรับการส่งข้อมูล

ตามที่เราวางแผนไว้ Arduino จะทำหน้าที่อ่านข้อมูลที่ได้จากเซนเซอร์หลากหลายรูปแบบแล้วจึงส่งค่าที่ได้ให้ Raspberry Pi หมายความว่า โค้ดที่เราเขียนใน Arduino จะแบ่งออกเป็น 2 หน้าที่ ได้แก่

  1. อ่านค่าจากเซนเซอร์ที่เชื่อมต่ออยู่
  2. ส่งค่าที่อ่านได้ไปยัง Raspberry Pi

โดยโค้ดโปรแกรมที่เราจะใช้ใน Raspberry Pi มีดังนี้

int sensor_value;
void setup() {
Serial.begin(9600);
}

void loop() {
sensor_value = random(100);
Serial.println(sensor_value);
delay(1000);
}

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

int sensor_value;

เริ่มการสื่อสารผ่านทาง serial communication ของ Arduino Uno ด้วยคำสั่งด้านล่าง

Serial.begin(9600);

ทำการวนสุ่มค่าสำหรับส่งไปยัง Raspberry Pi และส่งค่าไปยัง Raspberry Pi ทุกๆ 1 วินาที

void loop() {sensor_value = random(100);
Serial.println(sensor_value);
delay(1000);
}

หลังจากนั้น คุณก็สามารถที่จะนำ Arduino ไปเชื่อมต่อกับ Raspberry Pi เพื่อทดสอบส่งข้อมูลได้เลย โดยที่ Arduino จะใช้ไฟเลี้ยงจากพอร์ต USB ของ Raspberry Pi ไม่ต้องต่อไฟเลี้ยงเพิ่ม

ทำการรันโปรแกรมสำหรับรับค่าจาก Arduino ผ่าน Serial Communication ด้วยคำสั่ง

chmod +x reader.py
./reader.py

โดยผลลัพธ์ที่ได้จากโปรแกรมข้างต้นก็จะเป็นตัวเลขที่ Arduino สุ่มมาให้นั่นเอง!

กรณีเชื่อมต่อแล้ว Raspberry Pi ไม่ได้รับค่าจาก Arduino ให้ทำการกดปุ่ม Reset บน Arduino 1 ครั้ง เพื่อให้ Arduino เริ่มทำการสื่อสารกับ Raspberry Pi ผ่าน Serial Communication ใหม่

เพียงเท่านี้ Raspberry Pi ของคุณก็จะได้รับค่าที่ Arduino อ่านได้จากเซนเซอร์ได้แล้ว โดย Arduino ทำหน้าที่เป็นตัวกลางในการสื่อสารระหว่างทั้งสองตัว โดยสามารถนำไปประยุกต์ใช้ได้หลายรูปแบบ อาทิ

  • ใช้ Arduino เป็นตัวกลางระหว่างเซนเซอร์ที่ Raspberry Pi ไม่รองรับ
  • ใช้ Arduino เป็นตัวกลางในการรวมค่าจากเซนเซอร์หลายๆตัวแล้วส่งค่าไปให้ Raspberry Pi ทีเดียว ลดภาระการทำงานของ Raspberry Pi

นอกจากนี้ คุณก็ยังสามารถส่งค่าจาก Raspberry Pi กลับไปยัง Arduino ด้วย Serial Communication ได้เช่นกัน รออ่านบทความหน้านะครับ เราจะมาลองกัน!

--

--