makecode for microbit

makecodeのうちでmicrobit用のバージョンがmake code for microbitになります。pxtという言葉も出てきますが、makecodeというのは目に見える画面エディタのことで、pxtはmakecodeを動かすためのGitHubのリソースのことだという記述があります。

https://github.com/microsoft/pxt-microbit

にmicrobit用のpxtリソースが存在しますが、このpxtリソースでできることは、

① makecode for microbitをローカルサーバーで動かす

② ローカルで開発環境を構築

の二つだと思います。

手順通り動かしてみると、ローカルでmakecode for microbitが立ち上がりました。

大半はTypeScriptで拡張機能が実現できそうですが、ハードウェアを扱うときにはC++も必要になるでしょう。

 

admin

Static TypeScriptはmakecode for microbitの拡張機能作成で使われる

makecodeはマイクロソフトが開発したオープンソースでユーザ側が自由に拡張できますが、その元になっている仕組みを調べ始め。ネット上には情報が少ないですが、

きっかけは、

https://interface.cqpub.co.jp/magazine/202202/

ですが、雑誌というのは決まった分量に収めないといけないので、行間が省略されているので、雑誌のテキストだけではよく理解できないので自分なりに理解のための整理。

makecodeで何ができるのか?

開発がマイクロソフトなので、① Arcade、② micro:bit、③ Minecraftができるということです。

makecodeの開発言語はStatic TypeScript、なぜStaticなのかというとメモリの少ないマイコンでJavaScriptの動作環境は用意できないからネーティブのコードに変換する、つまりJavaScriptが持つDynamicな機能は削除されたTypeScriptのサブセットなのでStaticという名前がつけられています。実はmakecodeの開発環境にはTypeScipt以外にBlocksとStatic Pythonも使われている(BlocksとStatic Pythonはコンパイル時にTypeScriptに変換される)ようです。Blockは” Blocks is implemented using Google Blockly.“だそうですが、ScratchもGoogle Blocklyを使っています。

<makecode用の言語についてのリンク>

https://makecode.com/language

一方pxtはStatic TypeScriptコンパイルの実行環境。

<pxtについてのリンク>

https://github.com/Microsoft/pxt

pxtの実行環境には三種類あるそうですが、

“PXT programs are executed in at least three different environments: microcontrollers, with native code compilation (ARM) browsers * server-side JavaScript engines (node.js, etc)”

実際的にはnode.jsを使うのが一番ポピュラーでしょう。

 

admin

 

Docker割り当てリソースの設定

VScode起動時にDockerも起動されるようになっているので、その都度8GBも消費するのは無駄だろうから割り当てを変えます。実メモリ16GBでDockerに8GB割り当ててしまうと、状況によってはメモリプレッシャがwarningレベルになります。4GBあれば当面十分だろうからDockerの設定画面で変更。

アクティビティモニターで見ると、

割り当てサイズが変更されました。

 

admin

 

倒立振子のループ時間が変わるとパラメータも修正必要

以下で作成した倒立振子、

https://isehara-3lv.sakura.ne.jp/blog/2022/12/30/倒立振子(pi制御でハンチングなくした)/

Wi-Fi環境無いところのために、Wi-Fi関連の処理(Pose情報をudpで送信)を削除すると、PIDパラメータの最適値が変わってきます。

モーターの駆動力を計算しているところをloop処理から切り出すと以下のような処理ですが、

  // calc motor power
  float Duty, P, D, now, dt, Time;
  now = TARGET - roll_data;    // calc delta
  if (-25 < now && now < 25) { if (abs(now) >= 0){
      Time = micros();
      dt = (Time - preTime)/1000000;
      preTime = Time;
      P = now/90; // (-90~90) → (-1.0~1.0)
      I += P*dt;
      D = (P - preP)/dt;
      preP = P;
      power = P_val * P + I_val * I + D_val * D;
      //Serial.println(power);
      if (power < -1) power = -1;    // limit the max value
      if (1 < power)  power = 1; 
      if (power < 0){
        dir = 1;
      }else{
        dir = -1;
        }               // set forward/reverse
    }

時間で正規化されてるわけでも無いから、powerの値そのものが変動してしまうからでしょう。

電池電圧変動でも同じpower指定しても実際のモーター駆動力は変化して、調整点がズレるのと似ていると言えば似ているかもしれません。

 

admin

micro:bitのLED表示時間が異常に長い件について

直前のブログでLED表示時間が異様に長い件、micro:bitのドキュメントにその理由と思われる記載がありました。

https://lancaster-university.github.io/microbit-docs/ubit/display/?fbclid=IwAR0ZlyEd0pQnAIEmQUUK_gUnD-jalUa-hzdmIHjCRyauOcIJwdLBerLbFyI

overviewの最後にある通り、

“In it’s normal mode, the display will update every 18ms (55 Hz). If the display is in light saving mode the period is changed to 15ms (66 Hz).”

18ms毎にupdateされるようなので、この時間がLED表示データ書き込み時間として見えて来ているようです。マルチタスク動作ではないだろうmicrobitのファームウェアでは。

 

admin

Micro:bitでライントレース

Arduinoベースの車では、簡単に軌跡を外れるので、Micro:bit carにセンサを外付けしてあたりを付けてみた。Arduino(VScodeのPlatformIO)ではmicro:bit(makecode)に比較して開発のループ時間が長くなるので。

3Dプリンタでアタッチメントを作成して、センサーを両面テープで貼り付けました。アナログ入力はP0とP2を使っています。

動きを遅くするために、モーターの動作時間を限定してフィードバックが確実にかかるようにしてやると『カメモード』ですがトレースできるようになりましたが、動かすにはパラメータが多いので調整は大変そうです。ましてP.I.D制御までやろうとすると。

makecodeのコードは以下に、

https://github.com/chateight/trace_microbit

2023/5/18 LED表示に時間が掛かっている

LED表示にステータス、前進/右旋回/左旋回の数字を表示させるだけで数十ms必要で制御が間に合わなくてコースアウトしていたので、LED表示を削除して『ネズミモード』ぐらいまで高速化、展開時のモーター駆動にはP制御も追加しました。P制御の原理はフォトトランジスタの読み取り差をモーター駆動力にリニアに反映(下限と上限は決めていますが)しています。

 

admin

 

自走車にライントレース機能を付加する(センサー編)

ライントレースはロボット構成の基本要素なので、一度はやってみます。

一年半前に作った自走車(超音波センサーで障害物回避)にライントレース機能を付加するのが便利そうなのでそれでやります。

センサーは、

https://resources.kitronik.co.uk/pdf/56111-kitronik-move-line-following-board-datasheet.pdf

ですが、フォトダイオードと光センサートランジスターを組み合わせた出来合いのモジュールを使います。電源電圧3V時に黒で3V、白で0Vが出力されます。

取り付け位置は中央ネジで3Dプリンタで造形したアタッチメント経由で取り付けの予定。

ラインマットとセンサーの距離が重要だろうから、事前にM5Stack使って距離を決めてやります。

<黒>

<白>

 

もちろん白黒で理想的に0Vや3Vにはならないから、ダイナミックレンジが取れそうなところで距離を設定します。どちらにしても近すぎても(シートに接触するぐらいに知るとかえってダイナミックレンジは悪化)遠すぎても(もちろん反射光を拾うのが動作原理なので論外)いけません。

で、概ね5mmあたりが適切のようです。

P.S. 2023/5/11

ArduinoのADCで読み込むと黒と白の値が反転してます。なぜだろう?

 

admin

Dockerにデフォルトで割り当てるメモリサイズ

あまり気にしたことはなかったのですが、Dockerに割り当てられるメモリが少な過ぎれば当然動いて欲しいものも動かないということになりますが、メモリサイズを指定しないでDockerを起動して割り当てられるメモリサイズを確認してみました。

条件はM1MacBook Airでメモリは16GBです。

# free
              total        used        free      shared  buff/cache   available
Mem:        8040052      436668     6207184      352068     1396200     7070628
Swap:       1048572           0     1048572

アクティビティモニターで見ても確かに8GB割り当てられているので、デフォルトではおそらく物理メモリサイズの半分が割り当てられるようです。Linuxで普通に使っていて何ら問題になりそうもないサイズです。

現実的には実メモリが8GBあればDockerの動作に問題は無いというのが一般的な記事に書かれていることですが、それだとデフォルトでおそらく4GB割り当てられてMac側が4GBでは他のアプリの動作が厳しくなりそうですからVMにしろDockerのようなコンテナにしろ実メモリが多くて困ることはありません。

 

admin

 

Goのアップデート

すでに2月に1.20になっていますが今さら。homebrewでインストールしているので、

% brew upgrade go

で1.19 -> 1.20へ、

==> Running `brew cleanup go`…

で1.19は関連ファイルが削除されます。

$GOROOTを確認すると、

% go env GOROOT
/opt/homebrew/Cellar/go/1.20.3/libexec

1.20にupgradeされました。$GOROOTはこのように自動的に更新されるので、直接手を入れる必要はないようです。以上はcuiモードで有効で、VScodeだと、以下のGo xxをクリックすれば、インストール済みの版数の選択あるいは新規ダウンロードができます。

 

admin

ラズパイ用チャットアプリ再構成

チャット機能は以下の記事の通り独立モジュールとして開発していましたが、

https://isehara-3lv.sakura.ne.jp/blog/2023/04/28/ラズパイにチャット機能を追加/

mifareカードアプリと分ける必要もなくなったので統合しました。ソースコードのリンクは以下になります。

https://github.com/chateight/myfare-copy

修正箇所は、router.goの以下の2行と、myfareのブラウザ画面からのリンクボタン追加とmain.goからの呼び出し(以下のコード切り出し)の追加。

r.Static(“/static”, “./go_chat/view/static”)
r.LoadHTMLGlob(“./go_chat/view/*.html”)
Static/LoadHTMLGlob()のリンクディレクトリ呼び出しは、Run()を起動したmain.goが基準になるのでそこからの相対ディレクトリに変更、関連処理のmain.goからの呼び出しを移動しただけです。
<main.go部分>
func main() {
	// to call card reader function()
	go uidSerial.SerialMain()

	// chat data base create and make table to store chat messages
	sql_db.DbCreate()
	// start chat service
	go chat.Run()
	
	// start myfare card service
	wevServer()
}

 

admin