วันศุกร์ที่ 28 ธันวาคม พ.ศ. 2555

GPIO RPI + Arduin

บทความนี้นำมาจากเวป http://raspberry-pi-th.blogspot.com/


จากครั้งที่แล้ว เราได้เปิดการใช้งาน Serial Port ของ Raspberry Pi ไปแล้ว วันนี้เราจะมาลองเพิ่มประสิทธิภาพของ Raspberry Pi ด้วยการเพิ่ม Arduino ให้สื่อสารกับ Raspberry Pi ผ่านทาง Serial Communication โดยจะมีการรับส่ง คำสั่งและส่งค่ากลับผ่านทาง Serial Port ของ Raspberry Pi และ Serial Port ของ Arduino เพื่อเป็นแนวทางในการนำ Arduino มาใช้เป็น I/O ของ Raspberry Pi ซึ่งเราจะได้ I/O ที่เป็นดิจิตอล และ ได้ Analog input เพิ่มจาก Arduino นั่นก็แปลว่า Raspberry Pi เราจะมีความสามารถมากขึ้นไปอีก
ปล. สำหรับมือใหม่ Arduino คือไมโครคอนโทรลเลอร์ ที่มีการอ้างไปหาตำแหน่งหน่วย Input/output ของไมโครคอนโทรลเลอร์ ด้วยรูปแบบที่เหมือนๆ กัน มาใส่ไว้ที่ Bootloader ไม่ว่าจะเอาไมโครคอนโทรลเลอร์ตระกูลใด(ที่สามารถทำได้) ให้มาอยู่ใน Platform ของ Arduino แล้วหล่ะก็ ชื่อของ Input / Output ก็จะเหมือนๆ กัน ทำให้เง่ายต่อการศึกษา และป็นที่นิยมมาก
หลักการ ก็คือ Arduino และ Raspberry Pi เองจะต้องมีการเขียนโปรแกรมเพื่อรอรับค่า และส่งค่า ผ่านทาง Serial Comm เมื่อได้รับคำสั่ง (ที่เราเองเป็นคนกำหนดแล้ว) ก็จะให้แต่ละบอร์ด ไปทำตามคำสั่งนั้น แล้วส่งผลลัพธ์กลับไป ผ่านทาง Serial Comm เหมือนเดิม นั่นก็แปลว่า ทั้งทางฝั่ง Arduino และทางฝั่ง Raspberry Pi จะต้องมีโปรแกรมรองรับเป็นของตัวเอง แต่คุยกันด้วยรูปแบบการสื่อสาร UART  นั่นเป็นหลักการ เปรียบได้กับ ไม่ว่าบอร์ดนั้นจะมาจากไหน ตระกูลใด Platform ใดก็ตาม แต่ถ้าต้องการคุยกันให้รู้เรื่อง ต้องคุยกันเป็นแบบมาตรฐาน เช่น คุยกันรูปแบบ UART  สิ่งที่แต่ละบอร์ดต้องทำนั้นก็คือ ทำให้สัญญาณที่ต้องการจะสื่อสารกันนั้น อยู่ในรูปแบบภาษากลาง เป็นมาตรฐาน (ในที่นี่คือ UART) นั่นเอง เหมือนกันกับ แต่ละชาติ แต่ละภาษา หากต้องการสื่อสารกัน เราจะใช้ภาษาอังกฤษ เป็นตัวกลางในการสื่อสารนั่นเอง
ที่นี่ เรามาลองทำโจทย์กันง่ายๆ ก่อน เพื่อให้เกิดความเข้าใจ ระหว่างการเขียนโปรแกรมให้ Raspberry Pi และ Arduino ให้สื่อสารกันได้ โดยเราจะให้  Raspberry Pi ทำการอ่านค่าการกดสวิทช์ที่ต่ออยู่กับช่องดิจิตอลของ  Raspberry Pi ช่องที่ 24 และ 26 เมื่อมีการกดสวิทช์เกิดขึ้น  Raspberry Pi จะส่งค่าคำขอไปที่ Arduino เพื่อให้ทำการอ่านค่าสัญญาณอะนาล๊อก (ซึ่งอาจจะเป็นค่าจากเซนเซอร์แบบใดๆก็ได้) ในที่นี้ เราจะให้ R ปรับค่าได้เป็นตัวสร้างสัญญาณอะนาล๊อก ที่ช่องสัญญาณ AN0 และ AN1 ของบอร์ด Arduino แล้วให้ Arduino ทำการส่งค่ากลับไปบอก Raspberry Pi ส่วน Raspberry Pi เมื่อได้ค่ามาแล้วให้แสดงผลผ่านทาง Console ต่อไป
ในด้านฮาร์ดแวร์นั้น เนื่องจาก Arduino เองสามารถส่งสัญญาณแรงดันออกมาได้ถึง 5 V เพราะฉะนั้น ที่ด้านส่งข้อมูลออกของ Arduino จะต้องทำการปรับแรงดันให้เหลือ ในระดับที่ปลอดภัยสำหรับ Raspberry Pi เสียก่อน ส่วนทางด้านรับข้อมูลเข้าของ Arduino ไม่จำเป็นต้องปรับแรงดัน เพราะแรงดันจากขาออก 3.3V จาก Raspberry Pi นั้น เป็นระดับที่ Arduino เข้าใจได้
Arduino                                                  Raspberry Pi
   Rx<--------------------------------------------->Tx
   Tx (ปรับลงเหลือ 3.3 V ก่อน)<---------------> Rx
   GND<----------------------------------------->GND
ในการแปลงแรงดันจาก 5V ให้ลดลงเหลือ 3.3V เราใช้วิธี Voltage Divider โดยเราจะใช้ตัวต้านทานค่า 10k ทำการแบ่งแรงดัน  (ผมลองวัดค่าดูแล้ว ค่าไม่เกิน 3.3V และอยู่ในช่วงที่ Raspberry Pi เข้าใจระดับสัญญาณได้)
Raspberry Pi and Arduino Experiment
คำเตือน : ระวังเรื่องของระดับสัญญาณด้วยนะครับ อย่าให้เกิน 3.3V สำหรับตำแหน่งใดๆ ก็ตามที่จะต่อเข้า GPIO ของ Raspberry Pi
การพัฒนาโปรแกรมทางฝั่ง Arduino
สามารถเริ่มต้นศึกษาได้จากตัวอย่างที่ผมได้ทำไว้แล้ว จากที่นี่http://mechacity.blogspot.com/2011/03/arduino.html  ทำการเขียนโค๊ดบน ARDUINO IDE แล้วทำการโปรแกรมลงบนบอร์ด Arduino
ด้วยโค๊ด
const int analogInPin0 = A0;    // Analog input pin that the potentiometer is attached to
const int analogInPin1 = A1;    // Analog input pin that the potentiometer is attached to
void setup() {
  // initialize serial communications at 115200 bps:
  Serial.begin(115200);
}
void loop() {
  unsigned int cmd;
  unsigned int sensorValue = 0;        // value read from the pot
  if(Serial.available() > 0){
    cmd = int(Serial.read()) - 48;
    switch(cmd){
      case 1:
        sensorValue = analogRead(analogInPin0);
        Serial.print("A0=" );
        Serial.print(sensorValue,DEC);
        Serial.print("|" );
        Serial.flush();
        break;     
      case 2:
        sensorValue = analogRead(analogInPin1);
        Serial.print("A1=" );
        Serial.print(sensorValue,DEC);
        Serial.print("|" );
        Serial.flush();
        break;   
    }
  }   
}
Arduino Firmware
หมายเหตุ : ในระหว่างการทำการโปรแกรมลงบอร์ด Arduino เราต้องไม่ให้ pin RX ของ Arduino ต่ออยู่กับอะไรในวงจร เพราะวงจรในบอร์ด Arduino ต้องใช้ pin RX ในการโปรแกรม (Burn) ลงชิพ
การพัฒนาโปรแกรมทางฝั่ง Raspberry Pi
เรายังคงใช้ภาษา Python แล้วโมดูล Python-serial ในการพัฒนาโปรแกรม โดยนำโค๊ดจากตัวอย่างที่แล้ว มาทำการดัดแปลงให้เข้ากับโจทย์ที่เราจะทดลอง บันทึกชื่อไฟล์ arduinoProj1.py
โค๊ด
#! /usr/bin/python
import serial
import time
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BOARD)
GPIO.setup(24,GPIO.IN,pull_up_down=GPIO.PUD_UP)
GPIO.setup(26,GPIO.IN,pull_up_down=GPIO.PUD_UP)
ser = serial.Serial('/dev/ttyAMA0',115200,timeout=1)
ser.open()
time.sleep(2)
def readLine(ser):
    str = ""
    while 1:
        ch = ser.read(1)
        if(ch == '|'):
            break
        str += ch
    return str
while True:
    line = ''
    if(GPIO.input(24) == False):
        ser.write('1')
        print 'button1 pressed'
        line = readLine(ser)
    elif(GPIO.input(26) == False):
        ser.write('2')
        print 'button2 pressed'
        line = readLine(ser)
    try:
        if line <> '':
            data = line.split('=')
            print 'Analog channel ' + data[0] + ' value = ' + data[1]
    except KeyboardInterrupt:
        pass
        GPIO.cleanup()
        ser.close()
        print 'Good bye!!!'
Raspberry Pi Firmware
ทดสอบการทำงาน ด้วยการรันโปรแกรมผ่าน Console ด้วยคำสั่ง (ภายใน directory ที่เก็บไฟล์ arduinoProj1.py) ด้วยคำสั่ง sudo ./arduinoProj1.py  จากนั้นทำการกดปุ่มที่ต่ออยู่กับ GPIO 24 และ 26 ของ Raspberry Pi สังเกตผลลัพธ์บนหน้าจอ Console แล้วทดลองปรับค่าความต้านทาน สังเกตการเปลี่ยนแปลง
Arduino and Raspberry Pi
จริงๆ แล้วเราควรที่จะเลือกใช้ Arduino Firmware ที่ยืดหยุ่นกว่านี้ ผมหมายถึง เราไม่ควรทำการแก้ไขโค๊ดที่ฝั่ง Arduino มากนัก แต่ควรจะมีโค๊ดที่สามารถปรับเปลี่ยนการทำงานตั้งแต่ฝั่ง Raspberry Pi เพื่อกำหนดการทำงานของ Arduino แทน ซึ่งในอินเตอร์เนตมี Library ประเภทนี้ อยู่ ตอนต่อไป ผมอาจจะนำมาสาธิตให้ดูนะครับ

บทความนี้นำมาจาก http://raspberry-pi-th.blogspot.com/2012/11/raspberry-pi-and-arduino-experiment.html

ไม่มีความคิดเห็น:

แสดงความคิดเห็น