一塊兒玩轉樹莓派(7)——樹莓派模數/數模轉換實踐

一塊兒玩轉樹莓派(7)——樹莓派模數/數模轉換實踐

若是你跟隨本系列博客閱讀到此,那麼我相信,你已經可以使用樹莓派的GPIO接口作許多有趣的事情了。可是不知你是否有發現,GPIO功能接口不管是輸入仍是輸出,都只有高電平或低電平這兩種選項,抽象到數學中,即只有0和1兩種數值選項,這種離散數值的信號咱們將其稱爲數字信號。更多時候,咱們須要使用的元件並不是只有開和關兩種狀態,這時候就須要用數值連續的信號來表達,這種連續的信號咱們稱之爲模擬信號。本篇博客,咱們將初步涉獵在樹莓派上如何處理模擬信號。python

1、樹莓派模數轉換模塊基礎

其實,直接使用GPIO的功能引腳並不是徹底不能處理模擬信號,咱們知道不管須要多少種狀態信號,經過GPIO的電平高低來處理都是沒法實現的,可是你必定還記得PWM脈衝寬度調製技術,這其實就是一種將數字信號轉換成模擬信號的方式,例如在前面的RGB實驗中,咱們曾使用PWM技術來控制3種發光二極管的發光明暗程度,若是將二極管的全亮定義爲值1,全暗定義爲值0,則在明暗之間能夠經過設置不一樣的佔空比來實現,例如須要亮度值爲0.5時,只須要設置佔空比爲50%便可。經過PWM技術,雖然咱們每一個精確的時刻輸出的依然是數字信號(0或1),但最終做用到元件上的信號是模擬的,這就完成了最簡單的數模轉換。編程

一樣的道理,對於某些外接元件來講,其輸出的信號也多是模擬的,例如溫度、光亮傳感器,若是直接經過GPIO來獲取這些元件的信號是模擬的,解析會很是困難,這時咱們就須要一個數模轉換模塊來幫助咱們將其轉換爲數字信號。markdown

一、關於模數轉換

數模轉換器,又稱D/A轉換器,簡稱DAC。用來把數字量轉換成模擬量的器件,關於數模轉換器的電路和工做原理,不在本篇博客的核心討論範圍內,若是你有興趣能夠查閱數字電路和模擬電路的相關書籍。對其對應,模數轉換器,又稱爲A/D轉換器,簡稱ADC。用來把模擬信號轉換爲數字信號。樹莓派自己沒有集成模數轉換模塊,咱們須要外接一個轉換單元,在本實驗中,咱們採用基於PCF8591芯片的模數轉換模塊。ide

二、PCF8591芯片

PCF8591是一個單片集成,單獨供電,低功耗的8位數A/D轉換器,其芯片自己以下圖所示:測試

一塊兒玩轉樹莓派(7)——樹莓派模數/數模轉換實踐

能夠看到其左右各有8個引腳,引腳功能圖以下:編碼

一塊兒玩轉樹莓派(7)——樹莓派模數/數模轉換實踐

如上圖所示,其AIN0到AIN3都是模擬輸入引腳,其用來輸入外接元件的模擬信號,它還有1個模擬輸入引腳AOUT,用來輸出模擬信號。.net

A0,A1,A2這3個引腳用來進行硬件地址編程,在嵌入式編程中,每一個可編程的引腳咱們將其理解爲一個二進制位,3個引腳能夠表達0-7這8個數字(000,001,010,011,100,101,110,111),所以在同一個I2C總線上,實際能夠同時鏈接8個PCF8591芯片進行工做(I2C總線咱們後面會介紹)。code

VSS是接地引腳,VDD是工做電壓引腳,AGND是模擬信號接地引腳,VREF是基準電源引腳。blog

OSC引腳爲外部時鐘輸入端或內部時鐘輸出端,EXT若是接地,表示使用內部時鐘,不然表示使用外部時鐘。接口

SCL和SDA是I2C總線接口引腳,咱們使用這兩個引腳來進行數據傳輸,後面會介紹。

下面是PCF8591工做的電路原理圖:

一塊兒玩轉樹莓派(7)——樹莓派模數/數模轉換實踐

舒適提示,在閱讀本篇博客時,難度可能要比本系列的前幾篇博客大,你可能會感受雲裏霧裏,不要着急,後面咱們會經過實驗來幫助你理解模數轉換以及I2總線的工做方式,掌握了這些,你的樹莓派開發本領將進一步提高。

三、PCF8591實驗模塊

上一小節咱們介紹了PCF8591芯片的引腳用法,實際在本實驗中,咱們並不會直接使用這個芯片,而是使用基於PCF8591芯片的一個工做模塊,以下圖所示:

一塊兒玩轉樹莓派(7)——樹莓派模數/數模轉換實踐

如上圖所示,此模塊功能很是豐富,咱們逐一介紹。

左邊一列引腳做用分別爲:

  • AOUT :內部芯片的DA 輸出接口
  • AIN0 :內部芯片的模擬輸入接口 0
  • AIN1 :內部芯片的模擬輸入接口 1
  • AIN2 :內部芯片的模擬輸入接口 2
  • AIN3 :內部芯片的模擬輸入接口 3

右邊一列引腳的做用爲:

  • SCL :I2C 通訊接口
  • SDA :I2C 通訊接口
  • GND :模塊地
  • VCC :電源接口 外接 3.3v-5v

除此以外,P4,P5,P6三個地方咱們能夠經過接短路帽的方式來選擇是否接入相關功能。

P4:接上短路帽,表示將熱敏電阻接入電路。

P5:接上短路帽,表示將光敏電阻接入電路。

P6:接上短路帽,表示將0-5V的可調節電壓接入電路。

若是P4,P5,P6都不接短路帽,可使用外部元件經過4個AIN引腳進行輸入。關於這幾個功能如何使用,後面咱們會介紹。

此模塊的工做示意圖以下:

一塊兒玩轉樹莓派(7)——樹莓派模數/數模轉換實踐

4.I2C總線基礎知識

I2C總線是有Philips公司開發的一種簡單、雙向的同步串行總線。只須要兩根線便可實現鏈接在總線上的設備間進行通訊。在I2C總線的通信協議中,SDA用來傳輸數據,SCL是串行的時鐘線,傳輸流程以下圖所示:

一塊兒玩轉樹莓派(7)——樹莓派模數/數模轉換實踐

只看圖你可能會感受很是疑惑,結合樹莓派工做起來,其實要理解並不複雜,在I2C協議中,樹莓派就是主機,鏈接的PCF8591就是從機,主機與從機間不管是發送數據仍是接受數據,都是由主機先發起,形象化的流程以下:

1.主機觸發開始通訊條件(SDA和SCL電平知足必定條件)。

2.經過地址找到要通訊的從機(即PCF8591的3個地址編程引腳設置的地址)。

3.主機發送工做命令,即指定要從從機讀數據仍是寫數據,讀哪一個通道的數據等(PCF8591有4個輸入通道)。

4.收到數據會發送ACK回執。

5.結束這次通信後,主機發送完成指令給從機(SDA和SCL電平知足必定條件)。

5.幾個重要的指標概念

1.位數

ADC元件的位數很是重要,它描述了一種可讀概念,以PCF8591爲例,其實8位的數模轉換芯片,也就是說其輸出的數字量是0到255之間的數值,一共256種(2的8次方)。

2.基準電壓

基準電壓用來標準數模轉換芯片輸出的數值與電壓之間關係,例如基準電壓爲5V,則0到255這256個刻度至關於將5V的電壓平均分紅了255份,數值沒增長1,至關於電壓約增長0.019V。

2、實驗:測定溫度和光亮度

如今,咱們已經準備好了須要使用到的基礎知識,能夠開始咱們的試驗了。PCF8591自帶光感與溫度傳感器,咱們嘗試使用這兩個傳感器來讀取環境的溫度與亮度。

一、連線

首先,咱們能夠先使用3個短路帽將PCF8591模塊的P四、P五、P6都進行短接,以下圖所示:

一塊兒玩轉樹莓派(7)——樹莓派模數/數模轉換實踐

短接後,至關於咱們將PCF8591模塊自帶的可調節輸出電壓、光感信號輸出和溫度信號輸出都接入了電路,能夠直接經過I2C總線對其數據進行獲取。

以後,咱們將PCF8591模塊模塊的SCL、SDA分別鏈接樹莓派對應功能的引腳,GND進行接地,VCC接5V。關於找到樹莓派上這些引腳的位置,能夠參考下面博客:

https://my.oschina.net/u/2340880/blog/5123429

筆者這裏使用擴展板來接線,會更加直觀方便,以下圖所示:

一塊兒玩轉樹莓派(7)——樹莓派模數/數模轉換實踐

如今,咱們已經完成了接線部分的工做。

二、代碼編寫

由於須要使用到樹莓派的I2C總線功能,在開始編碼前,咱們須要將樹莓派的I2C功能開啓,打開樹莓派的配置頁面,在其interfaces選項中打開SPI和I2C選項,以下圖所示。

一塊兒玩轉樹莓派(7)——樹莓派模數/數模轉換實踐

咱們先將完整的實驗代碼奉上:

#coding:utf-8

#SMBus (System Management Bus,系統管理總線) 
import smbus   #在程序中導入「smbus」模塊
import time

bus = smbus.SMBus(1)         #建立一個smbus實例

# 數據讀取的方法
def read(chn): #channel
    if chn == 0:
        #發送一個控制字節到設備 表示要讀取AIN0通道的數據
        bus.write_byte(0x48,0x00)   
    if chn == 1:
        #發送一個控制字節到設備 表示要讀取AIN1通道的數據
        bus.write_byte(0x48,0x01)
    if chn == 2:
        #發送一個控制字節到設備 表示要讀取AIN2通道的數據
        bus.write_byte(0x48,0x02)
    if chn == 3:
        #發送一個控制字節到設備 表示要讀取AIN3通道的數據
        bus.write_byte(0x48,0x03)
    bus.read_byte(0x48)         # 空讀一次,消費掉無效數據
    return bus.read_byte(0x48)  # 返回某通道輸入的模擬值A/D轉換後的數字值

if __name__ == "__main__":
    while True:
        print('電位計 AIN3 = ', 0.0196 * read(3))   #電位計模擬信號轉化的數字值
        print('光敏電阻 AIN0 = ', 255 - read(0))   #光敏電阻模擬信號轉化的數字
        print('熱敏電阻 AIN1 = ',255-read(1))      #熱敏電阻模擬信號轉化的數字值
        time.sleep(2)

下面咱們來詳細解釋下上面的代碼,首先smbus是一個Python模塊,咱們以前並沒使用過,咱們此次實驗不使用GPIO,使用smbus來進行I2C總線管理。

在覈心邏輯執行前,首先須要進行總線管理器的實例化,使用以下方法:

bus = smbus.SMBus(1)

其中的參數表示要使用的I2C版本。

前面咱們分析過,在I2C總線通訊中,主機先要發送指令告訴從機要作什麼,對應代碼中就是write_byte方法,這個方法用來向PCF芯片發送一個8位的控制指令,經過查閱芯片手冊,很容易找到這個8位的控制指令每一位的意義,以下圖所示:

一塊兒玩轉樹莓派(7)——樹莓派模數/數模轉換實踐

咱們從左往右來分析上圖。

對於上圖,咱們在多解釋一下,這個8位的控制指令,第1位和第5位都是默認填充位,都用0填充,目前沒有任何意義。

第2位表示是否開啓AOUT輸出口,只有這一位爲1,數模轉換纔會工做,數字信號纔會被轉換爲模擬信號從AOUT引腳輸出。(本次實驗咱們暫不使用)

第3位和第4位用來編程控制輸入模式,這兩位能夠組成的數值有00,01,10,11共四種,設置爲00表示AIN端口與輸入通道一一對應。01,10,11這3種模式通道的值都是通過 處理的,上圖有明確的標註,好比在11模式下,通道0的值是AIN0和AIN1輸入的差分,通道1的值是AIN2和AIN3輸入的差分。(本次實驗咱們也無需使用這一功能)

第6位的做用是設置是否自動切換通道,當其設置爲1時,每次讀取數據後,通道都會切換,例如第一次讀取通道0的數值,第二次會在讀取時,會自動讀取通道1的數值。

第7位和第8位用來指定從哪一個通道讀取數值,有4個通道可用,分別經過00,01,10,11進行設置。

咱們再來看下write_byte方法:

bus.write_byte(0x48,0x00)

這個方法有兩個參數,第2個參數就是咱們上面說的指令參數,其用16進製表示,例如0x03設置爲:

第1位 第2位 第3位 第4位 第5位 第6位 第7位 第8位
0(佔位) 0(不使用AOUT) 0(一一對應模式) 0(一一對應模式) 0(佔位) 0(不啓動切換通道) 1(設置要讀取的通道) 1(設置要讀取的通道)

 write_byte這個方法的第1個參數用來設置I2C總線中要爲哪個從機設置指令,PCF的地址設置是7位,查閱手冊以下:

一塊兒玩轉樹莓派(7)——樹莓派模數/數模轉換實踐

能夠看到第4位到第7位都是固定的,前3位是可編程的,還記得PCF的A0到A3引腳吧,就是讓主機來分配從機地址使用的。咱們能夠知道,PCF從機的地址必定在二進制數01001000(0x48)到01001111(0x4F)之間,要查閱當前鏈接到樹莓派的PCF從機的地址,能夠在樹莓派終端輸入以下指令:

sudo i2cdetect -y 1

效果以下圖所示:

一塊兒玩轉樹莓派(7)——樹莓派模數/數模轉換實踐

從圖中能夠看到,樹莓派當前只鏈接了一個I2C從機模塊,分配的地址是0x48。

如今,上面的代碼對你來講很是好理解了,須要注意,其中除了0x48表示的是PCF從機的地址外,其餘十六進制數都是指令。指令設置完成後,接下來就能夠進行數據的通訊,使用以下方法:

bus.read_byte(0x48)

這個方法用來經過I2C總線從PCF讀取數據,上面代碼中咱們在讀取數據時連續調用了兩次,這是由於PCF8591接收到讀取數據的命令後會同時進行上一次轉換數據的傳輸和本次數據的轉換,空讀一次能夠消費掉不正確的數據。

還有一點須要注意,對於咱們使用的PCF8591模塊來講,其自帶的可調節電壓會輸出到第4個通道,光敏傳感器的數據會輸出到第1個通道,熱敏傳感器的數據會輸出到第2個通道,在本次實驗中,第3個通道不被使用(若是你使用的PCF8591模塊和筆者的不太同樣,對應通道可能會不一樣,能夠自行測試)。

3、盡情玩耍

如今,你能夠嘗試在樹莓派上運行寫好的程序,經過輸出能夠看到當前的可調節電壓、環境亮度和環境溫度的狀況。你能夠嘗試使用螺絲刀對電位計進行調節,能夠實時的看到輸出電壓的改變,能夠關燈和開燈來改變環境亮度,你也能夠將熱敏傳感器握在手中,這些均可以明顯的從輸出信息上看到環境數據的變化。以下圖所示:

一塊兒玩轉樹莓派(7)——樹莓派模數/數模轉換實踐

此次,關於樹莓派編程,咱們學到了一些新的東西,使用I2C總線和數模轉換模塊咱們能夠作出更多有意思的東西,好比紅外控制的自制電視機?好比有有馬達驅動的遙控小車?等等...。你能夠作好準備,咱們後面會一塊兒開發一些更好玩的東西!

專一技術,懂的熱愛,願意分享,作個朋友

QQ:316045346

相關文章
相關標籤/搜索