Raspberry Pi Compute Module 4(以下CM4)をセットしたIOボードにゴム足を付けて基板むき出しで使っていたのですがケーブルの収まりが悪いので「CM4 IO スマートケース」を購入してプチ改造した際のメモです。
CM4は、Raspberry Pi 4 Model B(以下4B)の産業・組み込み用途向けモデル。セットアップ方法は多少異なるものの、OSやGPIOは互換性があるので同じアプリケーションや各種センサモジュールが動作します。
CM4 IOスマートケース
CM4にはIOコネクタの実装がないので、CM4専用のRaspberry Pi Compute Module 4 IO Board(以下、IOボード)とセットで使っています。IOボードには、4BのUSB3.0コネクタの代わりにPCIeスロット、RTCとバックアップ用の電池ホルダ(CR2031)が追加されています。
購入したCM4はeMMC内蔵(のためスロットは付いていてもmicroSDカードは使えない)タイプなので、セットアップ方法は多少異なるものの4Bと同じOSをeMMCもしくは PCIeスロットに挿したNVMe M.2 SSD カードからブートできます。
金属加工された「CM4 IO スマートケース」は、IOボードの各種インターフェース用のケーブル差し込み口が精度良く加工されています。購入時から判っていたことですが、コンパクトで取り回しやすい反面、PCIeスロットやGPIOを使うには狭いです。ケースを開けることなくNVMe M.2 SSDの交換やケース外で各種センサ類をI2C接続できるようにプチ改造しました。
購入したCM4にはWi-Fi/Bluetoothが無いタイプなので外付けアンテナは取り外しています。ケース前面に緑色の押しボタンスイッチがついているので、早速設定しました。
電源SW(押しボタンスイッチ)でシャットダウンと起動を行う設定
4BやCM4にはデフォルトで、
・稼働中にGPIO3(ピン番号 5)とGNDが短絡したときにシャットダウン(低電力モードで動作)
・シャットダウン状態で GPIO3 と GND を短絡すると起動
を1つのスイッチで実現できます。
この設定は物理的に電源遮断するものではないので、電源を立ち上げ直す必要がある時は電源コネクタを挿し直す(電源スイッチをON/OFFする)必要があります。
nanoでconfig.txtファイルを編集して、シャットダウンの設定を追加します。
sudo nano /boot/config.txt
少し触ったりしても電源が落ちないように、2秒長押しでシャットダウンするようにdebounce=2000(デフォルトは100)を追加しました。
dtoverlay=gpio-shutdown,gpio_pin=3,debounce=2000
config.txtに上書き保存した後、設定反映するためにシャットダウンします。この後は、ボタンスイッチを押すことで起動とシャットダウンができます。
詳細は、インストールしたRaspberry Pi OSの/boot/overlays/READMEを「gpio-shutdown」で検索するとヒットします。
CPU冷却ファンの制御設定
付属する常時回転のケースファンを取り外して、GPIOにつないで温度制御ができるヒートシンクと一体型のPWM制御CPU冷却ファンを実装しました。
ファン温度は、Raspberry Pi OSのメニューの「設定」–>「Raspberry Pi の設定」–>「パフォーマンス」で行います。デフォルト設定は 80度です。
CPU冷却ファン吸気口とNVMe M.2 SSD取り付け用の穴加工
ケース内にCM4+IOボードを組み込むとCPU冷却ファンがふさがるので、電気ドリルとミニホールソーを使って、天板に37φの吸気口を開けました。
ファンに触れないように天板にFANガードをゴムプッシュを挟んで固定します。
ケース外からNVMe M.2 SSDを挿せるようにPCIeスロット真上に28φの開口を開けています。
T字型のPCIeアダプターカードはケースに干渉するので、I型のPCIeアダプターカードを使います。
購入したCM4はeMMC内蔵なので外部デバイス無しでもOS起動できますが、高速かつOSセットアップ済のNVMe M.2 SSD基板を差し替えて異なるOSを直ぐにbootできるPCIeスロットの使い勝手は手放せません。
i2c-gpio (ソフトウエアI2C)の割り当て、I2Cをケース外に10m延長
i2c-gpio (ソフトウエアI2C)の割り当て
GPIO3を電源起動に使うので、新たにi2c-gpio( GPIO 5 と GPIO 6 )を割り当てる設定を行います。
SoC内蔵のI2Cを無効化
/boot/config.txt中にある「 dtparam=i2c_arm=on 」を #でコメントアウトします。
#dtparam=i2c_arm=on
i2c-gpio( GPIO5 と GPIO6 )を割り当てる設定
boot/config.txtに下記を追加して保存します。 CM4を再起動すると指定したピン( GPIO 5 と GPIO 6 )が i2c-gpio (バス番号 3)になります。
dtoverlay=i2c-gpio,bus=3,i2c_gpio_sda=5,i2c_gpio_scl=6,i2c_gpio_delay_us=2
SoC内蔵の I2Cはプルアップ抵抗が実装されていますが、i2c-gpioの場合は外付けのプルアップ抵抗が必要です。マスタ側、スレーブ側ともにLTC4331モジュール基板上のランドパターンをショートしてプルアップ抵抗(10KΩ)を有効化します。
# | 呼称 | SDAの割当て GPIO名称 (ピン番号) | SCLの割当て GPIO名称 (ピン番号) | 備考 |
1 | SoC内蔵の I2C (ハードウエア I2C) | GPIO2 (3 番ピン) | GPIO3 (5 番ピン) | GPIO2と3はプルアップ抵抗内蔵 |
2 | i2c-gpioドライバ (ソフトウエアI2C) | GPIO5 (29 番ピン) | GPIO6 ( 30番ピン) | 外付けのプルアップ抵抗が必要 |
ケース外へのI2C+電源の延長
ケースにCM4+IOボードを内蔵するとGPIOへの各種センサモジュールの接続が面倒です。しかし、I2Cは基板やケース内の近距離用のインターフェースなので遠くには引き出せません。
ケース外でも安定して使うために、LTC4331モジュール(マスタ、スレーブ用の 2個セット)を使ってI2Cを延長しました。マスタ側をGPIOに接続し、外部への配線引き回しにはLANケーブルを使います(LAN用のハブは使えません)。
LTC4331モジュールのマスタ側とスレーブ側をつなぐLANケーブルは、 通信用には4番線と5番線しか使いませんが、スレーブ側のLTC4331モジュールと接続する I2Cモジュールに給電するために1番線に3.3V、2番線にGNDを追加で割り当てました。
LANケーブルは、ケース背面の取り外した無線LAN用アンテナ取付穴にグロメット(ゴム)で養生して引き込んでいます。
今回使ったLANケーブルはストレートケーブル(B配線)だったので、利用する 1(3.3V、白/橙)、2(GND、橙)、4(通信、青)、5(通信、白/青)をLTC4331モジュールのLANコネクタのランドパターンに直接はんだ付けしました(*LANケーブルのワイヤ色は異なる場合もあります)。
i2c-gpioに割り当てたGPIO5 、GPIO6、3.3VとGNGピンからくるジャンパーワイヤをLTC4331モジュール基板裏面の該当端子にはんだ付けします。
GPIO and the 40-pin Header | raspberrypi.orgより引用して追記
現在10mのLANケーブルを使っています。LANケーブルの先には、スレーブ設定したLTC4331モジュールを介して、I2Cデバイスに4線(SDL、SCL、3.3V、GND)を供給します。
スレーブ側にBME280センサモジュールをつないで動作確認(2022/07/30追記)
電源が入ると両方のLTC4331モジュール基板上のLINK のランプが点灯すれば通信はOKです。スレーブ側から引き出したI2C(SDA、SCL)と3.3V、GNDに接続したBME280センサモジュールを動作確認します。
LXTerminalで下記コマンドを投入すると、i2c-3(バス番号3)にBME280のアドレス(0x76)が見えます。
ls /dev/i2c*
i2cdetect -l
i2cdetect -y 3
Python3:BME280から測定データを取得(2022/07/30追記)
Raspberry Pi OS with desktop(bullseye)にプリインストール されているThonny Python IDEを使ってPython3コードでBME280の気圧、温度、湿度の測定データを取得できました。