1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Raspberry Pi PicoでPicoMite(MMBasic)を使う〜SPIデバイスのADT7310で温度測定

Posted at

はじめに

シリアルバス規格の一つであるSPI(Serial Peripheral Interface)を利用したデバイスの接続をPicoMite(MMBasic)で試してみた。

PicoMiteのSPI

PicoMite(MMBasic)でSPIを利用する手順は次の通り。

  1. SPIデバイスとPicoのピンの対応付け
  2. SPIチャンネルを開く
  3. SPIデバイスの設定
  4. SPIデバイスからのデータ受信
  5. SPIチャンネルを閉じる

ピン割り当て

SETPINコマンドでSPIデバイスのピンとRaspberry Pi Picoのピンを対応付ける。構文は次の通り。

SETPIN RX, TX, CLK, SPI
  • SPIはチャンネル1でチャンネル2に割り当てる場合はSPI2にする
  • TXはRaspberry Pi PicoからSPIデバイスへのデータ送信
  • RXはRaspberry Pi PicoがSPIデバイスからデータ受信
  • RX、TX、CLKに割り当てできるPicoのピンは下表の通り
パラメータ チャンネル1のピン チャンネル2のピン
RX GP0、GP4、GP16、GP20 GP8、GP12、GP28
TX GP3、GP7、GP19 GP11、GP15、GP27
CLK GP2、GP6、GP18 GP10、GP14、GP26

SPIチェンネルを開く

SPIを利用するにはSPI OPENコマンドでSPIチャンネルを開く必要がある。
構文は次の通り。

SPI OPEN speed, mode, bit

それぞれの引数は次の通り

  • speed:Hz単位のクロック周波数
  • mode:下表に示す送信モード0〜3までの数値で指定する
  • bit:送受信するデータ幅の指定、4〜16ビットを指定する
モード 説明 CPOL CPHA
0 クロックはアクティブハイで、データは立ち上がりエッジでキャプチャ、立ち下がりエッジで出力 0 0
1 クロックはアクティブハイで、データは立ち下がりエッジでキャプチャ、立ち上がりエッジで出力 0 1
2 クロックはアクティブローで、データは立ち下がりエッジでキャプチャ、立ち上がりエッジで出力 1 0
3 クロックはアクティブローで、データは立ち上がりエッジでキャプチャ、立ち下がりエッジで出力 1 1

データの送受信

SPIデバイスとのデータの送受信にはSPI()関数を使います。構文は次の通り。

receive_data = SPI(data_to_send)

data_to_sendは送信データで同時に受信も行なう。受信したデータはreceive_dataに格納される。
受信のみを実行する場合は送信データは任意の値、たとえば0でよい。

バルク送受信

データの一括送受信が可能です。
データの一括送信は送信するデータの列挙、文字列、配列を引数に指定できます。構文を以下に示します。

SPI WRITE nbr, data1, data2, data3,..
SPI WRITE nbr, string$
SPI WRITE nbr, array()
  • nbrは送信データ数
  • 文字列や、配列はnbr以上の文字数、要素数が必要です

一括受信では受信したデータを配列に格納します。構文を以下に示します。

SPI READ nbr, array()

使用部品

SPIデバイスとして秋月電子通商で購入したADT7310使用 高精度・高分解能 SPI・16Bit 温度センサーモジュールを使用し、取得した温度の表示にI2C接続のOLED、YUWENW OLEDディスプレイ 0.96インチ 2個入り OLEDモジュール I2C 128X64 4ピン ホワイト Arduinoに対応に使用した。

ADT7310

ADT7310はADT7410と同様に13/16 ビットADC を内蔵しており、13ビット設定の場合で0.0625℃の、16ビット設定で0.0078℃の分解能がある。
バイト単位で受信した2バイト分のデータをシフト演算などで13ビットあるいは16ビットの値に変換して温度を算出する必要がある。

13ビットデータからの温度計算

13ビットデータの場合の計算式を以下に示す。

  • $正の温度=読み取ったデータ/16$
  • $負の温度=(読み取ったデータ - 8192)/16$

温度の正負判定はADT7410からのデータは2の補数なのでデータの最上位ビット(MSB)が1か否かで判断できる。13ビット出力の場合、4096以上の値が負数である。

16ビットデータからの温度計算

16ビットデータの場合の計算式を以下に示す。

  • $正の温度=読み取ったデータ/128$
  • $負の温度=(読み取ったデータ - 65536)/128$

16ビット出力の場合、読み取ったデータが32768以上の値が負数である。

配線

ADT7310とRaspberry Pi Picoの接続は下記のとおり。

ADT7310のピン Picoのピン(物理ピン)
VDD 3V3(36)
SCL GP18(24)
SDO GP20(26)
SDI GP19(25)
CS GP21(27)
GND GND

OLEDとRaspberry Pi Picoの接続は下記のとおり。

OLEDのピン Picoのピン(物理ピン)
GND GND(3)
VCC 3V3(36)
SCL GP15(20)
SDA GP14(19)

OLED-ADT7310_ブレッドボード.png

プログラム

ADT7310の出力をデフォルトの13ビット受信するプログラムを以下に示します。

ADT7310.bas
Dim data%(2), raw%, temp!, stemp$               ' Define variables
SetPin GP20, GP19, GP18, SPI                    ' Set the pins to be used as SPI
SetPin GP21, DOUT                               ' Set the pin to SPI chipselect
SPI OPEN 100000, 3, 8                           ' Open SPI,100kHz, mode 3, 8bit
Pin(GP21) = 0                                   ' Select ADT7310
SPI WRITE 4, &HFF, &HFF, &HFF, &HFF             ' Rest SPI
Pin(GP21) = 1                                   ' Deselection ADT7310
Pause 300                                       ' Wait 300msec
Pin(GP21) = 0                                   ' Select ADT7310
Dummy = SPI(&H54)                               ' Set continuous read mode
CLS                                             ' Clear OLED screen
Do
  SPI READ 2, data%()                           ' Read temperature data, store to array 
  raw% = data%(0) << 8 Or data%(1)              ' convert read data
  raw% = raw% >> 3
  If raw% >= 4096 Then raw% = raw% - 8192       ' Conversion when negative
  temp! = raw% / 16                             ' Calculate temperature
  stemp$ = Str$(temp!, 2, 1) + Chr$(&H60) + "C" ' Create temperature string
  Text 0, 0, stemp$,,3                          ' Draw temperature on OLED
  Pause 1000                                    ' Wait 1 sec
Loop

Pin(GP21) = 1                                   ' Deselection

SPI CLOSE                                       ' Close SPI

End

このプログラムは次の処理を実行している。

ADT7310とRaspberry Pi Picoの接続に合わせてピンをSPIチャンネル1に設定

SetPin GP20, GP19, GP18, SPI
SetPin GP21, DOUT

SPIチャンネル1を100kHz、モード3、8ビットデータ送受信で開く

SPI OPEN 100000, 3, 8

SPIインターフェイスのリセット。
SPIデバイスの入力に32シリアルクロック周期以上の1を加えるとインターフェースがリセットされる。リセットしないとうまく動作してくれなかった。
CSをローレベル(PIN(GP21) = 0)にしてSPIデバイスにデータを送信する。送信後CSをハイレベル(PIN(GP21) = 1)にしている。

Pin(GP21) = 0
SPI WRITE 4, &HFF, &HFF, &HFF, &HFF
Pin(GP21) = 1

連続読み出しモードに設定する。
ADT7310のデータシートではSPIデバイスへのコマンド01010100(&H54)を送信するとADT7310は温度データを連続して読み出せるようになります。

Pin(GP21) = 0
Dummy = SPI(&H54)

送信するコマンド01010100(&H54)の各ビットは次の意味がある。

  • C7、C1、C0は常に0
  • C6のR/Wは読み書きの指定で、1にすると読み出しに、0にすると書き込みになる
  • C5〜C3はレジスタの指定で010(0x02)は温度データのレジスタを示す。ちなみに0x01はコンフィギュレーションレジスタ
  • C2は連続読み出しの指定で、1にすると連続読み出しになる
C7 C6 C5 C4 C3 C2 C1 C0
0 R/W レジスタアドレス 連続読み出し 0 0
0 1 0 1 0 1 0 0

戻り値は利用しない

ADT7310からのデータを2バイト分読み取り、配列data%に保存する。
先頭8ビット分がdata%(0)に、後続の8ビットがdata%(1)に格納される。

SPI READ 2, data%()

受信した温度データを13ビットに変換
温度データは8ビットずつ受信し、2つの配列要素に格納されているため13ビットデータへの変換を行なう。先頭8ビット分を左へ8ビットシフトした値(data%(0) << 8)と後半の8ビット(data%(1))との論理和を求め16ビットの値にすし、変数raw%に格納する。
次に不要な下位3ビット分を取り除くために右へ3ビットシフトする。

raw% = data%(0) << 8 Or data%(1)
raw% = raw% >> 3

温度データから温度の算出
ADT7310から取得した温度データは2の補数なので符号ビットのみが1の4096(1 0000 0000 0000)以上は負数となり、値の変換が必要になる。負数のときは2の補数の温度データから8192(=$2^{13}$)を引くと負数が得られる。
13ビットの分解能が0.0625℃なので温度データを16(=1/0.0625)で割れば温度が得られる。

If raw% >= 4096 Then raw% = raw% - 8192
temp! = raw% / 16    

表示用文字列の作成
算出された温度の値を整数部2桁、小数部1桁の文字列に変換し、OLEDへ出力する。

stemp$ = Str$(temp!, 2, 1) + Chr$(&H60) + "C"
Text 0, 0, stemp$,,3

参考サイトなど

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?