วันพฤหัสบดีที่ 10 มีนาคม พ.ศ. 2559

ทดสอบ MCP3008 กับบอร์ด Raspberry Pi A+

ตัวอย่างโปรแกรมใช้งาน IC หมายเลข MCP3008 โดยโปรแกรมนี้จะอ่านค่าจาก สวิทช์ 5 ปุ่มที่ ขา Ch0 และอ่านค่า VR 10k ที่ขา Ch1 แล้วแปลงค่าเป็น Digital Input ไปยัง Raspberry Pi

Switch ของ DFRobot 5 ปุ่ม แต่ใช้สายไฟแค่ 3 เส้น Vcc, Gnd และ Output



หลักการทำงานของสวิทช์

ผังการเชื่อมต่อสวิทช์

วงจรของสวิทช์จะใช้ไฟเลี้ยงเข้าขาที่ 3 ผ่าน R1 กลับไปยังขา Output ไปยังขา Analog Input ของ MCP3008 ซึ่งจะรับค่าที่แปลงไฟเป็นระดับจาก 0-1023 (10 bit)

เมื่อกดปุ่ม S1-S5 ซึ่งมี R ต่อคั่นไว้ด้วยค่าต่างๆ คือ 330, 620, 1k, 3.3k  ตามลำดับ หากกดปุ่มใดๆ แล้วไฟที่กลับเข้าไปยังขา Analog Input จะเปลี่ยนแปลงค่าตามไปด้วย

ดังนั้นการเขียนโปรแกรมต้องตรวจวัดก่อนว่า กดปุ่มที่ 1 แล้วอ่านค่ากลับมาได้เท่าใด กดปุ่มอื่นๆ ได้ค่าเท่าใด แล้วนำมาเขียนโปรแกรมให้ทำงานตามที่เราต้องการ

ปัญหาการรับค่าทาง Analog จะมีบ้างเมื่อเรากดปุ่มแล้วค่าไฟฟ้าเปลี่ยนแปลงขึ้นลงเล็กน้อย และค่าที่แปลงเป็น Digital ก็เปลี่ยนตาม ทำให้ค่าที่ได้ไม่นิ่งเท่าที่ควร เราจึงต้องเผื่อเวลา หรือคำนวณให้ปัดเศษ และมีช่วงของค่าที่รับด้วย

และปัญหาอีกประการหนึ่งที่ผู้เขียนพบและสร้างปัญหาได้พักใหญ่ๆ เพราะต่อไฟเลี้ยงจาก 5V เข้าไปแล้วค่าเพี้ยน เพราะเดิมต่อเพียง 3.3V เท่านั้น ดังนั้นวงจรเราต้องกำหนดค่าไฟให้ถูกต้องอย่างใดอย่างหนึ่ง

ค่าที่ได้จากไฟเลี้ยง 5V
#5V#Green  = 2.01-2.02#Yellow = 1.82#White  = 2.86-2.87#Blue   = 2.22-2.23#Red    = 2.5
ค่าที่ได้จากไฟเลี้ยง 3.3V
#3v3#Green  = 2.68 (2.7)#Yellow = 2.59 (2.6)#White  = 3.07-3.08 (3.1)#Blue   = 2.77-2.78 (2.8)#Red    = 2.91 (2.9) 

ตัวอย่างซอร์สโค้ด

#!/usr/bin/python

import spidev
import time
import os

# Open SPI bus
spi = spidev.SpiDev()
spi.open(0,0)

# Function to read SPI data from MCP3008 chip
# Channel must be an integer 0-7
def ReadChannel(channel):
  adc = spi.xfer2([1,(8+channel)<<4,0])
  data = ((adc[1]&3) << 8) + adc[2]
  return data

# Function to convert data to voltage level,
# rounded to specified number of decimal places.
def ConvertVolts(data,places):
  volts = (data * 3.3) / float(1023)
  volts = round(volts,places)
  return volts

# Define sensor channels
sw_channel = 0
vr_channel = 1

# Define delay between readings
delay = 0.1

#5V
#Green  = 2.01-2.02
#Yellow = 1.82
#White  = 2.86-2.87
#Blue   = 2.22-2.23
#Red    = 2.5

#3v3
#Green  = 2.68 (2.7)
#Yellow = 2.59 (2.6)
#White  = 3.07-3.08 (3.1)
#Blue   = 2.77-2.78 (2.8)
#Red    = 2.91 (2.9) 


print("Please press a key.");
last_vol = 0
nVol = 0
while True: 
  # Read the light sensor data
  sw_level = ReadChannel(sw_channel)
  sw_volts = ConvertVolts(sw_level,1)

  vol_level = ReadChannel(vr_channel)
  if (vol_level > 0):
    nVol = (vol_level * 100)/1023
    // จะปัดเศษทศนิยม
  if (nVol > 0 and nVol <> last_vol):
    print(nVol, last_vol, vol_level)
    os.system("mpc volume "+ str(int(nVol)))
    last_vol = nVol
  if (sw_volts < 3.2):
    if (sw_volts == 2.6):
      print("Prev")
      os.system("mpc prev")
    if (sw_volts == 2.7):
      print("Pause/Play")
      os.system("mpc toggle")
      time.sleep(0.3)
    if (sw_volts == 2.8):
      print("Next")
      os.system("mpc next")
    if (sw_volts == 2.9):
      print("Stop")
      os.system("mpc stop")
    if (sw_volts == 3.1):
      print("Press key again to SHUTDOWN!!!");
      time.sleep(2)
      sw_level = ReadChannel(sw_channel)
      sw_volts = ConvertVolts(sw_level,1)
      if sw_volts == 3.1:
        print("SHUTDOWN!!!")
        os.system("sudo /sbin/shutdown -h now")
      else:
        print("Nothing to do.")
      
    time.sleep(0.05)

  # Wait before repeating loop
  time.sleep(delay)


VR 10k ต่อเข้าขา Ch1 ของ MCP3008


จากตัวอย่างในการคำนวณค่า vol_level จากสูตร nVol = (vol_level * 100)/1023

ค่า nVol จะถูกปัดเศษลงตามหลักของ Python โดยผลจะกลายเป็น Integer แต่ถ้าต้องการผลเป็น float ก็เพิ่มเครื่องหมาย . ต่อท้าย หรือ .00 ต่อท้าย เช่น

>>> (1000 * 100)/1023
97
>>> (1000 * 100.)/1023
97.75171065493646

หากสงสัยหรือมีข้อเสนอแนะอะไรสามารถโพสต์คอมเม้นท์ไว้เพื่อปรับปรุงแก้ไขให้ถูกต้องต่อไป... ขอบคุณมากครับ...

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

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

Driver สำหรับ USB UART TTL

https://drive.google.com/open?id=0B80EqvaAGSB8dU9EMXdwQmJCLVE