外部ライブラリ
基本操作
マイクロコントローラに接続されているデバイス,またはマイクロコントローラ自体において,既存のライブラリを使いたいこともあるだろう.
そのようなライブラリは,MicrocontrollerEmbedCode[…,<|…,"Libraries"->paths,…|>]という形で"Libraries"特性にパスを指定することで使用することができる.
デバイス用の外部ライブラリのコードは,入力または出力のチャンネルをタイプ"ExternalLibrary"とし,追加のチャンネル指定をサブオプションとして加えると,生成されたコードとともに差し込むことができる.したがって,外部ライブラリの機能を使用する入力または出力チャンネルは"ExternalLibrary"-><|libkey1->val1,…|>のように指定する.
ライブラリがマイクロコントローラ自体で使用される場合は,外部ライブラリのコードの指定はMicrocontrollerEmbedCode[sys, <|…,libkeyi->valuei,…|>,…]のようにマイクロコントローラの第2引数で指定しなければならない.
外部ライブラリのためのキー libkeyi は,プログラムのどの部分に外部ライブラリコードを差し込むのかを指定するもので,以下のものがある:
| "IncludeFiles" | インクルードするファイル |
| "Definitions" | マクロの定義 |
| "Declarations" | 関数宣言 |
| "Utilites" | ユーティリティ関数・変数 |
| "Initializations" | プログラムの初期化 |
| "Loop" | 各サンプリング時点で実行する |
| "PreLoop" | "Loop"の前に実行する |
| "PostLoop" | "Loop"の後に実行する |
| "UntimedLoop" | プロセッサが解放されているときに繰り返し実行する |
Pololuライブラリの例
PololuのZumoロボットには押しボタンとブザーがある.またそれらとインタラクトするためのライブラリも提供されている.Arduino用のライブラリをインストールする標準的な手順に従うと,提供されたArduinoの例が実行できるようになり,正しく動作していることが確認できる.
この例では,フォルダPushButtonおよびZumoBuzzerの中身だけが必要である.ここでは,これらのフォルダの場所はファイルシステムのどこでもよい.
lib = Table[FileNameJoin[{$HomeDirectory, "Documents", "Arduino", "libraries", f}], {f, {"Pushbutton", "ZumoBuzzer"}}];incls = {"<Pushbutton.h>", "<ZumoBuzzer.h>"};utils = {"ZumoBuzzer buzzer", "Pushbutton button(ZUMO_BUTTON)"};ボタンのライブラリには,ボタンが押されているかどうかを確認するのに使用できる isPressed 関数がある.ライブラリを使って,ボタンの状態に応じて
か
が得られる.
l = {"button.isPressed()?1:0"};
ic = "ExternalLibrary" -> <|"Loop" -> l|>;系は入力をそのまま通す.そのため,sys の出力も
か
である.
sys = StateSpaceModel[{{}, {}, {}, {{1}}}, SamplingPeriod -> 0.1, SystemsModelLabels -> None, ExternalTypeSignature -> "uint8_t"];ブザーライブラリには指定された音を鳴らすことができる playNote 関数がある.音はライブラリのヘッダファイルで定義される.出力は変数 playQ に設定され,音は sys の出力が
の場合にのみ鳴らされる.
l = {"uint8_t playQ", "if(playQ){buzzer.playNote(NOTE_E(5),100,15);}"};oc = "ExternalLibrary" -> <|"Loop" -> l|>;コードが埋め込まれたら,ブザーはボタンが押されるたびに鳴るようになる.
Needs["MicrocontrollerKit`"]MicrocontrollerEmbedCode[sys, <|"Target" -> "ArduinoUno", "Inputs" -> ic, "Outputs" -> oc, "IncludeFiles" -> incls, "Utilities" -> utils|>, "/dev/tty.usbmodem14101", <|"Libraries" -> lib|>]Arduinoライブラリの例
Arduino言語には擬似乱数を生成するための random という関数がある.前の例と同様にライブラリの場所とその他のコード各部を指定する必要がある.
lib = FileNameJoin[{$RootDirectory, "Applications", "Arduino.app", "Contents", "Java", "hardware", "arduino", "avr", "cores"}];ic = "ExternalLibrary" -> <|"IncludeFiles" -> "Arduino.h", "Loop" -> "random(-10,11)"|>;ℳ = MicrocontrollerEmbedCode[StateSpaceModel[{{}, {}, {}, {{1}}}, SamplingPeriod -> 0.1, SystemsModelLabels -> None], <|"Target" -> "ArduinoUno", "Inputs" -> ic, "Outputs" -> "Serial"|>, "/dev/tty.usbmodem14101", <|"Libraries" -> lib|>]これで,デバイスフレームワークを使って値を読み込むことができる.
parse[d_] := With[{res = ToExpression@FromCharacterCode@Rest@d},
Which[NumericQ[res], res, True, Nothing]]dv = DeviceOpen["Serial", "/dev/tty.usbmodem14101"]y = {};
task = SessionSubmit@ScheduledTask[
If[DeviceExecute[dv, "SerialReadyQ"], AppendTo[y, parse[DeviceReadBuffer[dv, "ReadTerminator" -> ℳ["Serial"]["EndByte"]]]];
DeviceExecute[dv, "ReadFlush"]]
,
0.1
];TaskRemove[task];
DeviceClose[dv]Histogram[y, 20]FindDistributionParameters[y, UniformDistribution[{min, max}]]