M5stackをVS codeで使う(1)

Arduino IDEはコンパイル遅いし、使い慣れたVS codeの方が良さそうに見えるので、VS codeで環境構築。コアとなる拡張機能はPlatformIOになります。

参考サイトは以下の通り、

https://haratta-tech-lab.com/m5stack-intro-arduino-vscode/#toc12

https://fabcross.jp/category/make/sorem5/20210112_cat_robot.html

ライブラリは画像中のワークスペースではなく、PlatformIO管理下に配置されるようです。この例ではM5Stack.hとSimpleBeep.hを組み込んでいますが、必要になればPlatformIOのライブラリ管理で必要なライブラリを追加すれば良さそうです。実はライブラリ管理は少々複雑のようですが、まずは必要なら都度追加で問題はないでしょう。

コンパイル速度はArduino IDEよりも明かに高速化しているように思う。

 

admin

 

Montereyから導入のコマンドラインでネット速度を計測できるコマンド

% networkquality

==== SUMMARY ====                                                                                         

Upload capacity: 220.748 Mbps

Download capacity: 291.286 Mbps

Upload flows: 16

Download flows: 12

Responsiveness: High (2364 RPM)

最後のResponsiveness1分間で何回やりとり可能かということだろうから、秒換算でおよそ40回だからping相当で12ms程度ということになる。nuro以外だとこの数字が落ちるんだろう。

 

admin

Arduinoのプロジェクトディレクトリ変更

Macの書類ディレクトリにArduino関連のライブラリやスケッチを入れてましたが、M5stack関連をインストールしたらiCloudの残り容量がなくなったのでディレクトリを変更しました。

Arduino — preferencesの設定メニューにディレクトリ指定があるので、元のディレクトリを丸ごとiCloudのバックアップ対象外にコピーすれば大丈夫でした。

移動先はユーザディレクトリのルートに、

 

admin

初めてM5stack gray を使う

納品されたので、半分に分解してみた。左側部分には電池が入っていて、ある程度はバッテリー動作もできるようです。また、磁石も入っているようで、Macのトラックパッドに吸い付きます。

9軸センサーの機能確認は追々ですが、まずはArduino IDEでM5stackの疎通を確認します。

参考サイトは、

https://qiita.com/hmmrjn/items/2b2da09eecffcbdbad85

①〜④はマストで、⑤は動作確認用、初めてM5stackに電源つないだときは自己診断プログラムが走りますが、sdカードは入っていないのでエラーになりました。

① M5stack用のUSBドライバーインストール

ちなみに接続はUSB type-cなのでArduinoとは異なります。ごく短いtype-cケーブルが添付されてますが、実用上は短すぎると思うので別の長めのケーブルを使った方が良いと思います。

② Arduino Core for ESP32のインストール

③ ボードとシリアルポートの選択

チェックしたように選択、ボード種類とコード書き込み用のポート設定です。

④ ライブラリのインストール

必要になれば入れれば良いと思うけど、必須そうなものをとりあえず入れてみた。

⑤ サンプルプログラムの動作

ここではスピーカの機能を確認するプログラムを書き込みしてみました。コードを見るとボタンが押された時にボタン毎に異なるトーンの音が出るようになってますが、音階の正しさはともかく異なるトーンの音が出ました。

 

admin

Rubyの進捗

見返すと、10月下旬に買った本ですが、進捗は8割ぐらいで残りは第8章の「オブジェクトとクラス」。

Rubyは他の言語(Java, c# etc)と印象が違うのはLisp系(関数プログラミング言語)の影響を受けているからなのかとようやく理解してきた感じです。

Ruby

おそらくRubyに馴染むと他の関数プログラミング言語にも取っ付きやすいんじゃないかと思う。

 

admin

Visual Studio CodeでArduino環境

たまたまVSCode開いたら、Arduino拡張機能をおすすめされている。

調べてみると、MicroSoftのプラグインは実は裏ではArduino IDEをそのまま使っているらしいけど、Arduino IDEよりもVS Codeの方がエディタとしても使いやすいと思うから移行かな。

 

admin

Arduino MKR WiFi 1010のVin電圧の規格

以下のリンクの公式ドキュメントによると5.5V、しかしどこかには6V以上という記載もあったので、バッテリー充電制御のICの規格を当たってみる。

https://docs.arduino.cc/static/fc77c3c3c77d69764ba7773df64c99db/ABX00023-datasheet.pdf

使用しているのはBQ24195Lなので仕様を見てみると、

https://www.tij.co.jp/product/jp/BQ24195L

最大定格で17Vだから10V以下なら余裕ということになる。NiHの5直だと初期は7Vぐらいになるから確認のために。

 

admin

Arduino MKR WiFi 1010のWi-Fiファームウェアアップデート

サンプルプログラムの版数チェックで版数上げろと言われるのでアップデート。

処理プログラム自身をArduinoに書き込んで実行します。

手順は以下に記載ありますが、

https://support.arduino.cc/hc/en-us/articles/360013896579-Check-and-update-the-firmware-for-WiFiNINA-and-WiFi101

要はArduinoメニューから、

WiFiNINA Firmware Updaterを選択して、

Updaterの指示に従えばうまくいきました。

 

admin

FreeRTOSのタスク遷移とタスク間通信

FreeRTOSでタスクのコントロールとタスク間通信ができれば、当面のやりたい事はできるようになります。

1. タスク遷移図

http://happytech.jp/wordpress/2017/02/25/rtos-for-iot-mcu-task-control/

に分かりやすい図があったので借用。

タスク中で時間待ちdelay()させてもタスクは実行権は手放さないので、他のタスクは動作できず、設定した時間だけ停止状態に入るvTaskDelay()関数が必要になります。この場合のEventとはタイムアウトになりますね。

 

2. タスク間通信

いろんな手法が存在しますが、queueを使うのが一番使いやすそうなので使ってみます。queueとは分かりやすく言えばFIFOです。最も軽量で使えるのはTask Notificationsのようですが、汎用性はqueueのほうがあります。

① queueの作成

1行目のxQueueCreate()でqueueの作成(定義)を行います。

QueueHandle_t xQueue = xQueueCreate( 10, sizeof( unsigned long ) );

最初ループ処理の内側に入れてたので、メモリが枯渇してMalloc errorが出ました。領域確保は当然一回だけ必要です。

② 送信側

14行目のxQueueSend()でqueueにデータを送り込みます。

xStatus = xQueueSend(xQueue, &SendValue, 0);

 

③ 受信側

47行目のxStatus = xQueueReceive()でqueueからデータを取り出します。

xStatus = xQueueReceive(xQueue, &ReceivedValue, xTicksToWait);

 

QueueHandle_t xQueue = xQueueCreate( 10, sizeof( unsigned long ) );
void threadA( void *pvParameters ) 
{
  int32_t SendValue = 0;
  BaseType_t xStatus;
  SERIAL.println("Thread A: Started");
  while(1){
  //for(int x=0; x<100; ++x)
  //{
    //SERIAL.print("A");
    //SERIAL.flush();
    web_server();
    ++SendValue;
    xStatus = xQueueSend(xQueue, &SendValue, 0);
         if(xStatus != pdPASS) // send error check
         {
             while(1)
             {
                 Serial.println("rtos queue send error, stopped");
                 delay(1000);
             }
         }
    myDelayMs(2000);
  //}
  
  // delete ourselves.
  // Have to call this or the system crashes when you reach the end bracket and then get scheduled.
  //vTaskDelete( Handle_bTask );
  }
  SERIAL.println("Thread A: Deleting");
  vTaskDelete( NULL );
}

//*****************************************************************
// Create a thread that prints out B to the screen every second
// this task will run forever
//*****************************************************************
void threadB( void *pvParameters ) 
{ 
  BaseType_t xStatus;
  int32_t ReceivedValue = 0;
  const TickType_t xTicksToWait = 500U;
  SERIAL.println("Thread B: Started");

  while(1){
      distance=s_sensor();
      xStatus = xQueueReceive(xQueue, &ReceivedValue, xTicksToWait);

      //Serial.println("check if data is received");

      if(xStatus == pdPASS) // receive error check
         {
             Serial.print("received data : ");
             Serial.println(ReceivedValue);
         }
      else{
        Serial.println("No data available");
      }
      /*
         {
             if(uxQueueMessagesWaiting(xQueue) != 0)
             {
                 while(1)
                 {
                     Serial.println("rtos queue receive error, stopped");
                     delay(1000);
                 }
             }
         }
         */
    //SERIAL.println("B");
    SERIAL.flush();
    myDelayMs(500);
  }
}

動作させると以下のシリアルポート出力になります。queueに存在しなければ存在しないよと出力してます。既にthreadAとthreadBでwebサーバーと距離センサー機能の呼び出しをおこなっているので、実用的なマルチタスクに一歩前進。

モニタータスクはリソースの解放忘れなどのチェック用に開発期間中は削除できないでしょう。

 

admin