個人情報保護方針 お支払いについて お問い合わせ

Rock Compute Module CM3でI2Cを使用(RTCとPWMファンコントローラ)



Raspberry Piといえば、HAT(GPIO)です。HATにはSPI,I2C,I2S,PWM,GPIO等の拡張機能があり、RockCM3+CM4I/Oボードのdtbを適用している場合、/dev/i2c-0と/dev/i2c-6が有効になっています。オーバーレイは使用していません。I2Cバスに接続されているデバイスの動作確認を行っていきます。

mraaとi2cdetect
RTCの動作確認
FAN制御用EMC2301
ユーザーモードでのI2Cアクセス
ユーザーモードでのGPIOアクセス
ユーザーモードでのPWMアクセス
I2C/PWM/GPIOによるファンコントローラ


mraa-i2cとi2cdetect

I2Cにつながっているものを調べるコマンドとしてi2cdetectがあります。i2cdetect -lでI2Cバスのリストが、sudo i2cdetect -y [バスNo] で接続されているデバイスが表示されます。I2C0には1C/20/2F/51のデバイスが、I2C6は30/3a/50のデバイスが見えているようです。HDMIケーブルを抜くと3aと50は消えるのでこの2つはモニタ内にあるものだと推測できます。
I2C0のアドレス20はRK817(PMIC+Codec)のようです。
$ i2cdetect -l

i2c-6 unknown DesignWare HDMI N/A
i2c-0 unknown rk3x-i2c        N/A

$ sudo i2cdetect -y 0

      0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
 00:          -- -- -- -- -- -- -- -- -- 0c -- -- --
 10: -- -- -- -- -- -- -- -- -- -- -- -- UU -- -- --
 20: UU -- -- -- -- -- -- -- -- -- -- -- -- -- -- 2f
 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
 50: -- 51 -- -- -- -- -- -- -- -- -- -- -- -- -- --
 60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
 70: -- -- -- -- -- -- -- --

次にmraaを試します。基本的に同じことができます。Rock CM3 I/Oボードを使用している場合にはRadxaのwikiに従ってダウンロードします。

$ sudo apt-get install -y libgtest-dev pkg-config cmake-data
$ git clone -b master https://github.com/radxa/mraa.git
$ cd mraa

Raspbery Pi CM4 I/Oボードを使用している場合には以下からダウンロードします。(Rock CM3 I/Oボードも対応しています)

CM4 I/O Board対応版mraa: mraa_cm3_rpi_cm4.tar.gz

ここで、CMakeList.txtを編集して

option (BUILDSWIGNODE "Build swig node modules." ON)
option (USEPYTHON3TESTS "Force tests to run with python3" OFF)

の2行を

option (BUILDSWIGNODE "Build swig node modules." OFF)
option (USEPYTHON3TESTS "Force tests to run with python3" ON)

に書き換えます。そのあとビルドします。

$ mkdir build
$ cd build/
$ cmake ..
$ make
$ sudo make install
$ sudo ldconfig
$ mraa-i2c version

Version v2.1.0-26-gd59936f on Radxa ROCK CM3 IO

$ mraa-i2c list

Bus 0: id-00 type-linux default
Bus 1: id-06 type-linux

$ mraa-i2c detect 0

 00: -- -- -- -- -- -- -- -- -- -- -- -- 0c -- -- --
 10: -- -- -- -- -- -- -- -- -- -- -- -- 1c -- -- --
 20: 20 -- -- -- -- -- -- -- -- -- -- -- -- -- -- 2f
 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
 50: -- 51 -- -- -- -- -- -- -- -- -- -- -- -- -- --
 60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
 70: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --

$ sudo i2cdetect -y 1

 00: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
 30: 30 -- -- -- -- -- -- -- -- -- 3a -- -- -- -- --
 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
 50: 50 -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
 60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
 70: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --

Addr:20 RockChip RK817-5 PMIC+Codec (CM3)
Addr:2F EMC2301 FanController (CM4 I/O Board)
Addr:51 PCF8563 - Real-time clock/calendar (CM4 I/O Board)



I2Cのアドレスは7bitしかないので、同じアドレスをもつデバイスは多数存在しますが、ある程度特定できます。

I2C Address List
https://i2cdevices.org/addresses

Bus0
   Addr 1C
     47L04/47C04/47L16/47C16 - 4K/16K I2C Serial EERAM - Control register
     FXOS8700 - 6-axis sensor with integrated linear accelerometer and magnetometer
     MCP9808 - ±0.5°C Maximum Accuracy Digital Temperature Sensor
     MMA845x - 3-axis, 14-bit/8-bit digital accelerometer

   Addr 20
     Chirp! - Water sensor
     FXAS21002 - 3-axis gyroscope
     HW-061 - I2C Serial Interface LCD1602 Adapter
     MA12070P - Merus Multi level Class D Interated amplifier
     MCP23008 - 8-Bit I/O Expander with Serial Interface I2C GPIO expander
     MCP23017 - I2C GPIO expander
     PCA6408A - Low-voltage, 8-bit I2C-bus and SMBus I/O expander
     PCF8575 - Remote16-BIT I2C AND SMBus I/O Expander withInterrupt Output
     TCA9554 - 4 Low Voltage 8-Bit I 2C and SMBus Low-Power I/O Expander With Interrupt
     XD8574A - I2C 8-Bit I/O Expander

   Addr 2f
     AD5243 - Dual, 256-Position, I2 C-Compatible Digital Potentiometer
     AD5248 - Dual, 256-Position, I2 C-Compatible Digital Potentiometer
     AD5251 - Dual 64-Position I2 C Nonvolatile Memory Digital Potentiometers
     AD5252 - Dual 256-Position I2C Nonvolatile Memory Digital Potentiometers
     DS1881 - Dual NV Audio Taper Digital Potentiometer
     MCP4532 - 7/8-Bit Single/Dual I2C Digital POT with Volatile Memory
    *EMC2301 FanController

   Addr 51
     AT24C64 - 2-Wire Serial EEPROM 64K (8192 x 8)
     CAT24C512 - EEPROM - 512Kbit - 64KB
     LM25066 - PMBus power management IC
     MB85RC - Ferroelectric RAM
     PCA9685 - 16-channel PWM driver default address
    *PCF8563 - Real-time clock/calendar
     VCNL4200 - High Sensitivity Long Distance Proximity and Ambient Light Sensor With I2C Interface

Bus6
   Addr 30
     SAA2502 - MPEG audio source decoder

   Addr 3a
     MLX90632 - FIR temperature sensor
     PCF8574AP - I2C-bus to parallel port expander
     PCF8577C - 32/64-segment LCD display driver
     SAA1064 - 4-digit LED driver

   Addr 50
     47L04/47C04/47L16/47C16 - 4K/16K I2C Serial EERAM - SRAM Memory with EEPROM backup
     AT24C64 - 2-Wire Serial EEPROM 64K (8192 x 8)
     CAT24C512 - EEPROM - 512Kbit - 64KB
     FS1015 - Air Velocity Sensor Module -- 0-5, 0-15m/sec
     LM25066 - PMBus power management IC
     MB85RC - Ferroelectric RAM
     PCA9685 - 16-channel PWM driver default address

参考資料: https://linuxhint.com/i2c-linux-utilities/
参考資料: https://wiki.radxa.com/Mraa



RTCの動作確認

RaspberryPiでは標準状態ではRTCが設定されていないようです。下記の内容を/boot/config.txtに追記します。

$ sudo vi /boot/config.txt

[pi4]
# Enable DRM VC4 V3D driver on top of the dispmanx display stack
dtoverlay=vc4-fkms-v3d
max_framebuffers=2

[cm4]
dtparam=i2c_vc=on
dtoverlay=i2c-rtc,pcf85063a,i2c_csi_dsi

Rock CM3でdtbをCM4 I/Oボード用に差し替えた場合には必要なI2Cは有効になっています。

$ ls /dev/i2c*

/dev/i2c-0 /dev/i2c-6

I2Cバスが有効でないか、RTCデバイスが見つからない場合には以下のように表示されます。

$ timedatectl

               Local time: 水 2020-12-16 19:58:01 JST
           Universal time: 水 2020-12-16 10:58:01 UTC
                 RTC time: n/a
                Time zone: Japan (JST, +0900)
System clock synchronized: no
              NTP service: active
          RTC in local TZ: no


RTCデバイスにアクセス可能な場合には以下のように表示されます。RockCM3の場合にはRK817デバイスが、CM3上に搭載されているのでこちらのRTCが見えているのかもしれません。

$ timedatectl
               Local time: 水 2020-12-16 19:56:22 JST
           Universal time: 水 2020-12-16 10:56:22 UTC
                 RTC time: 水 2020-12-16 10:56:23
                Time zone: Japan (JST, +0900)
System clock synchronized: yes
              NTP service: active
          RTC in local TZ: no



i2cdumpコマンドでRTCチップPCF85063Aのレジスタを読み出してみます。レジスタ内容が32アドレスごとに繰り返しています。レジスタが0x00-0x11までしかないからです。レジスタ4が秒を示していて、更新されているのがわかります。

$ sudo i2cdump -y -0 0x51



参考資料: https://akkiesoft.hatenablog.jp/entry/20201217/1608130800
参考資料: http://www.hogetan.net/note/memo/pi_i2ccmd.html



FAN制御用EMC2301



CM4 I/O boardのデータシートに寄ればファンの制御用のIC EMC2301が搭載されています。i2cdumpコマンドでレジスタ内容を確認してみます。Raspberry Piでよくある冷却ファンの制御はGPIOピンを使ってソフトウェアでPWM制御しているようです。この方法ではCPUパワーが潤沢でないRaspbery Piに負荷をかけ、結局CPU温度を上げてしまうようです。ファンの強さを制御するなら専用のPWMコントローラで制御するほうが理にかなっているでしょう。



EMC2301のデータシートによればレジスタFDhがプロダクトIDでEMC2301:37h / EMC2302:36h / EMC2303:35h / EMC2305:34hを示し、レジスタFEがマニファクチャID 5Dhを示すようです。このFan用PWMコントローラは4PINのファンコネクタ経由でPWMをするだけでなく回転数も読めるようです。回転数を指定して動作させるにはCM4/RockCM3で使用できる4-pinファンを有するヒートシンクは見つからないので、4cmのファンのみ入手してみようかと思っています。今回は直接PWMのデューティ比を制御してみます。PWM1のデューティ比を制御するにはレジスタ30hを書き換えればよいようです。FFhで100%、80hで50%です

$ sudo mraa-i2c set 0 0x2f 0x30 0x80





参考資料: https://yokahiyori.com/raspberry-pi-cm4_cooling/#:~:text=ながら調整です。
参考資料: https://lab.sasapea.mydns.jp/2022/07/15/rp-pwmfan/

ユーザーモードでのI2Cアクセス

/dev/i2c-*へのアクセスにはスーパーユーザーの権限が必要です。ターミナルからのコマンドならsudo を先頭に付加すればよいのですが、GUIアプリケーションだとそうもいきません。回避する方法として、GUIを実行するユーザーアカウントをI2Cグループに追加する方法があります。/dev/i2c-* の属性を見るとグループに対してR/W可能になっています。

$ sudo adduser rock i2c

一旦ログアウトするとこのユーザーからI2Cにアクセスできるようになっています。



参考資料: https://femm.hatenadiary.org/entry/20150501/1430464817

ユーザーモードでのGPIOアクセス

/sys/class/gpio/*へのアクセスにはスーパーユーザーの権限が必要です。I2Cの場合にはi2cグループ属性からの読み書きができましたが。こちらはrootでのみのアクセスになっています。そこで、gpioグループを作成してユーザーをgpioグループに参加させ、アクセスできるようにします。

$ sudo addgroup gpio
Adding group `gpio' (GID 1001) ...
Done.
$ sudo usermod -aG gpio user

ついで、この gpio グループに対してデバイス管理ツール(udev rules)を作成します。

$ sudo vi /etc/udev/rules.d/60-gpio-group.rules

ファイルの中身は以下のようにします。

SUBSYSTEM=="gpio", KERNEL=="gpiochip[012345]", GROUP="gpio", MODE="0660"
SUBSYSTEM=="gpio", PROGRAM="/usr/bin/bash -c '/usr/bin/chown -R root:gpio /sys/class/gpio/gpio*/*'"
SUBSYSTEM=="gpio", PROGRAM="/usr/bin/bash -c '/usr/bin/chmod -R ug+rw /sys/class/gpio*/*'"
SUBSYSTEM=="gpio", PROGRAM="/usr/bin/bash -c '/usr/bin/chown -R root:gpio /sys/devices/platform/*.gpio/*'"
SUBSYSTEM=="gpio", PROGRAM="/usr/bin/bash -c '/usr/bin/chmod -R ug+rw /sys/devices/platform/*.gpio/*'"

再起動後、/dev/gpio* と /sys/class/gpio/は gpioグループからアクセスできるようになっています。



参考資料: https://knowledge.sayabo.com/2022-03-18/aml-s905x-cc-の-armbian-22-02-にて-gpio-を制御する/

ユーザーモードでのPWMアクセス

/sys/class/pwmchip*/へのアクセスにはスーパーユーザーの権限が必要です。gpio同様pwmグループを作成してユーザーをpwmグループに参加させ、pwmグループでアクセスできるようにします。

$ sudo addgroup pwm
Adding group `gpio' (GID 1001) ...
Done.
$ sudo usermod -aG pwm user

groupsコマンドでユーザーはrootグループに参加していないことを確認します。rootグループに参加していると、exportしてできるpwm*フォルダのオーナーがgpioではなくrootになってしまい、うまく動作しません。rootグループの参加している場合にはgpasswd -dコマンドでグループから除外します。

$ groups rock
rock : rock root sudo audio video netdev i2c gpio pwm
$ sudo gpasswd -d rock root
ユーザ rock をグループ root から削除
$ groups rock
rock : rock sudo audio video netdev i2c gpio pwm
$

ついで、この pwm グループに対してデバイス管理ツール(udev rules)を作成します。

$ sudo vi /etc/udev/rules.d/60-pwm-group.rules

ファイルの中身は以下のようにします。

SUBSYSTEM=="pwm*", KERNEL=="pwmchip[01]", GROUP="pwm", MODE="0660"
SUBSYSTEM=="pwm*", PROGRAM="/usr/bin/bash -c '/usr/bin/chown -R root:pwm /sys/class/pwma/pwm*'"
SUBSYSTEM=="pwm*", PROGRAM="/usr/bin/bash -c '/usr/bin/chown -R root:pwm /sys/devices/platform/*.pwm/*'"
SUBSYSTEM=="pwm*", PROGRAM="/usr/bin/bash -c '/usr/bin/chmod -R ug+rw /sys/class/gpio*/*'"
SUBSYSTEM=="pwm*", PROGRAM="/usr/bin/bash -c '/usr/bin/chmod -R ug+rw /sys/devices/platform/*.pwm/*'"

再起動後、/sys/class/pwm/は pwmグループからアクセスできるようになっています。ただし、exportしたあとにできるpwm0等のフォルダの属性は変更されません。いまのところ自動でchmod/chownする方法がみつからないので、手動で行う必要があります。

$ echo 0 >> /sys/class/pwm/
参考資料: https://forums.raspberrypi.com/viewtopic.php?t=316514/
参考資料: https://forums.raspberrypi.com/viewtopic.php?t=173282
参考資料: https://www.linuxmaster.jp/linux_skill/2012/11/post-134.html



I2C/PWM/GPIOによるファンコントローラ

I2CやGPIOを使う方法がわかりましたので、システムトレイに収容されるファン制御 Qtアプリケーションを作成しました。比較的重たい処理をRaspberry Pi 4Bにさせた場合に、ヒートシンクがついていてもかなり温度が上がるようです。できれば夏場も安定して動作してほしいですし、制御機器として使用する場合には製品寿命を短くしないためにもファンによる冷却はあったほうがいいと思われます。しかし、ファン自体も電力を食いますし、よく冷えるファンは煩いので、必要なときのみに動作させたいところです。

Raspberry Pi OSで標準的にサポートしているファン制御は基本的にOn/Offの制御のみのようです。さらに言えば、Ubuntuではファン制御アプリのサポートはありません。今回のファン制御アプリケーションでは以下の3種類の制御を行うことができます。。

  1. CM4 I/O ボードに搭載のEMC2301をI2C制御
    EMC2301は4線式のファンを接続し、PWMのDuty比による制御またはファン回転数による制御を 行うことができます。Raspberru Pi Compule Module 4またはRadxa Compute Module 3を CM4 I/Oボードに接続した場合等、I2Cバス上にEMC2301を見つけた場合に、この制御を選べる ようにしてあります。負荷や電源電圧の変動に寄らず、ICが目的の回転数でファンを回転させる ために、安定してCPUに付加をかけずに成業することが可能です。

  2. ハードウェアPWMによるファン制御
    /boot/config.txtを編集することによりGPIOと共有するピンの一部をPWMにすることができます。 HAT端子にもいくつかのピンが出ています。このPWM機能を使用することで、CPUに負荷をかけず にDytyを指定してファンを制御することができます。3ピンタイプのファンが使用できます。

  3. ソフトウェアPWMによるGPIOファン制御
    PWM機能に割り当てたいピンにすでにほかの機能が割り当てられていたりする場合もあります。 ソフトウェアでGPIOピンをHigh/Lowに制御することでDutyを変更し、任意の空きピンでファンを 制御する方法です。CPUへの負荷をできるだけ抑えるため、PWM周波数はごく遅くしてあります。 3ピンタイプのファンが使用できます。




fancontrol_1.0.0.1_arm64.deb for Bullseye/Ubunth20.04 (ARM 64bit)

右クリックしてダウンロードします。インストール方法は以下の通り

$ sudo dpkg -i fancontrol_1.0.0.1_arm64.deb
アプリケーションを実行する前に、前述の方法で、root権限ではなく、本アプリを使用するユーザーからI2C/PWM/GPIOにアクセスできるように設定しておいてください。特にハードウェアPWMを使用する場合には使用するPWMをあらかじめexportしておく必要があります。

起動後に自動的に起動するためにはUbuntuデスクトップの場合には「自動起動するアプリケーションの設定」で設定します。起動を遅らせるため、Commandの項目を[bash -c "sleep 30 && /opt/group_design_service/fancontrol/fancontrol"]に設定します。




VNC経由での接続の場合、「セッションと起動」で設定できます。





アクセスカウンター アクセスカウンター