※なにか気になる点がありましたらコメント欄にご記入ください。また、工作や回路を製作する場合には、細かい作業などに対して、細心の注意を払われるようお願いいたします。
【目次】
1.はじめに
ラズベリー・パイ Pico(以下Picoと表記)のA/D変換のポートを増やしたかったので、Picoを用いてMCP3208という、マイクロチップ社製のA/D変換機能を持ったICを動かすことを考えてみました。
アマチュアの電子工作erが書いたブログです。いたらない点があるかと思いますが、大目に見て頂けると幸いです。
(;´∀`)
2.MCP3208について
おおよそこちらの方の記事を参考にさせて頂きました。MCP3208の基本的な使い方など参照して頂けたらと思います。
リンク先:
www.denshi.club
実体配線図を図1に示します。
Picoとは下の対応表の通りに接続します。
対応表:
Pico側 | MCP3208側 | ||
---|---|---|---|
4番 | SCK | 13番 | CLK |
5番 | TX | 11番 | Din |
6番 | RX | 12番 | Dout |
7番 | CSn | 10番 | /CS/SHDN |
MCP3208とはSPI機能を用いてPicoとやり取りをします。
- 具体的なコードは3章で見ていきますが、データを読み出すときは、1chずつcs(0)(チップセレクト)を入れ有効にし、データを読みだしたらcs(1)にして選択を解除します。
(チャンネルを変えない場合でも、その都度cs(0)をしないとデータの読み出しはできないみたいです)
- またMCP3208は、1~8番ピンがA/D変換の入力chとなっています(他のモードもあるようです)。
- 今回は1番と2番ピンからVR0、1の電圧を読み取ることとします。(ch0,1)
※今さらですが、このMCP3208は12ビットの分解能を持ちます。ここでは、0~3.3Vを0~4095の値に変換します。
- また、値を読み取るときは、次に示すような3つのデータを送信し、その度ごとに1バイトずつデータをPicoが受け取ります。(図2~図4)
図2の中のD0~D2はチャンネルを指定するのに使用します。具体的には図3のように値をセットします。
Pico側で読み取った値は図4のようになります。a0~a11 とありますが、A/D変換の結果である12bitのデータを意味しています。
具体的なコードを見ていく中で、さらに解説していきます。
3.ソースコード
実装したソースコードをリスト1に示します。
リスト1 実装したソースコード
from machine import SPI, Pin import utime #ここから処理がスタートします if __name__ == '__main__': spi_sck = Pin(2) spi_tx = Pin(3) spi_rx = Pin(4) # 周波数 400kHz で SPI ペリフェラル 0 を作成 spi = SPI(0, baudrate=400000, sck=spi_sck\ , mosi=spi_tx, miso=spi_rx) # ピン 5 でチップセレクトを作成。 cs = Pin(5, mode=Pin.OUT, value=1) # Process arguments print('Press Ctrl-C to quit.') rxdata = bytearray(6) try: while True: # ペリフェラルを選択。 cs(0) rxdata[0] = spi.read(1, 0x06)[0] rxdata[1] = spi.read(1, 0x00)[0] rxdata[2] = spi.read(1, 0x00)[0] # ペリフェラルを選択解除。 cs(1) # ペリフェラルを選択。 cs(0) rxdata[3] = spi.read(1, 0x06)[0] rxdata[4] = spi.read(1, 0x40)[0] rxdata[5] = spi.read(1, 0x00)[0] # ペリフェラルを選択解除。 cs(1) data0 = ((rxdata[1] & 0x0f) << 8) + rxdata[2] data1 = ((rxdata[4] & 0x0f) << 8) + rxdata[5] print(rxdata, data0, data1) utime.sleep(1) # ctl-C が押されたときの処理です except KeyboardInterrupt: # ペリフェラルを選択解除。 cs(1) spi.deinit()
解説:
① 7,8,9行でピンを指定し、11行でSPIの処理を扱うインスタンスを生成します。
② 14行でGP5(7番ピン)をcsに指定します。
③ 21行からメインループに入ります。
④ 24~26行でch0から電圧値を読み取ります。
関数 spi.read(a, data) は1バイトのdataを送信し、a バイトデータを読み出します。
2章で見たとおり、dataにはchを指定する値をセットします。
データを読み出す関数には [0] をお尻に付けて、リスト(?)の中身を取り出します。
要素が1つだけの場合でも”[0]”を付けないと、数値としてはみなされず、型が合っていないとしてエラーになります。
※ここの処理は2章で示したサイト内のArduino用のスケッチが大きな助けとなりました。
結構はまってしまって、ChatGPTの力を借りたりもしました。
(Pyhtonの基本ができてないので(汗))
⑤ 32~34行ではch1の値を読み取っています。
⑥ 38、39行では読み取った値を12ビットのデータに成形し、意味のあるものにしています。
⑦ 40行で結果を表示しています。
⑧ 48行以降。選択を解除し、SPIバスをオフにします。(終了処理です)
おおよその処理は以上です。
4.動画
動作のようすを示します。
ボリュームを動かすと、PC画面の数字が変化しています。
A/D変換により値を読み取っているわけですね。(^_^)
以上となります。お付き合い下さり、ありがとうございました。