Python可以這樣玩(20):PyMata 與I2C


到目前為止,大部分基礎的 Arduino 電路實驗我們學會了,相信大家對於 pySerialpyFirmata 擴充庫也有了基本的認識,我們現在即將進入第二個階段。

在這之前,先回顧一下之前我們學的七段顯示器,如果用最原始的方法,一個小小的七段顯示器幾乎就把 Arduino UNO 的腳位都站滿了,當我把我的實驗作品PO上臉書的時候,就有網友建議我可以使用BCD的方式簡化線路,74477448這兩個IC就具備了BCD轉七段顯示器的功能,不過,比較常用的方法是使用 74HC595來做,它把序列輸入轉成串列輸出,加上可以串接,因此減少了非常多的腳位並可以連接非常多的七段顯示器。

從這裡得到的啟示是,如果可以使用一些特殊的IC或是特殊的通訊協定,基本上可以做到的事情就更多了。

要更進一步釐清觀念,我們就來談談三種通訊協定:UARTI2C、以及SPI

UARTI2CSPI

對於專業電子工程人員而言,當然非常清楚UARTI2CSPI之間的差別,然而對於不是電子工程背景的玩家,對這些協定就比較陌生了,但是我們必須去面對,因為ArduinoRaspberry Pi開發板就有這些介面。

Arduino而言,最原初的Arduino就有UART,而演化不久後也加添了I2C,現在無論Arduino家族開發板如何演化,多會具備UARTI2C。而RPi方面則是從2012年最原初的RPi開始,就同時具備這三種介面,事實上Arduino開發板所用的微控制器晶片,其本身也是具備SPI介面功能的,只是Arduino將此功能掩蓋、關閉而已。

UART是用於 RS-232 USB 的通訊協定,中文名稱是通用非同步收發傳輸器。我們將 Arduino 插入電腦的USB孔,事實上開發板就開始以此方式與電腦通訊了。從下圖中我們就可以看到每種通訊功能所使用的腳位,還記得 d0d1吧,Rx/Tx就是 UART的腳位。





接下來進階的課程中,就會開始用到 SPI I2C

I2C

I²CInter-Integrated Circuit)字面上的意思是積體電路之間,它其實是I²C Bus簡稱,所以中文應該叫積體電路匯流排,它是一種串列通訊匯流排,使用多主從架構,由飛利浦公司在1980年代為了讓主機板嵌入式系統手機用以連接低速週邊裝置而發展。I²C的正確讀法為「I平方C」("I-squared-C"),而「IC」("I-two-C")則是另一種錯誤但被廣泛使用的讀法。自2006111日起,使用I²C協定已經不需要支付專利費,但製造商仍然需要付費以取得I²C從屬裝置位址。

I²C只使用兩條雙向漏極開路Open Drain)(串列資料(SDA)及串列時脈(SCL),我們在前面使用 74HC595就用到了類似的概念)並利用電阻將電位上拉。I²C允許相當大的工作電壓範圍,但典型的電壓準位為+3.3V+5v

I²C的參考設計使用一個7位元長度的位址空間但保留了16個位址,所以在一組匯流排最多可和112個節點通訊。節點的最大數量受限於位址空間以及400 pF的總的匯流排電容400 pF總電容也限制了實際通訊距離只有幾米。

常見的I²C匯流排依傳輸速率的不同而有不同的模式:標準模式100 Kbit/s)、低速模式10 Kbit/s),但時脈頻率可被允許下降至零,這代表可以暫停通訊。而新一代的I²C匯流排可以和更多的節點(支援10位元長度的位址空間)以更快的速率通訊:快速模式400 Kbit/s)、高速模式3.4 Mbit/s)。

I²C被應用在簡單且其製造成本較傳輸速度更為重要的週邊上。一些常見的應用如下:
·        為了儲存使用者的設定而存取NVRAM晶片。
·        存取低速的數位類比轉換器DAC)。
·        存取低速的類比數位轉換器ADC)。
·        改變監視器的對比度、色調及色彩平衡設定(視訊資料通道)。
·        改變音量大小。
·        取得硬體監視及診斷資料,例如中央處理器的溫度及風扇轉速。
·        讀取實時時鐘Real-time clock)。
·        在系統裝置中用來開啟或關閉電源供應。

在我們的進階課程中,就會開始實做I2C的電路。

SPI

串行外設介面Serial Peripheral Interface BusSPI),是一種用於短程通訊的同步串行通訊介面規範,主要應用於單晶片系統中。類似I²C 這種介面首先被Motorola(摩托羅拉)公司開發,然後發展成了一種行業規範。典型應用包含SD卡和液晶顯示器。 SPI裝置之間使用全雙工模式通訊,包含一個主機和一個或多個從機。主機產生待讀或待寫的影格資料,多個從機通過一個片選線路 決定哪個來回應主機的請求。 有時SPI介面被稱作四執行緒介面,SPI準確來講稱為同步串列埠。

SPI匯流排規定了4個保留邏輯訊號介面:
·        SCLKSerial Clock):串行時鐘,由主機發出
·        MOSIMaster Output,Slave Input):主機輸出從機輸入訊號,由主機發出
·        MISOMaster Input,Slave Output):主機輸入從機輸出訊號,由從機發出
·        SSSlave Selected):選擇訊號,由主機發出,一般是低電位有效
儘管上面的引腳名稱是最常用的,但在過去,有時會使用其他引腳命名約定,因此舊IC產品的SPI埠引腳名稱可能有所不同。

如果我們要控制8x8 LED矩陣,就可以搭配 MAX7219 晶片來達成,這就是一種SPI的連接方式。

在初階的課程中,我們實驗的元件都是直接使用數位或類比腳位來控制,在進階的課程中,則會開始使用以IC為基礎的各種感應器,而這些感應器都是使用以 I2C SPI 匯流排的方式來通訊。我們就先從 I2C開始。




上圖就是一個 I2C 連接方式的示意圖,一個 Master 可以連接多個 Slave感應器,在 Arduino Uno 中,類比腳位 4 5是用來與 SDA 以及 SCL 互動的。所以一般的接法大概會是這樣:




從上圖我們也可以看出,類比4, 5 腳位等同於開發板左上方的 SCL, SDA腳位,兩個電阻則為上拉電阻。

匯流排上有四種不同的操作模式,雖然大部分裝置只作為一種角色和使用其中兩種操作模式:
·        主節點(Master, 主動裝置)傳送 - 主節點傳送資料給從節點
·        主節點(Master, 主動裝置)接收 - 主節點接收從節點資料
·        從節點(Slave, 從動裝置)傳送 - 從節點傳送資料給主節點
·        從節點(Slave, 從動裝置)接收 - 從節點接收主節點資料

一開始,主節點處於主節點傳送模式,傳送起始位START),跟著傳送希望與之通訊的從節點的7bit位位址,最後再傳送一個bit讀寫位,該資料位表示主節點想要與從節點進行讀(1)還是寫(0)操作。
如果從節點在匯流排上,它將以ACK字元位元位應答(低有效)該位址。主節點收到應答後,根據它傳送的讀寫位,處於傳送模式或者接收模式,從節點則處於對應的相反模式(接收或傳送)。

位址和資料首先傳送最高有效位 起始位在SCL位高時,由SDA上電平從高變低表示;停止位在SCL為高時,由SDA上電平從低變高表示。其他SDA上的電平變化在SCL為低時發生。

如果主節點想要向從節點寫資料,它將傳送一個位元組,然後從節點以ACK位應答,如此重複。此時,主節點處於主節點傳送模式,從節點處於從節點接收模式。
如果主節點想要讀取從節點資料,它將不斷接收從節點傳送的一個個位元組,在收到每個位元組後傳送ACK進行應答,除了接收到的最後一個位元組。此時,主節點處於主節點接收模式,從節點處於從節點傳送模式。

此後,主節點要麼傳送停止位終止傳輸,要麼傳送另一個START位元以發起另一次傳輸(即「組合訊息」)。

看完了通訊的方式,就要開始動手做了。第一步先從 AVR C 的程式設計開始。不過很不幸的,溫度感應器百百種,要談I2C,就必須使用 I2C 架構的感應器才行。不過我發現我手上有三種溫度感應器,分別是LM35DHT11 TMP102,為了讓課程更具完整性,我決定把三種感應器的使用方式都討論一下。

留言

這個網誌中的熱門文章

Python可以這樣玩(16):共陰/共陽七段顯示器

Python可以這樣玩(11):數學繪圖

Python可以這樣玩(15):蜂鳴器與音樂