はじめに
Armadillo-IoT A9Eを使用したJapanITWeek・2025春 流量監視デモは
水の流れを計測する流量計が接続されたArmadillo-IoT A9Eがその流量をArmadillo-X2へ送信。
流量を受信したArmadillo-X2がディスプレイにグラフを表示するものになります。
参考動画:
Armadillo-IoT A6E +Di8+Ai4タイプを用いた流量監視デモ
※こちらはArmadillo-IoT A6E +Di8+Ai4を使用したものになります。
Armadillo-IoT A9E、Armadillo-900シリーズには、Linux を実行する2 つの Arm Cortex-A35 コアに加えて
1 つの Arm Cortex-M33 コアが搭載されており、デモではこのArm Cortex-M33 コア ソフトをカスタマイズしました。
この記事では、Cortex-M33カスタマイズ例として、デモソフトを解説。
また、番外編として、Linux sleep中に特定の流量に達した際、M33側から起床させる方法をご紹介します。
※Armadillo-IoT A9Eの製品マニュアルには、デバッグインターフェースの都合上
Cortex-M33カスタマイズについて記載しておりません。
システム構成
JapanITWeek・2025春 流量監視デモのシステム構成は
A9Eのデジタル出力(DO1、DO2)をパトライトに、デジタル入力(DI1)を流量計に接続。
A9Eは流量計のパルス出力から算出した流量をLANで接続したX2へ送信、また流量に応じてパトライトを制御。
流量を受信したX2は、HDMI接続されたディスプレイにグラフ表示をしています。
A9Eは、アナログ入力を持たないので、流量計はパルス出力モードで使用。
高速に出力されるパルスを正確に把握するため、M33がアクセスできるデジタル入力1の立ち上がりエッジ割り込みを
使用することにしました。
実際の接続
M33のカスタマイズ方法
RTOS ファームウェアの開発
を参照してください。
M33で検出した流量をLinuxへ通知するため
上記の後半に記載された arch/arm64/boot/dts/freescale/armadillo_900-customize.dtsを
編集し、Linuxに/dev/ttyrpmsg2を追加してください。
詳しい手順は以下に記載されています。
独自の DTS overlay を追加する
M33から送信されるデータは、Linuxでこの/dev/ttyrpmsg2に受信されます。
M33側の実装
m33-firmware-atのcustomディレクトリ内のソースを編集し
DI1を入力で初期化、立ち上がりエッジでの割り込みを登録。
FreeRTOSのSoftware Timerを使用し、1秒毎に直近2回のパルス間隔から計算した流量をLinuxへ通知します。
また、custom_tx関数を利用して、/dev/ttyrpmsg2に「alert=XXXX」という文字を送信しておくと
Linuxがsleep中。XXXXで指定した流量に達した場合、起床させる処理も実装しています。
customディレクトリの変更内容
m33_firmware_at/customディレクトリの変更内容を記載します。
●m33_firmware_at/custom/app_tty_custom.c
Linux が追加した tty に書き込むと実行される custom_tx() 関数に
Linuxがsleep中、特定流量に達した際、起床させる閾値設定を追加しています。
また、FreeRTOSのSoftwareTimerを使用して、1秒周期にコールバックされる関数を登録。
コールバック関数内では、流量の算出とLinux通知。Linux sleep中の起床処理を定義しています。
●m33_firmware_at/custom/custom.c
M33起動時の初期化処理の中で、DI1を入力として初期化、立ち上がりエッジで
直近2回の割り込み時間を取得する割り込みハンドラを登録しています。
また、前述の1秒周期コールバック関数を起動。Linux sleep中もM33はアクティブのまま動作するようにします。
Tips
●流量計算方法
使用している流量計(PF3W704)は、50mL/pulseの仕様になっています。
Linuxへは1分単位の流量(ml/min)を通知しているため、パルス間隔から1分単位での流量を算出する必要があります。
・パルス間隔が1秒なら
50ml×60秒÷1秒=3000ml/min
・パルス間隔が1.5秒なら
50ml×60秒÷1.5秒=2000ml/min
・パルス間隔が2秒なら
50ml×60秒÷2秒=1500ml/min
という具合に、パルス間隔から1分あたりの流量が算出できます。
※ソースコードでは、FreeRTOSのtickを使用して、上記を計算しています。
●流量 0ml/min 判定、パルス間隔が長くなった場合の補間処理
基本、上記で流量は算出できるのですが、
・流量が少なくなるとパルス間隔が伸びていく。その際、1秒毎にLinuxへ通知している流量の値をどうするか?
・流量 0ml/minでは、全くパルスが来なくなる。
という問題があります。
これに対し、以下の処理を作りました。
・タイムアウトを設け、流量 0ml/minを判定。
・1秒毎にLinuxに流量を通知しているタイマー内で、パルス間隔が前回通知より伸びていたら補間値をLinuxへ通知する。
Pythonアプリの実装
ABOSDEでX2へ流量を通知するシンプルなPythonアプリを開発しました。
・TCPによるLAN通信
・DO2つによるパトライト制御
・M33からの流量受信
を行っています。
main.pyの他に、使用するパッケージ、デバイスの都合
packages.txtにpython3-libgpiod
requirements.txtにpyserial
app.confにadd_devices /dev/gpiochip1,add_devices /dev/ttyrpmsg2
を追加しています。
X2アプリの実装
A9EからTCPで受信したデータをグラフ化するソフトをFlutterで開発しました。
本ブログは、Armadillo-IoT A9E、Armadillo-900 、Cortex-M33カスタマイズ例を記載したものなので、説明は割愛します。
番外編(特定流量での起床)
作成したPythonアプリは、常時流量を監視するものですが
通常はsleepしていて、流量が特定条件になった際、起床するアプリケーションを作りたい場合もあると思います。
今回、M33にはLinux sleep中、特定流量を超えた際の起床処理も実装しているので、その場合の使用例です。
2023.04-at5 以上のブートローダーソースコード m33-firmware-atをcustomする必要があります。
流量が2500ml/min以下の状態で
コンソールから以下のコマンドを実行すると、sleep中に流量が2500ml/minを超えた時、Linuxが起床します。
[armadillo ~]# echo alert=2500 > /dev/ttyrpmsg2
[armadillo ~]# aiot-sleep
modemmanager | * Stopping modemmanager ... [ ok ]
connection-recover | * Stopping connection-recover ... [ ok ]
OK
aiot-sleep: Power Management suspend-to-ram
※流量が2500ml/minを超えた。
I/TC: Secondary CPU 1 initializing
I/TC: Secondary CPU 1 switching to normal world boot
[ 345.776770] fec 29950000.ethernet eth0: Graceful transmit stop did not complete!
aiot-sleep: change mode CPU Idle
OK
modemmanager | * Starting modemmanager ... [ ok ]
connection-recover | * Starting connection-recover ... [ ok ]
[armadillo ~]# [ 349.774678] usb 2-1.1: Device is not authorized for usage
ソースコード
・m33カスタマイズソース
GitHubにて公開してます。
git clone -b demos/flow_rate https://github.com/atmark-techno/m33-firmware-at m33_firmware_at
上記gitコマンド取得できます。
・Pythonアプリ
a9e-water-demo-202506.zip
・X2アプリ
a9e-water-demo-x2.zip
補足
今回、デモで使用したArmadillo-IoT A9EでのCortex-M33カスタマイズ例を記載しました。
ですが、Armadillo-IoT A9EはCortex-M33デバッグ用のインターフェース(コンソール/JTAG)が
外に出ておりません。
Cortex-M33の開発は、Armadillo-900 開発セットを使用して行うことを推奨します。