GR-ROSE IoTシステム開発コンテスト総復習

この記事は がじぇるねGR Advent Calendar 2021 の22日目です。

先月参加したGR-ROSE IoTシステム開発コンテスト 作品LT大会、ユニークな発表が多数ありましたが発表時間内では私の理解が追い付かなかったので、YouTubeで復習します。こうやって後から見返せるのはありがたいですね。自分の発表は見たくありませんが (^^;)

※ この記事は私の個人的なまとめです。独断と偏見を含みます。また私の理解不足のせいで誤解や抜け落ちがあるかもしれませんがご容赦ください。

エントリー (発表順、敬称略)

開始時間をクリックすると動画が始まります。

No タイトル 発表者 開始時間
コロナ禍・リモートワークとIoT 豊田陽介 0:10:05
GR-ROSEとAzureでつっこみロボをつくる 金子啓太 0:17:50
GR-ROSEを使って、RFIDタグ情報をAzureと連携してみる 松田夕貴 0:26:20
えっ!GR-ROSEってA*mじゃないの?から始めた話 永久健三 0:33:25
3軸アーム GUI 石垣翔子 0:42:40
コネクテッドマウス 長島宏明 0:50:25
IoT渾天儀で太陽の運行を知る 西村備山 1:01:05
GR-ROSE de ロボットカー 林 宜憲 1:08:45
LIDAR JUMP!! TKTK360 1:17:50
いろいろお知らせしてくれるIoT鳩時計 しろいとり子 1:26:35
Azureロボットは二足歩行の夢を見るか? 中村恭一 1:33:50
GR-ROSEとIoTCでいろいろ見守り 大栄 豊 1:42:30
IoT Central をつかった雲台制御 すぎやま 1:56:05
GR-ROSE + Azureで、見守りや防犯の仕組み robojp 2:01:35
ドローンにおけるGR-ROSE & Azure IoT Centralの一使用例 chaos 2:11:00
ネット経由でサーボアームを制御してみようとした(仮) TakSan 2:24:00
GR-ROSE による温湿度制御 やま 2:33:45

接続方法についての所感

Azure IoT vs MQTT

今回、17名中12名はIoT Centralを利用しました。一方で4名がMQTTを使用しており、MQTTの根強さがうかがえます。

マイクロソフト太田さんの言う「デバイスの数が何十万、何百万になったときに、MQTTでやるよりもAzure IoTを使ったほうが簡単」というは理解できる一方で、「そんな数のデバイスを想定してないしシンプルにMQTTでやりたい」というのも理解できます。加えて、われわれ組込み系技術者はブラックボックスを嫌う傾向があり、「チンプンカンプンな概念を理解して使うよりも低レベルからフルスクラッチしたほうが早くて確実だ!」という習性があるように思います (^^;)

Azure IoT Hubへの道

今回、少なくとも3名がGR-ROSEからAzure IoT Hubへの接続を試みるもうまくいかず代替手段をとることになりました。Azure IoT Hubへ直接接続されたのは石垣さんお一人だけのようです。石垣さんいわく「サンプルプログラムをIoT Hub用に改良しただけ」とのことですが、私も林さんもそこでつまづきました (^^;) これについてはもう少し詳しい情報が欲しいところです。

【2021/12/24 追記】
石垣さんからを情報いただき、接続できるようになりました。ありがたや!

その他のAzure技術についての所感

私はApp Serviceで Node.js を使ってWebアプリをホストしましたが、静的なファイルのホスティングBlob Storageを使うという手もあるんですね。また、Functionsを使ってサーバーレスでコードを実行するという手法をはじめて知りました。

その他の技術についての所感

Unityあり、ROSあり、基板設計あり、CNC加工ありと、みなさん多彩な技術をお持ちで、これぞコミュニティーの醍醐味という感じがしました。

使用デバイスについての所感

GR-ROSEがロボット用ボードということもあって、PWMサーボやシリアルサーボを使った作例が目立ちました。3軸ロボットアーム持ってるかたが4名もいてビックリ。その他に面白そう・便利そうと思ったものをピックアップします。

使用技術一覧 (主なもの)

No IoT接続 その他のAzure技術 その他の技術 主なデバイス
IoT Hub
(テレメトリ)
(MQTT経由)
Stream Analystics
Functions (Node.js)
Power BI
LINE Notify
Node.js (MQTT.js)
Grove CO2センサ
M5Stack Core2
LEDテープ+光拡散チューブ
IoT Central
(コマンド/API使用)
Blob Storage
(ホスティング)
- PWMサーボ (べゼリー)
Grove MP3モジュール
IoT Central
(テレメトリ/ルール)
- - UHF RFIDタグ / リーダー
MQTT - IFTTT, Google Assistant
Beebotte(MQTTブローカー)
Google Home
赤外線リモコン
IoT Hub
(ダイレクトメソッド?)
(デバイスツイン?)
Functions (Python) PHP(フロントエンド) 3軸ロボットアーム
IoT Central
(テレメトリ)
- TynyUSB(USBスタック)
TOPPERS, 基板設計
マウスのセンサIC
(ADNS-5050)
IoT Central
(コマンド/API使用)
App Service
(Node.js)
- ステッピングモータ
IoT Central
(コマンド)
Blob Storage(ログ)
Machine Learning
- シリアルサーボ
(KRS-3301, 回転モード)
TOFセンサ(VL53L0X)
MQTT Virtual Machines
(MQTTブローカー)
Unity LiDARセンサ(Camsense X1)
micro:bit
IoT Central
(コマンド/ジョブ)
- 3Dプリンタ PWMサーボ
Grove MP3モジュール
Grove 4-Digit Display
IoT Central
(コマンド)
- 板金設計/CNC加工 PWMサーボ
(KRS-4024, PWMモード)
IoT Central
(テレメトリ)
- GDBデバッグ 温湿度センサ
(HS3001, AHT20)
IoT Central
(テレメトリ)
- Python, Node-RED(ローカル)
ARマーカー, 3Dプリンタ
3軸ロボットアーム
9軸センサ(MPU9250)
IoT Central
(テレメトリ)
- - 焦電型赤外線センサ(PaPIRs)
PWMサーボ, プチブロック
IoT Central
(テレメトリ)
- ROS2 / Micro-ROS, RViz
Node.js(ローカル)
ドローン(+姿勢センサ)
3軸ロボットアーム
MQTT - shiftr.io(MQTTブローカー) 3軸ロボットアーム
IoT Central
(テレメトリ/コマンド)
- - 温湿度センサ(HS3001)
PWMサーボ

中華なデジタル顕微鏡Andonstar ADSM301

中国製のデジタル顕微鏡を買いました。
AndonstarのADSM301という製品です。
アマゾンで15999円。アマゾン発送ですぐ届きました。

f:id:licheng:20210807181130j:plain:w640

良いところ

  • 5インチの本体画面 / HDMI出力(フルHD) / USB接続(720P) の3通りの使い方ができる。
  • マイクロSDカード対応でスタンドアローンでも撮影・録画できる。
  • これだけの機能でこの価格!

良くないところ

  • メーカーのサイトを見ても製品仕様が分かりにくい。
  • 本体の操作ボタンがペコペコで安っぽい。操作画面が古臭い。
  • 本体画面はチルトできない。 (もうちょい上向きであってほしかった)
  • 本体画面とHDMI出力、USB接続は排他利用。 (これはしかたないか)

Andonstarのラインナップ

昨今では中国製のデジタル顕微鏡がアマゾンでもいろいろ出回るようになりました。中でもAndonstarというメーカーの製品はユーザー数が多いようで、YouTubeでもレビュー動画がたくさん見つかります。アマゾンでもメーカーの公式ストアが販売しているので安心感があります。

Andonstarのデジタル顕微鏡は品種がたくさんあってラインナップがいまいち分かりにくいのですが、ポイントは、①イメージセンサの画素数 ②本体画面のサイズ ③HDMI出力の可否 ④USB接続の可否 ⑤価格 です。

AD206 AD208 ADSM301 ADSM302 AD407 AD409
イメージセンサ 2M 2M 3M 3M 4M 4M
画面サイズ 7" 8.5" 5" 5" 7" 10.1"
HDMI出力 × ×
USB接続 × × ×
価格 \13k \15k \16k \23k \25k \40k

まず、イメージセンサの画素数によってローエンドのAD20x、ミドルレンジのADSM30x、ハイエンドのAD40xに分かれます。AD20xは画面は大きいもののHDMI出力もUSB接続もできません。ADSM30xは画面は5インチと小さめですがHDMI出力、USB接続とも対応しています。AD40xは画面も大きくHDMI出力にも対応していますが、AD407はなぜかUSB接続には非対応。AD409は全部入りでWiFiにも対応したフラッグシップモデルといった感じです。

なのでそこそこの価格でUSB接続が欲しいならADSM30xになります。ADSM301とADSM302の差がいまいちよく分りませんが、ADSM302のほうがスタンドが大きく対物距離も大きくとれて倍率も高い(つまり作業スペースを広く取れる)っぽいです。またADSM302は本体画面をチルトできます。

私はコスパ重視でADSM301を選びました。

ADSM301の3通りの使い方

(1) 本体画面 (スタンドアローン)

モニタにもPCにも接続せず、本体単独で使うことができます。本体画面の解像度は854x480ですが、ハンダ付け作業にはじゅうぶんでしょう。
本体にはマイクロSDカードのスロットがあり、写真や動画を撮って保存できます。動画の解像度はフルHD(1920x1080)です。写真の解像度は設定で変更できます。

(2) HDMI出力

本体にミニHDMI出力端子があり、外部モニタに映像を出力できます。解像度はフルHD(1920x1080)です。モニタに接続すると自動でHDMI出力に切り替わり本体画面は消灯します。

(3) USB接続

本体にマイクロUSB端子がありPCに接続できます。専用ソフトもありますが、とくに何もインストールしなくてもWindows 10ではカメラとして認識しました。ふつうのWebカメラと同様にカメラアプリでの写真撮影や動画録画ができます。解像度はフルHDではなく、写真・動画とも1280x720になります。アプリの設定で録画の解像度をフルHDに設定することはできますが、カメラ入力の解像度じたいは720P固定です。
f:id:licheng:20210802215314j:plain:w600

専用アプリは寸法や角度などを計測するためのものです。Andonstarのサイトからダウンロードできますが、インストールしようとすると「WindowsによってPCが保護されました」というブルーの警告メッセージ。かまわず実行するとノートン先生が「疑わしい処理を遮断しました」のメッセージ。いちおうインストールされたアプリを実行してみると「MSVCR100.dllが見つからない」というエラー連発。無理してインストールする必要も無いかなと思います。

写せる範囲

写せる範囲は、スタンドを上げて対物距離を最大にしたときで25mm×14mm程度。
f:id:licheng:20210801213356j:plain:w300 f:id:licheng:20210801213412j:plain:w300

スタンドを下げて対物距離を最短にしたときで、8mm×5mm程度。
f:id:licheng:20210801213426j:plain:w300 f:id:licheng:20210801213439j:plain:w300

加えて最大4倍までのデジタルズームができます。(USB接続時は無効)

試しにハンダ付け作業に使ってみた

0.75mmピッチ端面スルーホール部品のハンダ付けを試してみました。じゅうぶん使えますね。本体画面を使うのが遅延なくかつ自然な視線の向きになって良いと思います。ただ、実体顕微鏡とちがって遠近感が無いため思いのほか糸ハンダが操りにくいです。これはちょっと慣れが必要かも。実体顕微鏡が双眼で立体視できるのはやはり重要なことでした。

所感

この性能のものがこの価格で買えるのが驚異的ですね。自分の使い方としては

の2つがメインになりそうです。

参考サイト

GR-ROSEのブートとプログラム書き込みの仕組み

この記事は がじぇるねGR Advent Calendar 2021 の18日目です。

GR-ROSEのブートとプログラム書き込みの仕組みは、公式の資料がやや分かりにくかったので調査しました。
(ふつうに使うぶんにはほぼ必要ない知識です。)

まず、起動時のシーケンスを概観すると下図のようになります。

f:id:licheng:20211211111043p:plain:w440

(1) ユーザーアプリの起動

通常は、スライドスイッチSW1は「R」にセットされており、電源ONするとユーザーアプリが実行されます。

f:id:licheng:20211211110451j:plain:w320

(2) USBファームウェアの起動

リセットボタンを押すと、USBファームウェアが起動し、PCにはUSBストレージとして認識されます。ここにユーザーアプリのbinファイルをコピーするとユーザーアプリがマイコンに書き込まれます。

電源ON(コールドスタート)かリセットボタン押下(ウォームスタート)かの区別は、USBファームウェアがRSTSR1レジスタの値を見て判定しています。ただし、ウォームスタートであってもソフトウェアリセットの場合はユーザーアプリが起動します。これはRSTSR2レジスタの値を見て判定しています。

(3) USBブートモード

スライドスイッチSW1が「P」にセットされている場合、電源ONまたはリセットするとUSBブートモードで起動します。このモードではPCからRenesas Flash Programmer (RFP) を使ってプログラム(motファイルなどの形式)を書き込むことができます。

スライドスイッチSW1はRXマイコンのMD端子とUB端子につながっています。RXマイコンはMDがHighのときシングルチップモード(通常起動)になり、MDがLowでUBがHighのときUSBブートモードになります。

(2)でのプログラム書き込みはGR-ROSEのUSBファームウェアが提供する機能であるのに対し、(3)はRXマイコンにもともと備わっているブートプログラムの機能です。なんらかの理由でGR-ROSEのUSBファームウェアが消えてしまった場合(例えばE2デバッガを接続してプログラムのデバッグをおこなった場合)には、(3)の方法でUSBファームウェアを書き直すことができます。USBファームウェアmotファイルはGR-ROSEの公式ページからダウンロードできます。

GR-ROSEのFlashメモリマップと起動手順

スライドスイッチSW1が「R」のとき、RXマイコンはシングルチップモードで起動し、リセットベクタ(FFFFFFFC番地)に格納されているアドレスにジャンプします。リセットベクタにはUSBファームウェアのリセットハンドラ(PowerOn_Reset_PC関数)のアドレスが格納されているので、まずUSBファームウェアが起動します。USBファームウェアは前述のようにリセット要因をチェックして、ユーザーアプリを起動するかまたはUSBファームウェアの実行を継続します。

f:id:licheng:20211210225837p:plain:w400

ユーザーアプリのリセットハンドラ(PowerOn_Reset_PC関数)はFFE00000番地になるようにビルドされます。USBファームウェアは、ユーザーアプリを起動する場合にはこのFFE00000番地にジャンプします。

USBファームウェアの実行が継続された場合、PCからコピーされたbinファイルはまずUSBストレージ領域に書き込まれ、それからユーザーアプリ領域に展開され、その後ユーザーアプリのリセットハンドラにジャンプします。

GR-ROSEで FreeRTOS vs Azure RTOS

この記事は がじぇるねGR Advent Calendar 2021 の14日目です。

GR-ROSEでは、FreeRTOSとAzure RTOSという2つのRTOSをお手軽に使うことができます。
この記事ではGR-ROSEでこの2つのRTOSを比較します。

FreeRTOSとAzure RTOSについて

FreeRTOSはオープンソースRTOSで、2017年にAmazonに買収され現在はMITライセンスで公開されています。(買収以前はGPLライセンスでした。)

いっぽう、Azure RTOSは元の名をThreadXといい、2019年にMicrosoftに買収されました。ソースコードGitHubで公開されてはいますが、プロプライエタリなライセンスになっています。Microsoftは特定のマイコンメーカーとOEMライセンス契約を結んでおり、ライセンスされたマイコンでは無償でAzure RTOSを利用できます。逆に言えば、ライセンスされていないマイコンにAzure RTOSを移植して勝手に再配布したり本番利用したりはできません。別途ライセンス料金を支払う必要があります。

f:id:licheng:20211204111701j:plain:w400

この2つのRTOSのどちらが良いかというのは一概に言えませんが、IoTに関して言えば答えは簡単です。クラウド側がAWSならFreeRTOS、AzureならAzure RTOSでしょう。そもそもAmazonMicrosoftも自社のIoTソリューションのためにこれらのRTOSを買収したわけですから、とうぜん自社のIoTクラウドサービスとの連携をサポートしています。

f:id:licheng:20211204102653j:plain:w500

ベンダ クラウド RTOS
Amazon AWS FreeRTOS
Microsoft Azure Azure RTOS

この記事ではIoTサポートの話は横に置いて、RTOSの基本的な部分について2つのRTOSを比較していきます。

GR-ROSEでFreeRTOSとAzure RTOS

GR-ROSEの開発環境はWebコンパイラ、e2studio、IDE for GRの3種があり、どれもFreeRTOSベースのArduino互換SDKが基本です。Arduino互換のAPIが使えるので、FreeRTOSをまったく意識しなくともプログラムできますが、FreeRTOSのAPIを使用すればマルチタスクなプログラミングも可能です。

#include <Arduino.h>
#include <FreeRTOS.h> // FreeRTOSのAPIを使う場合はインクルード
#include <task.h>     // タスク関係
#include <semphr.h>   // セマフォ、ミューテックス関係
#include <queue.h>    // キュー関係

いっぽう、Azure RTOSに関してはWebコンパイラとe2studioでAzure IoT Central用のサンプルプロジェクトが提供されています。こちらもArduino互換SDKですが、Azure RTOSAPIを使用すればマルチタスクなプログラミングも可能です。IDE for GRはサポートしてません。

#include <Arduino.h>
#include <tx_api.h> // Azure RTOSのAPIを使う場合はインクルード

マルチタスク

まずはRTOSの根幹であるマルチタスクから。(FreeRTOSではタスク、Azure RTOSではスレッドという用語を使いますが、方言の差くらいに捉えておきます。)

FreeRTOSでは次のように書きます。タスク関数へ渡す引数やハンドルの取得は不要ならNULLを渡します。

結果 = xTaskCreate(
    タスク関数, タスクの名前, スタックサイズ,
    タスク関数へ渡す引数のポインタ, 優先度, ハンドルを返すポインタ );

Azure RTOSでは次のように書きます。スタックに用いるメモリは予め確保した領域を渡します。プリエンプション閾値とタイムスライス値については後述します。自動スタートは、スレッドをすぐに開始するならTX_AUTO_STARTを、保留状態にするならTX_DONT_STARTを渡します。

結果 = tx_thread_create(
    ハンドルを返すポインタ, スレッドの名前, スレッド関数,
    スレッド関数へ渡す引数, スタック先頭へのポインタ, スタックサイズ,
    優先度, プリエンプション閾値, タイムスライス値, 自動スタート);

優先度の数字に注意してください。FreeRTOSでは数字の大きいほうが優先度が高くなるのに対し、Azure RTOSでは数字の小さいほうが優先度が高くなります。

GR-ROSEのメインタスク( setup()とloop() )は、FreeRTOS環境では優先度3、スタック512バイトに設定されています。(FreeRTOS/src/amazon_freertos_common/freertos_start.c)
いっぽう、Azure RTOS環境では優先度4、スタック4キロバイトに設定されています。(src/main.c)

排他制御

マルチタスクで並列処理をすれば、たいていの場合はミューテックスなどを使った排他制御が必要になります。

FreeRTOSでは次のように書きます。最大待ち時間はtick数で指定します。後述しますが、GR-ROSEでは tick = 1msec となっています。portMAX_DELAYを指定すると永久に待ちます。

SemaphoreHandle_t mutex;
mutex = xSemaphoreCreateMutex();
結果 = xSemaphoreTake(mutex, 最大待ち時間); // ミューテックスを獲得する (ロックする)
結果 = xSemaphoreGive(mutex); // ミューテックスを返却する (アンロックする)

Azure RTOSでは次のように書きます。優先度継承については後述しますが、 TX_INHERITを指定すると優先度継承が有効となり、TX_NO_INHERITを指定すると無効になります。待ちオプションは、TX_NO_WAITを指定すると待たずに即座に戻り、TX_WAIT_FOREVER を指定すると永久に待ち、それ以外の値の場合は指定したtick数まで待ちます。GR-ROSEでは tick = 10msec となっています。

TX_MUTEX mutex;
結果 = tx_mutex_create(&mutex, ミューテックスの名前, 優先度継承);
結果 = tx_mutex_get(&mutex, 待ちオプション); // ミューテックスを獲得する (ロックする)
結果 = tx_mutex_put(&mutex); // ミューテックスを返却する (アンロックする)

優先度継承(Priority Inheritance)とは、スレッド間で待ち合いをする場合にそれらのスレッドの中の最高の優先度でクリティカルセクションを実行するというものです。優先度の高いスレッドが優先度の低いスレッドに待たされて遅れるケース(優先度の逆転)を緩和する狙いがあります。

FreeRTOSではミューテックスは必ず優先度継承になります。タスク間の同期など優先度継承をすべきでない場合にはミューテックスではなくバイナリーセマフォを用います。

タスク間通信

マルチタスクでもう一つよく使うのが、キューを使ったタスク間のメッセージのやりとりです。

FreeRTOSでは次のように書きます。最大待ち時間は前述のミューテックスの場合と同様です。

QueueHandle_t queue;
queue= xQueueCreate(キューの長さ, 要素のサイズ);
結果= xQueueSend(queue, 要素へのポインタ, 最大待ち時間); // キューの末尾に要素を送る
結果 = xQueueReceive(queue,  要素を返すポインタ, 最大待ち時間); // キューから要素を受け取る

Azure RTOSでは次のように書きます。要素のサイズは32ビットワード単位であることに注意してください。指定できる値は1~16です。キューに用いるメモリは予め確保した領域を渡します。キューのサイズはトータルのバイト数を指定します。待ちオプションは前述のミューテックスの場合と同様です。

TX_QUEUE queue;
結果 = tx_queue_create(&queue, キューの名前, 要素のサイズ, キューの先頭へのポインタ, キューのサイズ);
結果 = tx_queue_send(&queue, 要素へのポインタ, 待ちオプション); // キューの末尾に要素を送る
結果 = tx_queue_receive(&queue, 要素を返すポインタ, 待ちオプション); // キューから要素を受け取る

プリエンプション

プリエンプションとは、現在実行中のタスクより優先度の高いタスクが実行可能である場合にOSが強制的にタスクスイッチすることです。プリエンプションが無いと、タスクが自発的に待ち状態に入らないかぎりタスクスイッチは起こりません。これを協調的マルチタスクと言います。

【FreeRTOSの場合】
FreeRTOSはプリエンプティブマルチタスクにも協調的マルチタスクにも設定できます。GR-ROSEのFreeRTOSはプリエンプティブマルチタスク、同一優先度タスクのタスクスイッチ(タイムスライス)あり、システム割り込み周期(tick)は1msecに設定されています。

#define configUSE_PREEMPTION       1      // プリエンプション有効
#define configUSE_TIME_SLICING     1      // 同一優先度タスクのタイムスライスあり
#define configTICK_RATE_HZ         (1000) // tick = 1msec
// configUSE_PREEMPTIONが0のときはconfigUSE_TIME_SLICINGは無視されます。

【Azure RTOSの場合】
Azure RTOSは基本的にプリエンプティブマルチタスクですが、スレッドごとに生成時にtx_thread_createの引数で優先度の他にプリエンプション閾値、タイムスライス値が設定できます。また TX_DISABLE_PREEMPTION_THRESHOLD を定義することでプリエンプションを無効にも設定できるようです。

プリエンプション閾値より優先度の高いスレッドのみがプリエンプションの対象になります。したがって、プリエンプション閾値は優先度以下の値を指定します。プリエンプション閾値に0を設定するとプリエンプションはおこなわれません。

タイムスライス値は、同じ優先度の実行可能状態のスレッドがあるときにタスクスイッチをおこなう時間をtick数で指定します。優先度とプリエンプション閾値に同じ値を設定したときのみ有効です。タイムスライス値にTX_NO_TIME_SLICE (=0)を設定するとタイムスライスが無効になります。つまり同じ優先度のスレッド間ではプリエンプションがおこなわれなくなります。

GR-ROSEのAzure RTOSでは、メインスレッドは優先度=プリエンプション閾値、タイムスライス値はTX_NO_TIME_SLICEに設定されています。

※ 現状、GR-ROSEのAzure RTOSではプリエンプションがうまく機能していないようです。この件はRulzにて問い合わせ中です。

APIリファレンス

Raspberry Pi PicoでPWM出力

ピン機能の設定

  • gpio_set_function()でピン機能をGPIO_FUNC_PWMに設定する。
  • RP2040には8つのPWMスライスがあり、各スライスにA/Bの2つのPWMチャンネルがある。
  • つまり最大8×2=16チャンネルのPWM出力が可能。
  • PWM周波数や分解能はスライスごとに設定できる。
  • 偶数番(2n)のGPIOはAチャンネル、奇数番(2n+1)のGPIOはBチャンネルで、スライス番号は n % 8
  • スライス番号はpwm_gpio_to_slice_num()でも取得できる。

PWM周波数の設定

  • Raspberry Pi Picoのメインクロックは125MHz。
  • pwm_set_clkdiv()で分周比を設定する。(0~256未満の実数値で設定)
  • pwm_set_wrap()でPWMの分解能を設定する。

メインクロックをsysclock、PWM分解能の設定値をwrap、分周比をclkdiv とすると、
PWM周波数 f = sysclock / ((wrap+1) ⋅ clkdiv) より
clkdiv = sysclock / ((wrap+1) ⋅ f )

例えばPWM周波数を250Hzに、PWMの分解能を11ビット(0~2047)に設定したい場合、
sysclock = 125,000,000Hz、wrap = 2047、f=250Hz より
分周比 clkdiv = 244.140625 となる。ただし、clkdiv は実際には1/16単位に丸められる。

デューティーの設定

  • デューティー(High期間)の設定にはpwm_set_chan_level()を用いる。
  • PWM出力の有効/無効はpwm_set_enabled()で設定する。

サンプルコード (Arduino環境用)

#include <hardware/pwm.h>

void setup()
{
    // GP2とGP3のピン機能をPWMに設定
    gpio_set_function(2, GPIO_FUNC_PWM);
    gpio_set_function(3, GPIO_FUNC_PWM);

    // GP2(とGP3)のPWMスライスを取得
    uint slice_num = pwm_gpio_to_slice_num(2);

    // PWM周期を設定
    pwm_set_clkdiv(slice_num, 244.140625);
    pwm_set_wrap(slice_num, 2047);
    
    // チャンネルA(GP2)とチャンネルB(GP3)のPWMのHigh期間を設定
    pwm_set_chan_level(slice_num, PWM_CHAN_A, 1024);
    pwm_set_chan_level(slice_num, PWM_CHAN_B, 512);
    
    // PWM出力イネーブル
    pwm_set_enabled(slice_num, true);
}

void loop()
{
  
}

参考


GR-ROSEで作るIoT渾天儀

この記事は がじぇるねGR Advent Calendar 2021 の5日目です。
先月開催されたGR-ROSE IoTシステム開発コンテストでのLTをもとに補足情報を加筆したものです。

Introduction

今日は12月5日。暦の上ではまもなく大雪を迎え寒さが日増しに深まるこのごろですが、皆様お変わりなくお過ごしでしょうか?

私も若くて元気なころは季節の移ろいをあまり切実に意識することはありませんでした。基礎代謝が高いと冬の寒さなんてへっちゃらなんですよね。でもだんだん年を取るにつれて、冬の寒さがつらい。季節の変化を意識して体調管理にも気を配らないといけないようになってきました。

f:id:licheng:20211120185758j:plain:w600

IoT渾天儀で太陽の運行を知る

さて、季節の移ろいというのは、つまりは地球から見た太陽の運行のことですよね。
そこで太陽の運行を知るためにこんなメカを作ってみました!名付けてIoT渾天儀です。

f:id:licheng:20211120190508j:plain:w640

メカは100円ショップ(セリア)で売ってるプラダンと木材で作りました。円弧の切り出しには直径30cmまで対応のコンパスカッターを使用しました。手作りのアナログ工作です。CADすら使ってません。紙とペンと定規とコンパスで設計しました。

f:id:licheng:20211121122852j:plain:w640

目盛りはinkscapeで描いてPDF化し、コンビニでA3用紙にプリントアウトしました。分度器のような目盛りはinkscapeのタイルクローン機能を使うと簡単に描けます。コンビニでのプリントアウトでは原寸大で印刷することに注意。ローソンの場合は「用紙に合わせる」を「しない」に設定します。

渾天儀とは?

f:id:licheng:20211121121945p:plain:w250:right

渾天儀とはいったい何かというと、古代のギリシャと中国で発明された天体観測のための機械です。西洋ではArmillary sphere (羅:Sphaera armillaris)、東洋では渾天儀 (こんてんぎ / Hùntiānyí / 혼천의) と呼ばれています。

IoT渾天儀のしくみ

私の作った渾天儀は2個のモータで動き、地球上から見た太陽と星座の動きをシミュレートできます。それと太陽はLEDで光ります。

f:id:licheng:20211121142458j:plain:w640

2個のモータにはステッピングモータを使い、これをGR-ROSEから制御します。24BYJ48はユニポーラ結線のモータなので、バイポーラステッピングモータドライバのDRV8825で駆動するのは不適切な気がするのですが、いちおう回ります。(桃, 橙, 黄, 青をA1, A2, B1, B2に接続、赤は未接続)

連続回転するものに給電するのは意外と難しいことで、スリップリングという部品を利用しています。LEDへの給電のスリップリングは小型化のためにコンタクトプローブ(ポゴピン)を使って自作しました。

f:id:licheng:20211121142651j:plain:w533

天文計算のフローは下図の通り。日時と観測地点の経度・緯度から太陽と星座の位置を計算してモータの回転角に換算します。本当は緯度に応じて天球の傾きもモータ駆動で変化させたかったのですが、機構的に難しいため今回は手動としました。

f:id:licheng:20211121142717j:plain:w533

この天文計算のC++クラス化をGitHubで公開しています。

IoT渾天儀の動作

夏至の日には太陽は双児宮から天蟹宮に入り、もっとも高い軌道を通ります。

f:id:licheng:20211121142745j:plain:w533

冬至の日には太陽は人馬宮から磨羯宮に入り、もっとも低い軌道を通ります。

f:id:licheng:20211121142759j:plain:w533

北緯35度では夏と冬でこれだけ太陽の高さが違うんですね。東京や大阪がだいたいこの北緯35度付近です。

黄道十二宮双児宮、天蟹宮、人馬宮、磨羯宮はそれぞれ、ふたご座、かに座、いて座、やぎ座に相当しますが、実際の星座の位置とは約1月ずれています。これは黄道十二宮が成立した二千数百年前と現代とでは地球の歳差運動によって自転軸の向きが変化しているためです。

IoT対応

肝心のIoTをやる時間があまりありませんでしたが、いちおうAzure IoT Central には対応しました。デバイス定義はコマンド1個だけで、日時と経度・緯度を指定するとそれに従って渾天儀が動き、計算結果の太陽の黄経・赤経赤緯を返します。

f:id:licheng:20211121142917j:plain:w640

それだけではちょっと寂しいので、REST APIを使って自前のWebアプリからもコマンドを呼んでみました。

f:id:licheng:20211121135315p:plain:w324

REST APIの使い方に関しては、公式のドキュメントに解説があります。

しかし、認証処理のところで出てくるトークンていうやつが、何のことやら分からなくて手こずりました。

要するに、IoT CentralのWebページの 管理 → APIトークン → 新規 で生成したトークンなる文字列を、HTTPリクエストヘッダのAuthorizationヘッダで指定しなければならないということらしいです。Web系の人にはこんなの常識なのかもしれませんが、組込み系の自分にはチンプンカンプンでした。

f:id:licheng:20211121160438p:plain

この文字列は秘密の文字列なので、フロントエンドに丸見えでは意味が無いように思われます。なのでAPI中継サーバを作成しました。詳しくは下記の記事に書きました。

今後の展望

というわけで今回はここまでですが、さらにブラッシュアップして、いつの日かリアルイベントが展示できるようにしたいと思ってます。

【課題】

  • モータの初期位置出し、現在は手動 → フォトセンサで自動化
  • メカの強度と精度がプラダンでは足りない → CADで設計してMDF製に
  • IoT対応もうちょっとしっかり → Azureの勉強からします

デモ動画

実際に渾天儀が回転しているデモ動画です。デモ用に4日で1年の動きにしています。
(地球が4回自転する間に1回公転すると仮定した場合の動きです。)

発表資料

Raspberry Pi Picoの2つのArduinoサポートを比較

Raspberry Pi PicoはArduino環境で開発することもできる。Raspberry Pi Pico用のボードサポートパッケージはArduino公式版以外にフィルハワー伯爵版(?)なるものが存在するようだ。

公式版はMbedの上にArduinoの皮かぶせたちょっとやっつけ仕事気味なかんじなのに対して、伯爵版はC/C++SDKベースで作られておりむしろ公式版よりしっかりしてるように感じる。詳しく見てみよう。

f:id:licheng:20211127164900j:plain:w500

Arduino公式版

Arduino公式でサポートしているため、「追加のボードマネージャのURL」を設定する必要は無い。ボードマネージャで pico と入力すれば Arduino Mbed OS RP2040 Boards というのが見つかるので、これをインストールする。するとボードの選択メニューに Arduino Mbed OS RP2040 Boards が追加される。

インストールされたパッケージのソースを覗いてみよう。
Winsowsなら %LOCALAPPDATA%/Arduino15/packages/arduino/hardware/mbed_rp2040 にある。

どうもMbed OSの上にArduino APIのラッパーをかぶせているようだ。ちょっと雑な作りのように感じる。利点としてはMbedのAPIをスケッチから直接呼び出すことも可能だが、それなら最初からMbedで開発すればいいじゃないかと思う。Mbedのマルチスレッド機能(Threadクラス)は使えないようだ。

また、Servo, EEPROM, SoftwareSerial といったおなじみのライブラリが使用できない。特にServoをサポートできないはずがないのでちょっと手抜きではないかと思う。

C/C++SDKAPIをスケッチから直接呼び出すことも可能だ。Mbed OS自体がC/C++SDKをベースに移植されているので、まあ当然と言える。C/C++SDKAPIを使えばデュアルコアを活用した並列処理は可能なようだ。(multicore_launch_core1関数)

Earle Philhower版

もう一つのサポートは Earle F. Philhower, III氏が公開しているものだ。 冒頭でフィルハワー伯爵と書いたが、Earleは伯爵(Earl)ではなくてファーストネームか。アール・F・フィルハワー3世、いったい何者だろう?

こちらは「追加のボードマネージャのURL」にURLを追記する必要がある。

https://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json

ボードマネージャで pico と入力すれば Raspberry Pi Pico/RP2040 というのが見つかるので、これをインストールする。するとボードの選択メニューに Raspberry Pi Pico RP2040 Boards が追加される。もちろん、公式版とは共存可能だ。

インストールされたパッケージのソースを覗いてみよう。
Winsowsなら %LOCALAPPDATA%/Arduino15/packages/rp2040/hardware/rp2040 にある。

こちらはC/C++SDKベースに作られている。C/C++SDKAPIをスケッチから直接呼び出すことももちろん可能だ。また、setup1()loop1() という関数を書けばコア1で実行される。setup()loop() はコア0で実行されるので、これによって並列処理が簡単に書ける。

また、公式版では使えなかった Servo と EEPROM がこちらでは使える。SoftwareSerialは使えないが、まあ個人的には要らないと思っている。ちなみにハードウェアシリアル通信は、SerialがUSBシリアルで、Serial1Serial2がUARTとなる。

気になるのが個人による開発という点で、今後ちゃんと保守されるのかという心配はある。しかしすでにかなり広く使われているようである。また、前述の通りそもそも個人の趣味と思えないような仕事である。アール・F・フィルハワー3世、いったい何者だろう?

所感

まだ実際に動かしてみたわけではないのだが、ソースをざっと眺めたかぎりでは伯爵版に軍配を上げたい。(もう伯爵版と呼ぶことにする。) 共存可能なので両方インストールしてしばらく様子を見ることにする。