ソフトウェアでGPIOを操作 (Bit banging)してSDAとSCL相当のシリアル波形を作って通信を実現するi2c-gpioドライバ(software i2c)を Raspberry Pi 4 Model Bの組み込みモジュール版となるRaspberry Pi Compute Module 4(以下、CM4) と 電流・電圧・電力計モジュール INA228 に使ってみました。
i2c-gpioドライバ(ソフトウエアI2C)のGPIO割り当て
CM4 のSoC(プロセッサ:Broadcom BCM2711)が持つI2C(SDA,SCL)に加えて、i2c-gpioドライバで空いているGPIOに割り当てることでもI2C通信が可能となります。GPIO名称の番号とピン番号(1~40ピン)があります。
今回はGPIO5(29 番ピン)、GPIO6( 30番ピン)に割り当てました。
# | 呼称 | SDAの割当て GPIO名称 (ピン番号) | SCLの割当て GPIO名称 (ピン番号) | 備考 |
1 | SoC内蔵の I2C (ハードウエア I2C) | GPIO2 (3 番ピン) | GPIO3 (5 番ピン) | GPIO2と3はプルアップ抵抗内蔵 |
2 | i2c-gpioドライバ (ソフトウエアI2C) | GPIO5 (29 番ピン) | GPIO6 ( 30番ピン) | 外付けのプルアップ抵抗が必要 |
Raspberry Pi OSでは、/boot/overlays/README に i2c-gpioの記載があります。SoC内蔵のI2C通信速度の default は100kbps。i2c-gpioドライバ の場合、i2c_gpio_delay_usをdefault の”2″ が同等の設定となります。

(1) SoCのI2Cを無効化して、同じGPIO2 とGPIO3 に i2c-gpio を割り当てる設定
SoCのI2Cが割り当てられているGPIO 2(SDA、 3番ピン )、 GPIO 3(SCL、5番ピン)を無効化して、i2c-gpioドライバに同じ GPIO 2 と3を割り当てる設定です。 GPIO 2 と3 は1.8kΩのプルアップ抵抗を持っているので既に回路を組んでいる場合はこの設定が容易と思います。
Raspberry Pi OSのLXTerminalを起動し、下記コマンドで設定ファイル config.txt をテキストエディタnanoで開きます。
sudo nano /boot/config.txt
SoCのI2Cを無効化
/boot/config.txt中にある「 dtparam=i2c_arm=on 」を #でコメントアウトします。
#dtparam=i2c_arm=on
i2c-gpioドライバに同じ GPIO 2 とGPIO 3 を割り当てて有効化
/boot/config.txtに下記を追加して保存します。CM4を再起動すると指定したピンが i2c-gpio 用になります。
dtoverlay=i2c-gpio,bus=1,i2c_gpio_sda=2,i2c_gpio_scl=3,i2c_gpio_delay_us=2
(2) SoCのI2C( GPIO2 とGPIO3 )はそのままに、新たにi2c-gpio( GPIO5 と GPIO6 )を割り当てる設定
i2c-gpioドライバ に新たに SDAとしてGPIO 5(29番ピン)を、 SCLとしてGPIO 6(30番ピン)を割り当てました。
/boot/config.txtに下記を追加して保存します。 CM4を再起動すると指定したピンが i2c-gpio 用になります。
dtoverlay=i2c-gpio,bus=3,i2c_gpio_sda=5,i2c_gpio_scl=6,i2c_gpio_delay_us=2
i2c-gpioドライバの動作確認、デジタルオシロでSDAとSCLの波形観察
SoCのI2C( GPIO 2 とGPIO 3 )はそのままに、新たにi2c-gpio( GPIO 5 と GPIO 6 )を割り当てる設定を行いました。
下記コマンドをLXTerminalで確認すると、
ls /dev/i2c*
SoCのI2Cも有効にしているので、2つのI2Cバスが見えます。 /dev/i2c-1がSoCのハードウェアI2C、もう一つがI2C-gpioのソフトウェアI2Cです。バス番号3を指定したので、i2c-3になっています。

INA228には測定対象としてスイッチングACアダプタ(12V)に負荷として白色LEDと抵抗を接続しています。

※ GPIO 2 と3はプルアップ抵抗(1.8kΩ)を内蔵

※プルアップ抵抗(手持ちの1.5kΩ)を外付け
SoCのI2C(バス番号1 )と i2c-gpio (バス番号3)で2個のINA228(0x40 、0x41)がi2cdetectで認識するかを確認します。

※GPIO 2 とGPIO 3 を割り当て

※GPIO 5 とGPIO 6 を割り当て
python3で作った簡易確認プログラムを連続実行して動作確認しました。測定値は スイッチングACアダプタの電圧、電流の変動範囲内で安定しており、今回の接続デバイスではI2C方式の違いによる差異は判りませんでした。CM4のCPU負荷には余裕があるのでI2C-gpioを常用利用しています。


デジタルオシロスコープでI2CのSCL(上段)とSDA(下段)の波形をモニタしました。周波数が低いこともあってかSoC、i2c-gpio共に比較的きれいな波形です。


プルアップ抵抗がない場合は、立ち上がりが遅い波形です。プルアップ抵抗は重要です。

