raspberry pi 2 model B+とraspbian busterでI2Cを使用する(raspbianでI2Cが使えない場合の対処)
raspi-configだけでI2Cが有効にならない
最近、ラズパイのGPIOとかを触り始めました。
手元にラズパイマガジン2015年秋号があり、当時合わせて購入したブレッドボードだの、LEDだのセンサーだのの部品セットがあるのですが、Lチカすらやらずに放置していたのですが、最近機械学習とかで試すネタが涸渇して(あるにはあるのですが..)、ふと思い立って基本のLチカから試し始めました。
うちの会社は本来なら今週開催されているはずだった東京オリンピックに合わせて今週が夏休み。まとまった時間が取れるので、各センサー等にピンヘッダのハンダ付けとかやって準備。
I2C接続のキャラクター液晶ACM1602NIを、ラズパイマガジン見ながらセットアップ。
こんな感じで繋いで、ラズパイマガジン出版元の日経BP社のサイトからDLしたサンプルプログラムを起動するも無情な「I/O Error」の表示。
配線を何度も確認しましたが、問題は無さそう。
ソフト問題っぽいなとあたりをつけてググると下記のサイトを発見。
カーネルバージョンが上がるとダメで、4.4なら大丈夫なのでダウングレードしろと。
今使っているOSはこんな感じでraspbianはbuster、カーネルは5.4になっています。
pi@raspberrypi:~ $ cat /etc/os-release PRETTY_NAME="Raspbian GNU/Linux 10 (buster)" NAME="Raspbian GNU/Linux" VERSION_ID="10" VERSION="10 (buster)" VERSION_CODENAME=buster ID=raspbian ID_LIKE=debian HOME_URL="http://www.raspbian.org/" SUPPORT_URL="http://www.raspbian.org/RaspbianForums" BUG_REPORT_URL="http://www.raspbian.org/RaspbianBugs" pi@raspberrypi:~ $ uname -a Linux raspberrypi 5.4.51-v7+ #1332 SMP Tue Aug 4 18:34:21 BST 2020 armv7l GNU/Linux
カーネルバージョン最新のままでも、古いbcm2708ドライバーのロードモジュールを入手して組み込めば良いという情報も書いてあるのですが、自分の環境では上手く動作せず、その間、/etc/modulesとか/boot/config.txtとか色々触っても解決せず。
結局は上記のブログの通り、下記コマンド実行して一旦カーネルのバージョンダウンを実施しました。
$ rpi-update 00a7eac6efc6ba29d94a7460f68215a1dbbdef0b
その状態でuname -aを実行すると。
pi@raspberrypi:~ $ uname -a Linux raspberrypi 4.4.47-v7+ #961 SMP Sun Feb 5 20:17:00 GMT 2017 armv7l GNU/Linux
ただしこれだけでは動かず、以下の対処が必要です。
/etc/modules
i2c-dev
これはrpi-configでI2Cをenableにすると追記されるはずですが、要確認。
/boot/config.txt
以下の2行が必要。baudtate=50000はACM1602NIに合わせた設定なので、使うI2Cデバイスの仕様に合わせて調整必要。
dtparam=i2c_arm=on dtparam=i2c_baudrate=50000
あと、これは必要かどうか判らないのですが、/etc/modprobe.d/にblacklist-i2c-bcm2835.confというファイルを作り、
blacklist i2c-bcm2835
を入れておきます。
逆に同じディレクトリ内のconfファイルのいずれかに、
blacklist i2c-bcm2708
が書かれていない事を確認します。
ここまでの対処でサンプルプログラムにエラーが出ずACM1602NIに文字を表示することに成功しました。
カーネルを最新版のままでraspberry pi 2 MODEL B+でI2Cを動かす
一応、カーネルバージョンを4.4まで戻す事でI2Cが使える様になったのですが、どうもすっきりしません。
宅内での実験にしか使わないので、セキュリティとかあまり気にはしていないのですが、やはり最新のカーネルで動かしたい。
ググったり、色々実験したりした結果から考察して以下の対処を行いました。
- カーネルバージョンを最新に戻す
$ sudo rpi-udate
完了後のバージョンを確認。
pi@raspberrypi:~ $ cat /etc/os-release PRETTY_NAME="Raspbian GNU/Linux 10 (buster)" NAME="Raspbian GNU/Linux" VERSION_ID="10" VERSION="10 (buster)" VERSION_CODENAME=buster ID=raspbian ID_LIKE=debian HOME_URL="http://www.raspbian.org/" SUPPORT_URL="http://www.raspbian.org/RaspbianForums" BUG_REPORT_URL="http://www.raspbian.org/RaspbianBugs" pi@raspberrypi:~ $ uname -a Linux raspberrypi 5.4.51-v7+ #1332 SMP Tue Aug 4 18:34:21 BST 2020 armv7l GNU/Linux
- /etc/modulesにi2c-devとi2c-bcm2708を設定
以下の様になっていればOK。pi@raspberrypi:~ $ cat /etc/modules # /etc/modules: kernel modules to load at boot time. # # This file contains the names of kernel modules that should be loaded # at boot time, one per line. Lines beginning with "#" are ignored. i2c-bcm2708 i2c-dev
- /boot/config.txtに以下を設定
dtparam=i2c_arm=on dtoverlay=i2c-bcm2708 dtparam=i2c_baudrate=50000
- /etc/modprobe.d/*.confでi2c-bcm2835をblacklist指定
ついでにi2c-bcm2708がblacklist指定されていないことを確認。(書かれていたらコメントアウト)blacklist i2c-bcm2835
reboot後、以下を実行して、i2c_devとi2c_bcm2708が正常にロードされている事を確認。
lsmodでi2c_bcm2708が表示されていても、dmesgにエラー表示が出ていると上手く行っていない可能性大です。
pi@raspberrypi:~ $ lsmod | grep i2c i2c_dev 16384 0 i2c_bcm2708 16384 0 pi@raspberrypi:~ $ dmesg | grep i2c [ 6.707652] bcm2708_i2c 3f804000.i2c: BSC1 Controller at 0x3f804000 (irq 77) (baudrate 50000) [ 6.712821] i2c /dev entries driver
これで2020/8時点のraspbian buster+最新カーネル(5.4)の組み合わせでI2Cが使える様になりました。
補足
raspbian buster+カーネル5.4で参考サイトに書かれている下記を試しましたが、上手く行きませんでした。
Just to repeat the entire process . . . . Download the old module here. Copy this file into /boot/overlays. In /boot/config.txt add the line dtoverlay=i2c1-bcm2708 at the end.
どうやらraspbianのあるカーネルのバージョン以降、i2cドライバーのデフォルトがi2c-bcm2708からi2c-bcm2835というものに変わった事が原因らしいと関連サイトを読む限り判断できるのですが、raspbianが後方互換性を一切持たずにアップグレードされるのも変だなと思い、自分の環境を調べてみると/boot/overlaysの下にi2c-bcm2708.dtboというファイルを見つけました。これは上記のサイトに書いてあるi2c1-bcm2708.dtboとは別のファイルです。おそらくはrpi-updateでDLされたbcm2708用のローダブルモジュールで、出処怪しいi2c1-bcm2708.dtboではなくi2c-bcm2708.dtboをoverlayすれば良いのでは?と思いつきました。
これが/etc/modulesや/boot/config.txtにi2c-bcm2708を追加した理由です。
pi@raspberrypi:~ $ ls -l /boot/overlays | grep i2c -rwxr-xr-x 1 root root 449 8月 4 18:37 bmp085_i2c-sensor.dtbo -rwxr-xr-x 1 root root 270 8月 5 09:08 i2c-bcm2708.dtbo -rwxr-xr-x 1 root root 1055 8月 5 09:08 i2c-gpio.dtbo -rwxr-xr-x 1 root root 2185 8月 5 09:08 i2c-mux.dtbo -rwxr-xr-x 1 root root 648 8月 5 09:08 i2c-pwm-pca9685a.dtbo -rwxr-xr-x 1 root root 5680 8月 5 09:08 i2c-rtc-gpio.dtbo -rwxr-xr-x 1 root root 5180 8月 5 09:08 i2c-rtc.dtbo -rwxr-xr-x 1 root root 5336 8月 5 09:08 i2c-sensor.dtbo -rwxr-xr-x 1 root root 1182 8月 4 18:37 i2c0-bcm2708.dtbo -rwxr-xr-x 1 root root 1396 8月 5 09:08 i2c0.dtbo -rwxr-xr-x 1 root root 854 8月 4 18:37 i2c1-bcm2708.dtbo -rwxr-xr-x 1 root root 1004 8月 5 09:08 i2c1.dtbo -rwxr-xr-x 1 root root 907 8月 5 09:08 i2c3.dtbo -rwxr-xr-x 1 root root 907 8月 5 09:08 i2c4.dtbo -rwxr-xr-x 1 root root 911 8月 5 09:08 i2c5.dtbo -rwxr-xr-x 1 root root 909 8月 5 09:08 i2c6.dtbo -rwxr-xr-x 1 root root 1353 8月 5 09:08 sc16is750-i2c.dtbo -rwxr-xr-x 1 root root 1353 8月 5 09:08 sc16is752-i2c.dtbo