とりちらかったもろもろの言葉たち

ちょっと大きめのつぶやきにすぎない戯言をとりあえず書いてみました

カテゴリーアーカイブ: 電子工作

Machinistにデータを送ってみるテスト

某紙のコラムのネタにするので、IIJの「Machinist」をちょいと使ってみた。データロガー的な使い方が簡単にできるサービスだ。

簡単に言ってしまえば、IoTデバイスなどのデータをJSONのパケットに組み立てて、Machinistに対してHTTPSでPOSTしてやればずんずん積もっていくというもの。基本は時間ごとのデータしか取れないのでまあ何でも格納できるというわけではないが、センサーが発したデータや機器のステータスなどを放り込んでおくにはいいのではないかと思う。

普通ならまあ、ラズパイあたりを使うところなのだろうが、これくらい単純なものならむしろESP32を使うくらいのほうがリアルだし実践的だろうと思ったので試してみた(あ、そもそもWindows 10のbashからは試していたんだった)。

用意したのは適当にAliExpressかeBayかで購入した、Node-32コンパチの安物。今はArduinoで使えるようにしているので、そのままArduinoでスクリプトを組むことにした。一応ESP32には内蔵の温度センサーがあるらしいので、これを送ればそれなりになるかという目論見で本体のみである。

まず調べるのは温度のとり方だが、どうやら怪しいようではあるがこういうところがあったのでそれを使って動かしてみた。OK。値はベロベロでようわからんが、まあ動いている。

次はそれをJSONのパケットにするのだが、ヒアドキュメントが使えないのでだるい‥と思って一瞬microPythonに乗り換えようかとも思ったが、考えてみればJSONくらいArduinoでも扱う方法があるだろうと探したら、やっぱりあった。いくつかあるようだが、とりあえず今回使ったのはArduinoJsonである。

これでゴリゴリ組み立ててシリアライズすればいいわけだが、意外と面倒なのが本当に正しくできているのかの検証。ArduinoJsonの場合、いろいろと見ていたらAssistantというページがあって、サンプルのJSONを放り込んだらシリアライズするプログラムを自動生成してくれる。これがありがたかった。

おかげで温度チェックのあと、HTTPとJSONを入れ込んだスクリプトが一発で動いた。正確にはArduinoJsonのページで警告しているように、標準のライブラリアンでデフォルトを使うとベータ版が入ってしまうこと。Assitantのページで生成するのはその前の安定版用なので、ライブラリの入れ替えは必要だった。あと相変わらずプログラムの転送が安定していないので3回くらいやり直したのが面倒だった。

というわけでコードはこんな感じ。なんかインデントが変だけどわかるでしょ。

#include <WiFi.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>

const char SSID[] = “<Your Wi-Fi SSID>”;
const char PASSWORD[] = “Wi-Fi PWD”;
const char URL[] = “https://gw.machinist.iij.jp/endpoint&#8221;;

extern “C” {
uint8_t temprature_sens_read();
}

void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
pinMode(LED_BUILTIN, OUTPUT);
WiFi.begin(SSID, PASSWORD);
Serial.print(“WiFi connecting”);

while (WiFi.status() != WL_CONNECTED) {
Serial.print(“.”);
delay(100);
}
Serial.println(” connected”);
}

void loop() {
if(WiFi.status()== WL_CONNECTED){ //Check WiFi connection status

HTTPClient http;

http.begin(URL); //Specify destination for HTTP request
http.addHeader(“Content-Type”, “application/json”); //Specify content-type header
http.addHeader(“Authorization”, “Bearer <Your API Key>”);

char buffer[256];
const size_t bufferSize = JSON_ARRAY_SIZE(1) + JSON_OBJECT_SIZE(1) + 2*JSON_OBJECT_SIZE(2) + JSON_OBJECT_SIZE(3) + JSON_OBJECT_SIZE(4);
DynamicJsonBuffer jsonBuffer(bufferSize);

JsonObject& root = jsonBuffer.createObject();
root[“agent”] = “ESP32”;

JsonArray& metrics = root.createNestedArray(“metrics”);

JsonObject& metrics_0 = metrics.createNestedObject();
metrics_0[“name”] = “temperature”;
metrics_0[“namespace”] = “Environment Sensor”;
JsonObject& metrics_0_tags = metrics_0.createNestedObject(“tags”);
metrics_0_tags[“FLOOR”] = “1F”;

JsonObject& metrics_0_data_point = metrics_0.createNestedObject(“data_point”);
metrics_0_data_point[“value”] = temperatureRead();

root.printTo(buffer, sizeof(buffer));
Serial.println(buffer);

int httpResponseCode = http.POST(buffer); //Send the actual POST request

if(httpResponseCode>0){
String response = http.getString(); //Get the response to the request
Serial.println(httpResponseCode); //Print return code
Serial.println(response); //Print request answer
}else{
Serial.print(“Error on sending POST: “);
Serial.println(httpResponseCode);
}
http.end(); //Free resources

}else{
Serial.println(“Error in WiFi connection”);

}
digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level)
delay(500);
digitalWrite(LED_BUILTIN, LOW); // turn the LED on (HIGH is the voltage level)

delay(1000);
}

マイルストーン:スマホでカメラ台を制御

Project Chasing Moonとか言ってしまったが、そのマイルストーンその1。

2016-04-16 20.28.45スマートフォンのアプリで、指定した角度に首を振り、チルトさせるというもの。コントローラーは例によってLightBlue Beanにした。今回は細かく指定できることを確認するため、専用のアプリも作成した。

基本はBluetooth Low EnergyのCharacteristicに角度(アジマスとチルト)を書き込むと、それに応じてカメラ台のサーボが対象の角度に動く。サーボの制御はArduinoのServoライブラリ任せなので、本当にどの角度なのかは確認していない。が、まあそれらしい角度には動いている。後々のために、LightBlue Beanから加速度センサーの値をCharacteristic経由で取得できるようにもしている。

動かすとこんな感じだ。

ポイントはサーボが5V、LightBlue Beanが3Vで動作するのを整合させることくらい。もしかしたらサーボの制御ピンはCMOSロジックだったのかもしれないけど、SG90の説明はなんにも書いてないのでまあレベル変換は入れておいた。CMOSロジックで動いているといいな。何となく、ちょっと動作が不安定な感じがあるので。本当は波形の確認とかしなきゃいけないんだけど、まあそれも次のステップかな。

もう一つポイントだったのはアプリの方だけど、今回はBluetooth Developer Studio(BDS)を使ったら簡単にできた。基本はLightBlue BeanのCharacteristicをやり取りするサービスのUUIDを使ってBDSでプロジェクトを立ち上げる。これで標準のプラグインを使って、Androidのクライアントコードを生成させる。同じ名前、名前空間でAndroid Studioのプロジェクトを作っておけば、BDSで生成した中に入っているバッチファイルがソースを放り込んでくれる。Javaのソースコードだけではなく、XMLのデザインファイルなども入れてくれるので、実行可能なアプリがその場でできてしまう。

あとはデータをやり取りする構造(プロトコル)を決めて適切に処理させればいい。

 

FreeSoC2とかいう開発キットでLチカまでの道

ETでCypress Semiconductorが配っていたSparkFunのPSoC5LP開発ボード。日本語の情報はあんまりないみたいだし、意外と動かすまでに手間だったのでメモ。まあぶっちゃけSparkFunが公開している文書を読めばわかるっちゃわかる。英語だけど結構丁寧に書いてあるし。

Arduino IDEの準備をする

まずArduino IDEが1.6.4以降が必要。とりあえず今ダウンロードすると、1.6.6になる模様。ウチのMac/PCには1.0.6までしか入れてなかったので、入れ替える必要があった。

それからハードウエア情報の追加。ARMプロセッサー対応を取り込む必要がある。まずArduino IDEのコンパイラーでCortex-M3のコードを生成できるようにする。これは比較的簡単で、「ツール」メニューの「ボード」項目を選ぶとリスとされるボードの中にある、「ボードマネージャー」を選ぶ。そうすると、使うボードのグループみたいなものだなこれは。Cortex-M0のコンパイラーとかボードとかもここで追加できる。本来はこのリストの中に「FreeSoC2」というのがはいるべきだし、そうしたいみたいだが、まだそこまではできていないという状況だ。

ボードマネージャー

次に、githubのリポジトリから、PSoCのサポートファイルをダウンロードする。zipファイルなのでこれを展開して、そのなかにある「Hardware」フォルダーをArduino IDEの「スケッチブックの保存場所」にコピーする。Hardwareフォルダーがすでにある場合は、中身を追加すればよい。これでようやく、ボードとしてSparkFunの「PSoC Dev Board」が選択できるようになる。

Arduinoのブートローダーを書き換える

さて、ここからが問題だ。ここで試しにUSBケーブルを「Target」に指してみても、シリアルポートドライバーが認識してくれない。「USBUART」という謎のデバイスがつながっていることになっている。

まあまずは、こいつをダウンロードしておく。Windowsのドライバーとか入っているくさいのでインストール。しかしCypress PSoC Programmerをインストールしてもとりあえずドライバーは認識しない。ドキュメント通りに「Debugger」ポートにつないでみるが、こちらもいろいろと謎のデバイス状態になっている。

これはとりあえずドライバーをインストールしてしまおう。C:\Program Files (x86)\Cypress\Programmer\driversフォルダーにインストール用のバッチファイルがあるので、これを実行してみる。これでDebuggerポートに接続した状態では謎デバイスがなくなったが、相変わらず「Target」は認識しない。

たぶんここが問題で、Arduino用のBootloaderを書き換えてやらなければいけないのだろう(と、この時点では思っていた。実際は違うことが後から判明した)。

ドキュメントに従い、ここで「PSoC Programmer」を起動する。あれ?認識してない。起動する前に接続していたせいかもしれないので、一度USBケーブルを抜いてから挿し直す。これで認識した。

Programmer1

これで「File」-「Open」でPSoCのサポートファイルにある「D:\Documents\Arduino\Hardware\SparkFun\psoc\bootloader.hex」を開く。ファイルを開くアイコンの隣にある「Program」ボタンをクリックすると、ブートローダーが書き込まれる。

これで認識するかと思いきや、「ドライバーはD:\Documents\Arduino\Hardware\SparkFun\psocにある」ときたもんだ。なので、このブートローダー更新作業をしなくてもホントは認識して作業できんじゃね?みたいなことは試していない。

さてドライバーをインストールしてめでたしめでたし…かと思いきや、落とし穴が待っていた。Arduino IDEが「コンパイルエラー」となる。

arm-none-eabi-gcc: error: C:\Temp\build9c9ef3bdfe2fccb480bc6e4bac749e41.tmp/core.a: No such file or directory

確認すると、確かにそこに「core.a」ファイルはない。テンポラリフォルダーの「core」フォルダーの下になら存在する。しかたがないので、ハードウエア情報の定義ファイルというか、platform.txtを書き換えた。D:\Documents\Arduino\Hardware\SparkFun\psoc\platform.txtを開いて「core」を検索すると、1カ所見つかる。その「core.a」を「core/core.a」と書き換えたら、無事コンパイルできて、スケッチもアップロードできた。これは定義ファイルだからとりあえず処置としては正しいのだけど、なんかそのうち引っかかるかもしれないので、備忘録としても公開しておこう。

 

 

ミニリノセロス改造の解説?

某京都大学のセンセイが「解説求む!」というので、ちょっと書いてみたり。

ミニリノセロスの動きがかな~りノンビリしていたので、うちわで扇ぐのに疲れてしまい、電動化を決意した。で、どうせなら単にモーター付けるだけじゃつまらないので、スマホでリモコン化しようと考えたわけだ。考えてみれば、これはゴールデンウィークの工作だったのだから、半年近く「鋭意制作中」だったわけだ。

基本コンセプトは「無改造」。ミニリノセロス側には何も手を入れない。だって手を入れて電動オンリーにしたら、なんかせっかく「風を食べる生物」感がなくなっちゃうし。ということでまず考えたのが、どうやって駆動するか。まあマブチモーターだよね。だったらまあArduinoじゃ駆動できないよね。などと考えて、次のような結論に落ち着いたわけだ。

temp1

見つけたのはDRV8832。データシートを見たら、まあコンデンサーをどう使えばいいのかまではわからないけど、とりあえず抵抗2本もあれば±3Vとか出せそうだというのが読み取れたので、抵抗値とか適宜計算したりして、電気的な計画はほぼ即日で終了。5月7日の投稿はこのあたりまでの作業。

問題は物理的な取り付け方法だったりするのだけれど、結局適当な方法も思いつかなかったので、しばらく放置。まあ使えそうなものを、ということで、ギアボックスとプラバンなどをゲット。これが5月14日にアマゾンでオーダーしているから、このあたりは割と素直に進んでいるな。一番悩んだのはモーターの回転系をどう連結させるかなんだけど、これはミニリノセロスを手動で動かすためのパーツを見て、「ああ、これで行けそう」と感じた。要はゴムチューブで連結させるんだけど、幸いなことに、たまたま受け側の形状が似ていたからこれで接続できた。3Dプリンターとかあれば、こう言うのを悩む必要がなくていいんだけど。で、ギアボックスを組み立てたところでしばし中断。このときはまだ、取り付け方法を思いついていなかった。

次は電子部品の手配。秋月のページで見ると大きさがわからないよね。実際には、とても小さくてこのままじゃ工作なんてできそうにない。幸いなことに、秋月では2.54mmピッチで引き出してくれた基板付きの製品を扱っていたので、そちらを購入した。抵抗とコンデンサーも適当に。これいつ買ったんだっけなぁ。たぶんセミナーの準備とかのついでに行ったから、たぶん6月19日とかそんなもんじゃないかな。

ここまでやって、しばし完全に放置。取り付け方は、まあ結局プラバンからつり下げるようにすればいいだろうと思ったのだけど、ちゃんと測って…とかが面倒だったんだろうなぁ。たぶん。

ようやく9月のシルバーウィークで、いいかげん宿題を片付ける気になって、つり下げ用のネジ類を手配したりした。

そして9月26日に取り付け確認。10月4日に電動化完了というのがこれまでの経緯。

電子回路の構成はこんな感じ。

temp2

まあ要するにただのデジタルOut2本で制御するだけなので、Bluetoothでいきなり制御できればそれでOKだったわけだ。ところがハンダ付けの失敗の結果、使用モジュールを変更したのでBLE制御になった。BLEではホストとデバイスの間で任意のデータをやり取りするのに「Characteristic」を使う。Arduino側は0.1秒間隔でCharacteristicをチェックし、その値で「前」「後」「停止」の3状態に対応させる。ホスト側はBLEに対しCharactersiticを書き込むことで操作する。Characteristicを書き込むのは、LightBlueアプリが使えるのでこれで実現したと。

えっと、たぶんこの最後の話さえあれば十分だったのではないかという気がする。