2013年6月7日 星期五

[ 認識與使用 Gertboard ] 第五部曲 - 數位轉類比 ( MCP4802 ) 和類比轉數位 ( MCP3002 ) 轉換器 ( D to A and A to D converters )

學習樹莓派週邊不容錯過的學習利器 "Assembled Gertboard (Rev2.0)",心動不如馬上行動!!露天賣場:

Assembed Gertboard (Rev2.0) - 利用 Raspberry Pi (樹莓派) 學習與開發電子 (週邊) 的最佳拍檔

PiGertboard 套件 (A) - Raspberry Pi (樹莓派) Gertboard 嵌入式套件

PiGertboard 套件 (B) - Raspberry Pi (樹莓派) Gertboard 外接式套件

Gertboard - A to D and D to A Converters ( 橙色部分 ),source: Gertboard User Manual (Rev 2.0)

Gertboard - D to A Converter 電路圖,source: Assembled Gertboard Schematics

Gertboard - A to D Converter 電路圖,source: Assembled Gertboard Schematics

Gertboard -  電路圖,source: Assembled Gertboard Schematics

[6] 數位轉類比和類比轉數位轉換器 ( D to A and A to D converters )

在 GertBoard  ( GB )上所使用的 ADC 與 DAC 晶片都是 8-pin 的 IC,但是兩者的封裝不一樣,DIP 封裝的是 MCP3002,SOIC 封裝的是 MCP4802。

MCP3002 是雙通道擁有 10-bit 解析度的類比轉數位 IC,使用 SPI 通訊介面;MCP4802 是雙通道擁有 8-bit 數位轉類比 IC,使用 SPI 通訊介面。

這兩顆 IC 都是使用 SPI 匯流排與樹莓派做通訊,分別連接到 GertBoard J2 上標示為 MOSI  ( Master Out / Slave Out ) 、MISO ( Master In / Slave Out )、SCK ( Clock )、CSnA ( Chip Select A )、CSnB ( Chip Select B)。MOSI 是由樹莓派輸出;MISO 是晶片輸入到樹莓派;SCK 是脈衝時鐘訊號;CSnA 是 ADC 晶片 MCP3002 的選擇訊號,是低準位致能,CSnB 是 DAC 晶片 MCP4802 的選擇訊號,兩者的 CSn 都使用 10K 電阻上拉。

使用時,就是將 J11 與 J2 相鄰的接腳接在一起就可以了。

詳細請參考下面的連接線路圖與照片。

Note:
因為一段時間未更新網頁,繼續寫這篇的時候剛好 wiringPi 釋出第二版。wiringPi v2 修正了很多問題,而且增加很多晶片以及賣場上面 GertBoard 和 PiFace 的函式庫支援,對於快速開發以及測試上非常方便,因為我們會另外使用 wiringPi 撰寫控制這兩種晶片的另一種方法,建議在接下去之前先下載以及安裝 wiringPi,這只是使用的函式庫不同而已。

檢查一下系統裡面是否已經裝了 wiringPi,如果有那就直接輸入下面指令將更新的資料下載下來
#### 切換目路到 wiringPi 底下
pi@raspberrypi ~ $ cd wiringPi
#### 直接使用 git 將檔案抓下來
pi@raspberrypi ~/wiringPi $ git pull origin
#### 重新編譯以及安裝 wiringPi
pi@raspberrypi ~ $ ./build

如果沒有安裝過 wiringPi 就到 "wiringPi Download and Install" 照著指令下載並安裝。


開啟 SPI 介面與安裝 Python SPI 套件 :

現在開始又到了安裝軟體的時間囉!

因為 MCP4802 與 MCP3002 都要使用到樹莓派的 SPI 介面,因此要對系統做一些修改,並且安裝 python 會用到的 SPI 函式庫:

首先先更新一下系統上的套件列表。如果很久沒更新了,先做下面這一行,不然就跳過
pi@raspberrypi ~ $ sudo apt-get update

上面如果有做的話,順便做一下系統更新,不做也可以 !
pi@raspberrypi ~ $ sudo apt-get upgrade -y

Note: 如果您是跟著前面第一部曲步驟做過來的話,那下面的步驟應該不需要再做,不然系統中必須已經安裝好了 git-core, python-dev, python-pip,不然是沒法往下繼續的 !

首先開啟 etc/modprobe.d/raspi-blacklist.conf 將 blacklist spi-bcm2708 前面加上 #

#blacklist spi-bcm2708

不清楚要怎麼改的,請參考 "[PiFace Digital 二部曲] 開啟樹莓派 SPI 介面" 裡的說明。

接著輸入下面指令,安裝 Python SPI 函式庫
pi@raspberrypi ~ $ sudo git clone git://github.com/doceme/py-spidev
Cloning into 'py-spidev'...
remote: Counting objects: 9, done.
remote: Compressing objects: 100% (8/8), done.
remote: Total 9 (delta 2), reused 7 (delta 1)
Receiving objects: 100% (9/9), 6.17 KiB, done.
Resolving deltas: 100% (2/2), done.
pi@raspberrypi ~ $ cd py-spidev/
pi@raspberrypi ~/py-spidev $ ls -l
總計 32
-rw-r--r-- 1 root root   196  5月 10 12:17 Makefile
-rw-r--r-- 1 root root   259  5月 10 12:17 README.md
-rw-r--r-- 1 root root   464  5月 10 12:17 setup.py
-rw-r--r-- 1 root root 19350  5月 10 12:17 spidev_module.c
pi@raspberrypi ~/py-spidev $ sudo python setup.py install
running install
running build
running build_ext
building 'spidev' extension
creating build
creating build/temp.linux-armv6l-2.7
gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fPIC -I/usr/src/linux/include -I/usr/include/python2.7 -c spidev_module.c -o build/temp.linux-armv6l-2.7/spidev_module.o
creating build/lib.linux-armv6l-2.7
gcc -pthread -shared -Wl,-O1 -Wl,-Bsymbolic-functions -Wl,-z,relro build/temp.linux-armv6l-2.7/spidev_module.o -o build/lib.linux-armv6l-2.7/spidev.so
running install_lib
copying build/lib.linux-armv6l-2.7/spidev.so -> /usr/local/lib/python2.7/dist-packages
running install_egg_info
Writing /usr/local/lib/python2.7/dist-packages/spidev-2.0.egg-info
pi@raspberrypi ~/py-spidev $

完成之後就可以開始接線做測試了!



數位訊號轉換成類比訊號 - 接線圖:

數位轉類比訊號是使用 MCP4802 晶片,位於 GB 板子上標註為 U10 的位置,小小的一顆;輸出接腳位在 J28 標示為 DA0 與 DA1 的位置。由於只傳送數位訊號到晶片並轉換為類比電壓輸出,下方的照片有接,但是實際上是可以不要接 MISO 的,自己試試看

數位轉類比接線圖,source: Gertboard User Manual (Rev 2.0)

MCP4802 內部參考電壓,在 Out Buffer Gain = 1 時標準值是 2.048 ( min: 2.008, max: 2.088) V,每一間隔大約是 8mV ( * 256 = 2.048 V )
數位轉類比接線照片
數位轉類比接線照片 - 近拍圖

數位訊號轉換成類比訊號 - 程式測試:

C 語言的測試程式為 dtoa,Python 是 dtoa.py,程式的說明請自行參考 Assembled Gertboard Manual Rev2.0, Page 34 - 36。

繼續上面的指令,輸入以下的指令測試 MCP4802
pi@raspberrypi ~/py-spidev $ cd ..~/GertBoard/GB_Python/
pi@raspberrypi ~/GertBoard/GB_Python $ sudo python dtoa.py
Which channel do you want to test? Type 0 or 1.
0
These are the connections for the digital to analogue test:
jumper connecting GP11 to SCLK
jumper connecting GP10 to MOSI
jumper connecting GP9 to MISO
jumper connecting GP7 to CSnB
Multimeter connections (set your meter to read V DC):
  connect black probe to GND
  connect red probe to DA0 on J29
When ready hit enter.

Your meter should read about 0.00V
When ready hit enter.

Your meter should read about 0.50V
When ready hit enter.

Your meter should read about 1.02V
When ready hit enter.

Your meter should read about 1.36V
When ready hit enter.

Your meter should read about 2.04V
When ready hit enter.

pi@raspberrypi ~/GertBoard/GB_Python $ 

可以繼續往下切換到另一目錄執行 C 程式
pi@raspberrypi ~/GertBoard/GB_Python $ cd ../gertboard_sw/
pi@raspberrypi ~/GertBoard/gertboard_sw $ sudo ./dtoa
... 中間省略 ...

兩個程式執行結果都一樣,但是 C 程式執行完了之後,輸出值會一直維持在 2.04 V 的輸出,使用上要注意一下 !



類比訊號轉換成數位訊號 - 接線圖:

類比轉數位的晶片是 MCP3002,位於 GB 板子上標示為 U6 的位置;輸出接腳位在 J28 標示為 AD0 與 AD1 的位置 。晶片會將輸入電壓 ( VDD/VREF = 2.7 - 5.5 V ) 除以 1024 ( 10-bit ) 經由 SPI 介面回傳到樹莓派,我們可以根據回傳的數值 ( Digital Output Code ) 得知所讀到的電壓 (VIN) 是多少 ?


VIN = [ VDD * ( Digitial Output Code ) ] / 1024

我們的測試線路所使用的外部輸入電壓是 3V3,因此可以讀到的最小解析度為每一個間隔為3.223 mV

類比轉數位接線圖,source: Gertboard User Manual (Rev 2.0)

類比轉數位接線照片
類比轉數位接線圖 - 近拍圖

類比訊號轉換成數位訊號 - 程式測試:

C 語言的測試程式為 atod,Python 是 atod.py,程式的說明請自行參考 Assembled Gertboard Manual Rev2.0, Page 34 - 36。

執行程式後,當您轉動可變電阻時,前方的數值由 0 - 1023 做變化,後面的 # 長度也會根據輸入的電壓做長度的增減。

繼續上一段的指令,繼續輸入 C 語言的程式測試
pi@raspberrypi ~/GertBoard/gertboard_sw $ sudo ./atod
Which channel do you want to test? Type 0 or 1.
1
These are the connections for the analogue to digital test:
jumper connecting GP11 to SCLK
jumper connecting GP10 to MOSI
jumper connecting GP9 to MISO
jumper connecting GP8 to CSnA
Potentiometer connections:
  (call 1 and 3 the ends of the resistor and 2 the wiper)
  connect 3 to 3V3
  connect 2 to AD1
  connect 1 to GND
When ready hit enter.

0483 ##############################
pi@raspberrypi ~/GertBoard/gertboard_sw $


接著切換目錄進行 python 程式碼的測試
pi@raspberrypi ~/GertBoard/GB_Python $ cd ../GB_Python
pi@raspberrypi ~/GertBoard/gertboard_sw $ sudo ./atod
... 中間省略 ...



數位轉類比和類比轉數位 - 程式測試 ( 使用 wiringPi v2 函式庫 ):

wiringPi v2 的目錄下 $wiringPi/wiringPi/ 新增了一些晶片可以使用的標頭檔,這些晶片只要一經過 [IC]setup() 函數設定和初始之後,就可以使用 pinRead()、pinWrite()、analogRead 和 analogWrite() 像是 GPIO 一樣變成樹莓派的擴充接腳,使用上非常方便,我們現在就使用這些標頭檔實際配合 wiringPi 來做。

先下載兩個寫好的程式,解壓縮之後有兩個目錄,目錄中分別是 adc_wpi2_mcp3002.c 和 dac_wpi2_mcp4802.c
pi@raspberrypi ~ $ cd codes/
pi@raspberrypi ~/codes $ wget -O adc_dac.tar.gz http://goo.gl/vpk6V

... 中間省略 ...

2013-06-07 17:20:32 (37.9 MB/s) - `adc_dac.tar.gz' saved [5724/5724]

pi@raspberrypi ~/codes $ tar -zxvf adc_dac.tar.gz
adc_wiringpi_mcp3002/
adc_wiringpi_mcp3002/adc_wpi2_mcp3002
adc_wiringpi_mcp3002/adc_wpi2_mcp3002.c
dac_wiringpi_mcp4802/
dac_wiringpi_mcp4802/dac_wpi2_mcp4802
dac_wiringpi_mcp4802/dac_wpi2_mcp4802.c
pi@raspberrypi ~/codes $ ls -l
總計 140
drwxr-xr-x 2 pi pi   4096  6月  7 16:42 adc_wiringpi_mcp3002
drwxr-xr-x 2 pi pi   4096  6月  7 16:45 dac_wiringpi_mcp4802
drwxr-xr-x 2 pi pi   4096  5月  5 18:17 p_motor
-rw-r--r-- 1 pi pi 122880  5月  5 18:19 p_motor.tar
-rw-r--r-- 1 pi pi   5724  6月  7 17:20 adc_dac.tar.gz
pi@raspberrypi ~/codes $

這兩個程式已經編譯完成,直接執行就可以得到與上面一樣的結果,所以我們不展示程式的執行過程,不過我們會說明如何使用 mcp3002 與 mcp4802 的標頭頭以及配合 wiringPi 如何做使用。

接線的方式與上面介紹的都一樣,照著接就可以了!

MCP3002 + wiringPi v2


Line 17 - 18:最重要的就是載入這兩個標頭檔:wiringPi.h,mcp3002.h

Line 22       :這是做為 analogRead ( "這個 GPIO 延伸位置的第一個接腳的位置" );輸入300 表示是 MCP3002 AD0,301 表示是 MCP3002 AD1

Line 24       :這是在 SPI 初始化的時候,說明晶片的 Chip Select ( CS ) 接腳是接在哪一個位置上的;0 表示是使用 spidev0.0,1 表示是使用 spidev0.1。可以將這個地方做調換,然後切換欲設控制 MCP3002 的 CSnA 為 CSnB 試試自己是否清楚了 !

Line 30 - 32:wiringPi 初始化,使用 BCM GPIO 號碼標號

Line 34 - 36:MCP3002 SPI 初始化;成功之後才可以調用 analogRead 讀取類比 ( 電壓 ) 輸入轉換為數位的訊號值

Line 40 - 54:這一段程式與 atod.c 的是一樣的,只不過將 Line 42 改成使用 alalogRead() 函數,Line 53 改成使用延遲 10 us 的時間函數。MCP3002 是 10-bit 的晶片,因此讀到的數值會是 0-1023,將其向右位移 4 個位元 ( 除以 16 ) 轉成 0-63 個 # 符號輸出做為電壓大小的刻度值。上面整段程式共會抓取 100,000 類比訊號值。


MCP4802 + wiringPi v2


Line 17 - 18:最重要的就是載入這兩個標頭檔:wiringPi.h,mcp4802.h

Line 21       :這是做為 analogWrite ( "這個 GPIO 延伸位置的第一個接腳的位置", "寫入的數值" );輸入400 表示是 MCP4802 DA0,401 表示是 MCP4802 DA1

Line 23       :這是在 SPI 初始化的時候,說明晶片的 Chip Select ( CS ) 接腳是接在哪一個位置上的;0 表示是使用 spidev0.0,1 表示是使用 spidev0.1。可以將這個地方做調換,然後切換欲設控制 MCP4802 的 CSnB 為 CSnA 試試自己是否清楚了 !

Line 29 - 31:wiringPi 初始化,使用 BCM GPIO 號碼標號

Line 33 - 35:MCP4802 SPI 初始化;成功之後才可以調用 analogWrite 寫入數值轉換成要輸出的類比電壓值。柱意到這邊要數入的數值範圍為 0 - 256 ( MCP4802 是 8-bit ),如果要由電壓轉換程相對應的數值,自己再做一些計算。

Line 43 - 48:這一段程式與 atod.c 的是一樣的,只不過將 Line 44 改成使用 alalogWrite() 函數。MCP4802 是 8-bit 的晶片,因此輸出的數值範圍是 0 - 256,電表上會輸出相對應的類比電壓。


以上就是使用 wiringPi v2 配合新建立的 mcp3002.h 與 mcp4802.h 函式庫所做的程式範例說明。


接下來第五部曲,就是使用前面幾個部份所做的相互混和測試的說明,請繼續往下一部曲移動。



賣場部落格 "認識 GertBoard " 系列文章:


<< Gertboard 相關資料文件下載>>

沒有留言:

張貼留言