วันนี้เราจะมาสาธิตการใช้ Raspberry Pi เพื่อรับค่าจาก Sensor ซึ่งให้ข้อมูลเป็นแบบ Analog กันครับ
เริ่มต้นต้องเข้าใจก่อนว่า Raspberry Pi นั้นไม่มีความสามารถในการรับค่าแบบ Analog โดยตรง (รับได้เฉพาะ Digital In/Out) ซึ่งไม่เหมือนกับ Arduino Board ซึ่งรับค่าได้ทั้งแบบ Digital และ Analog ดังนั้นจึงมีคนใช้วิธีการนำข้อมูลแบบ Analog เข้าไปประมวลผลต่อใน Raspberry Pi หลากหลายวิธีนะครับ เช่น
วันนี้เราจะมารับสัญญาณแบบ Analog โดยใช้ IC รุ่น MCP3208 กันครับ IC ตัวนี้เป็นแบบ DIP type นะครับมีความสามารถในการรับค่าได้ถึง 8 Channel โดยแปลงค่าเป็นข้อมูลแบบ 12 บิต หรือ (0 - 4096) และสามารถกำหนดค่า Vref ได้เองครับ (ค่าแรงดันสูงสุด หรือ 4096 ) ในเว็บต่างประเทศที่เขียนถึงวิธีการใช้งานกันมักจะใช้ MCP3008 นะครับ ซึ่งจะเป็นรุ่นที่แปลงค่าสัญญาณเป็น 10 บิต แต่ในประเทศของเรา ร้านขาย IC จะไม่มีขายรุ่น MCP3008 ครับ จะหาซื้อได้ก็จะเป็นรุ่น MCP3208 กันครับ
ดังนั้นเพื่อให้เพื่อนๆที่ติดตามอ่านบทความสามารถหาซื้อได้ เราก็จะเขียนให้ทั้งสองแบบละกันนะ แต่เดี๋ยวคิดว่าจะไปหามาขายบนเว็บ Arduitronics.com ครับ เผื่อจะได้ราคาที่ประหยัดกว่าด้วย
เอาละครับ มาดูรายละเอียดการส่งข้อมูลของ MCP3208 กันหน่อยครับ
ถ้าดูรูปด้านบนจะเห็นว่าเป็น IC แบบ 16 ขานะครับ ด้านซ้ายของ IC จะเป็น Analog Input ทั้ง 8 Channel อุปกรณ์ตัวนี้สามารถ Sampling ได้เกือบๆ 100 kSamp/s (ค่ารวมทั้ง 8 ช่องนะครับ ถ้าใช้มากกว่า 1 ช่อง ความเร็วที่ว่าก็ต้องหารด้วยจำนวนช่องที่ใช้งานด้วย)
ทางด้านซ้ายจะเป็นขาที่ใช้ติดต่อแบบ Serial Peripheral Interface (SPI) นะครับ ซึ่งประกอบด้วย CLK, DOUT, DIN, CS, DGND
ทีนี้มาดูโปรโตตอลในการติดต่อแบบ Serial Peripheral Interface (SPI) กันครับ ชื่อก็พอจะบอกได้ครับว่าเป็นการสือสารแบบอนุกรม นั้นคือใช้จำนวนสายสัญญาณในการติดต่อน้อย ทำให้ประหยัด Pin In/out ที่จะใช้ แต่ก็แน่นอนว่าต้องแลกมาด้วยการจัดการสัญญาณที่จะรับและส่งกันหน่อยครับ
ในการสื่อสารแบบ SPI นี้ จะมีตัวที่กำหนดจังหวะ และ เลือก option ต่างๆ ในการติดต่อกับอุปกรณ์ภายนอก เรียกว่า "Master" และอุปกรณ์ที่คอยทำหน้าที่ตามคำสั่งที่ Master ส่งมาบอก เรียกว่า "Slave" ทีนี้การทำงานของเราในวันนี้ เราจะใช้ Raspberry Pi เป็นตัวสั่งให้ MCP3208 ทำงาน โดยการเลือก Channel ของสัญญาณที่ต้องการ Sampling นะครับ ดังนั้น Raspberry PI ก็เป็น Master และ MCP3208 ก็จะเป็น Slave ของเรา
มาดูกันที่ละอุปกรณ์ครับ Port ของอุปกรณ์ที่เป็น Master นั้นก็จะประกอบด้วย
ฝั่ง Slave ก็จะมีขาดอย่างที่เห็นในรูปด้านบนครับ ได้แก่ CLK, DOUT, DIN, CS (Chip Select), DGND เมื่อได้ข้อมูลย่างนี้ก็ลงมือต่อกันได้เลยครับ เช่น MOSI (Master out slave in) ก็ต้องไปต่อกับ Din ของ Slave หรือ MISO (Master in slave out) ก็ต้องไปต่อกับขา Dout ของ Slave ครับ การต่อกับ Raspberry Pi GPIO ก็ตามภาพด้านล่างครับ
ทีนี้เพื่อความสะดวกของชีวิตกันเล็กน้อย ก็มีคนคิดประดิษฐ์ T-Cobbler ขึ้นมาเพื่อให้สะดวกในการต่อกับอุปกรณ์อื่นๆ บน Breadboard ครับ อุปกรณ์ตัวนี้ร้านเราขายตามลิงค์นี้ครับ มาพร้อมสายแพ (แต่ไม่รวม Breadboard นะครับ) จะเห็นว่า T-Cobbler จะทำหน้าที่แยกแรงดันไฟเลี้ยง 5 โวลต์ 3.3 โวลต์ และ GDN ไปไว้ที่จุดจ่ายแรงดัน Supply ของ Breadboard พอดีๆ เลยครับ เวลาจ่ายไฟเลี้ยงให้ IC ก็สามารถลากออกมาจจากด้านข้างของ Breadboard ได้หลายๆจุด
ทีนี้พอต่อแบบที่ว่าด้านบนก็จะได้ดังรูปนะครับ
ทีนี้จะขอเล่าให้ฟังคราวๆว่า การติดต่อ MCP3208 มันทำได้ยังไงนะครับ Time Diagram ด้านล่างเป็นตัวบอกว่าในแต่ละช่วงของการติดต่อ แต่ละ port ต้องทำอะไรบ้าง ดังนี้ครับ
ทีนี้ระหว่างที่รอและ Slave ยังไม่ได้เริ่มให้ข้อมูลกับ Master สาย Dout จะอยู่ที่ State HIgh Impedace นะครับ
ดังนั้นถ้าดูคราวๆแล้ว ในแต่ละ Sampling Master จะต้องส่งสัญญาณ Clock ออกไปรวม 24 ลูก และได้สัญญาณกลับมาตามที่ต้องการ ทีนี้ถ้า Raspberry Pi จับสัญญาณตลอดเวลา โดยเก็บทีละ Byte ก็จะกลายเป็นว่า Raspberry Pi ได้ข้อมูลมาทั้งหมด 24 บิต (3 byte) ดังต่อไปนี้
หน้าที่ของ Program ที่จัดการข้อมูล ซึ่งเราจะเขียนด้วย Python บน Raspberry Pi ก็จะต้องนำข้อมูลที่ได้อย่างที่กล่าวมาเรียงให้เป็นข้อมูลที่เราต้องการ ซึ่งจะมีค่าตามสัญญาณ Analog ที่วัด ตั้งแต่ 0 - 4096 นะครับ
เอาล่ะครับ มาถึงตัว Raspberry Pi กันหน่อยว่าจะต้องจัดการอย่างไรบ้างเพื่อให้คุุยกับ MCP3208 รู้เรื่อง
1. เริ่มต้นก็แน่นอนครับ ต้องลง Raspbian OS ซะก่อน โดยไปหาอ่านได้จากบทความของร้าน Arduitronics ตอน "Raspberry Pi - How to Cook Raspbian OS"
2. จากนั้นก็ ไปที่ LX Terminal จัดการกับ Library และตัว Download ที่ต้องใช้กันหน่อยครับ ตัวนี้เป็นโปรแกรมที่จะจัดการเรื่องการ Download ไฟล์ที่จำเป็นจาก Github มาให้ครับ
$ sudo apt-get install git
3. เสร็จแล้วเราต้องเข้าไปแก้ไฟล์ในระบบกันนิดหน่อยครับ โดยใช้คำสั่ง nano เพื่อให้สามารถใช้งาน SPI ได้โดย
$ sudo nano /etc/modules
แล้วให้เพิ่ม
spidev
ไปที่บรรทัดสุดท้ายของไฟล์
จากนั้นให้สั่งเปิดไฟล์ด้วย
$ sudo nano /etc/modprobe.d/raspi-blacklist.conf
แล้ว Comment เอา blacklist ออก ด้วยเครื่องหมาย # ที่เริ่มต้นบรรทัดครับ
#blacklist spi-bcm2708
ถ้าอนาคตอยากจะใช้ I2C ด้วยก็ comment ด้วยได้เลยครับ
4. ลงโปรแกรม Python และ ติดตั้งตามคำสั่งต่อจากนี้ครับ
$ cd ~
$ sudo apt-get install python-dev
$ git clone git://github.com/doceme/py-spidev
$ cd py-spidev/
$ sudo python setup.py install
จากนั้น Reboot ใหม่ด้วย
$ sudo reboot
มีข้อสังเกตที่สำคัญ (ที่ได้จากการทดสอบจริง) ดังนี้นะครับ
วันนี้เราจะใช้ LM35 ซึ่งเป็น Sensor วัดอุณหภูมิยอดฮิตของ TI มาเป็นตัวสาธิตเพื่อรับค่า Analog นะครับ ตัว LM35 ก็ใช้งานแสนจะง่าย มีขา 3 ขา จ่ายแรงดันอะไรก็ได้ ขอให้มากกว่า 3.3 VDC GND และขาสัญญาณ Analog output ซึ่งจะให้ค่าแรงดันประมาณ 10 mV ต่อ 1 องศาเซลเซียสครับ อยากได้ Data sheet ก็ตามนี้ครับ
จากนั้นจัดการต่อไฟเลี้ยง GND และเอาสัญญาณ CH0 จาก MCP3208 มารับค่าครับ
ดูตามรูปด้านล่างนะครับ
จากนั้นเปิด Python 2.7 กันครับ เราจะใช้ Editor ของ Python เพื่อตัดปัญหาการใช้ Space bar และ Tab กันครับ ทั้งนี้เนื่องจากภาษา Python ใช้การเว้น และ tab เป็นส่วนหนึ่งของ Syntax ว่าง่ายก็คือ ซี้ซั่วเว้นไม่ได้ครับ ไม่เหมือนกับภาษา C ที่ช่องว่างจะถูกข้ามไป ไม่ Compile
ลองดู Code ที่ผมใช้ครับ
import spidev, time
spi = spidev.SpiDev() spi.open(0,0) def analog_read(channel): r = spi.xfer2([4 | 2 |(channel>>2), (channel &3) << 6,0]) adc_out = ((r[1]&15) << 8) + r[2] return adc_out
reading = analog_read(0) voltage = reading * 3.3 / 4096 Temp = voltage * 99.5 print("Reading=%d\tVoltage=%f\tTemp=%2.2f" % (reading, voltage,Temp)) time.sleep(1) |
อย่าลืมนะครับ เตือนอีกครั้ง การ Copy แล้วไปปะ อาจจะทำให้ Complie ไม่ผ่านนะครับ ทั้งที่ดูแล้วเหมือนกันทุกอย่าง แต่การใช้ Space กับ Tab ก็ไม่เหมือนกันแล้วครับ ใน Python เดี๋ยวจะหาว่าตัวอย่างในนี้ Run ไม่ได้ซะงั้น
ถ้าอยากได้ไฟล์ acd_test.py นี้ก็ติดต่อเข้ามาที่ arduinoengineer@gmail.com ครับ ฝ่าย Support เราจะช่วยส่งไฟล์ไปให้กับลูกค้าของเราครับ
คราวนี้เรามาดูรายละเอียดใน Code กันนิดหน่อยครับ ใน Code นี้เป็นการสร้าง Function เพื่ออ่านค่า Analog 12 Bit เข้ามาเพื่อคำนวณอุณหภูมิ โดย ฟังก์ชั้น analog_read(channel) จะรับค่าตัวแปร Channel เข้ามา แล้วเอาไปสั่งต่อให้กับ MCP3208 จากนั้นข้อมูลที่เข้ามาก็ประมวลผลกันเล็กน้อย โดยเลือกเฉพาะ byte ที่สอง บางตำแหน่ง (เลือก Byte ที่สองโดยเอามา and กับ 15) แล้ว Shift ไปทางซ้าย และรวมกับ Byte ที่ 3
จากนั้นก็เอามาคำนวณเพื่อเทียบกับ Full scale ที่ 4096 กับค่าที่วัดได้ แล้วแปลงต่อเป็นค่าอุณหภูมิครับ
เรียบร้อยแล้วก็ Run โดย กดปุ่ม F5 ก็ได้ครับ
ผลการทำงานก็ตามภาพด้านล่างครับ
Link ที่น่าสนใจ / ข้อมูลเพิ่มเติม
วันนี้พอแค่นี้นะครับ ท่านใดมีข้อสงสัย หรือ ต้องการให้ข้อเสนอแนะ ก็ตามไปได้ที่ Facebook.com/arduitronics นะครับ
**** Arduitronics.com เราตอบแทนลูกค้าด้วยความรู้ *****
ไม่ได้ขายของอย่างเดียวนะจ๊ะ อิอิ
โดย Mountain A
หน้านี้เป็นสารบัญของบทความที่ปรากฏในเว็บของ Arduitronics.com นะครับ จะขอแบ่งออกเป็นหัวข้อตามกลุ่มของสินค้าในร้านดังต่อไปนี้
หน้าที่เข้าชม | 15,393,408 ครั้ง |
ผู้ชมทั้งหมด | 5,896,486 ครั้ง |
เปิดร้าน | 21 พ.ค. 2556 |
ร้านค้าอัพเดท | 16 ก.ย. 2568 |