樹莓派:類比轉數位處理

一、什麼是類比轉數位

類比數位轉換器(英語:Analog-to-digital converter, ADC, A/D or A to D),是指將類比訊號轉換成0101的數位訊息,由於電腦僅能處理數位資料,那如何將自然界的類比訊號轉換為數位訊號呢!這次是屬於非常基礎的概念認識,先不談晶片也不談程式設計!

二、與二天王(SPI與I2C)的糾纏

這次談硬不談軟,先了解二個很重要的週邊通訊協定SPI與I2C,建立最基本的概念後,未來不管是樹莓派、Arduino或是Microbit,都一樣可以適用,其實也可以上網查詢看看,目前市場上已經有各式各樣的感測與顯示模組,讓我們可以輕易的完成更多的工作。

三、利用MCP3008讀取類比訊號

樹莓派不像Arduino與Microbit有類比輸入,所以必須借助外在晶片來處理,這種晶片模組也有不少,可以依需要選擇。本次介紹最便宜的mcp3008晶片來解決這個問題。 首先啟用樹莓派的SPI介面,並說明mcp3008晶片的腳位如何與樹莓派連接,最後才利用gpiozero的MCP3008物件模組來輕易的處理讀取的問題。內容有點多,但卻是走向更遠方的起點!

from gpiozero import MCP3008, PWMLED
from time import sleep

# 使用generator的用法,可自行測試
# def convert_temp(gen):
#     for value in gen:
#         yield value


pwmled = PWMLED(27)
adc_pr = MCP3008(0)
adc_x = MCP3008(1)
adc_y = MCP3008(2)

try:
    while True:
        data = adc_pr.value
        pwmled.value = data
        print('Light: {:.2f}'.format(data))
        print('X={:.2f}'.format(adc_x.value))
        print('Y={:.2f}'.format(adc_y.value))
        sleep(1)
except KeyboardInterrupt:
    pass

# 使用generator的用法,可自行測試
# for temp in convert_temp(adc.values):
#     pwmled.value = temp
#     print('Light: {}'.format(temp))
#     sleep(1)

上面的程式碼是使用gpiozero,簡化了許多MCP3008的底層通訊與資料取得轉換,但也可以自己撰寫,如下程式碼。

import spidev
import time
import os

spi = spidev.SpiDev()
spi.open(0, 0)
spi.max_speed_hz = 500000

# 讀取某 channel 類比轉換出來的數位值,須了解MCP3008的資料交換機制
# 同時也要了解 Python 的位元運算方法,才可以理解這段程式
def ReadChannel(channel):
    adc = spi.xfer2([1, (8+channel) << 4, 0])
    data = ((adc[1] & 3) << 8) + adc[2]
    return data

# 將資料值轉換為電壓值
def ConvertVolts(data,places):
    volts = (data * 3.3) / float(1023)
    volts = round(volts,places)
    return volts

light_channel = 1
delay = 1

try:
    while True:
        light_level = ReadChannel(light_channel)
        light_volts = ConvertVolts(light_level, 2)

        print("--------------------------------------------")
        print("Light: {} ({}V)".format(light_level,light_volts))

        time.sleep(delay)

except KeyboardInterrupt:
    print("Exception: KeyboardInterrupt")

Last updated