2018年5月5日土曜日

[ESP32][AWS][IoT][Micropython]MQTT接続してPublish/Subscribeしてみる

Micropythonの公式v1.9.3のままだと証明書ありのSSL接続が未実装状態だったというオチがあって、3日ほど格闘してようやく解決。。

コミュニティのやり取りを見てると、ここの認証回りの修正は当分先な気がするので、自前パッチをあてるのがよさそうです。
(ESP-IDFのバージョンも最新のを使いたいとかもあるし、いっそのことまとめてやっちゃえ!w)


ってことで修正して動作確認。


#SSL接続import socket, ssl
s=socket.socket()
addr=socket.getaddrinfo("www.yahoo.com", 443)[0][-1]
s.connect(addr)
client=ssl.wrap_socket(s)


#MosquitoのブローカーにPublish(証明書なし)
import ssl
import socket
from mqtt import MQTTClient
MQTT_CLIENT_ID = "12341234"
MQTT_HOST      = "192.168.1.2"
MQTT_PORT      = 1883
client = MQTTClient(client_id=MQTT_CLIENT_ID, server=MQTT_HOST, port=MQTT_PORT, keepalive=10000, ssl=False)
client.connect()
client.publish("test", "ok")
client.disconnect()

#MosquitoのブローカーにPublish(証明書あり)
kw = {}
kw["cacert"]          = cacertdata
kw["cert"]            = certdata
kw["key"]             = keydata
kw["cert_reqs"]       = ssl.CERT_REQUIRED
kw["server_hostname"] = MQTT_HOST
kw["server_side"]     = False
client = MQTTClient(client_id=MQTT_CLIENT_ID, server=MQTT_HOST, port=MQTT_PORT, keepalive=10000, ssl=True, ssl_params=kw)
client.connect()
client.publish("test", "ok")
client.disconnect()


#Subsctibeしてみる


def sub_cb(topic, msg):
    print((topic, msg))

client = MQTTClient(client_id=MQTT_CLIENT_ID, server=MQTT_HOST, port=MQTT_PORT, keepalive=10000, ssl=True, ssl_params=kw)
client.connect()

client.set_callback(sub_cb)
client.subscribe("foo_topic")

client.wait_msg()
又は
client.check_msg()



これらが上手く実行できていれば問題ないと思います。

2018年5月2日水曜日

[Mycropython][ESP32]HTTPのSSL接続を行う

証明書を使ったSSL接続はエラーが出て出来てないけど
MicropythonでHTTPS接続は出来たのでメモ


import ussl as ssl
import usocket as socket
s=socket.socket()
ai=socket.getaddrinfo("google.com", 443)
addr=ai[0][-1]
s.connect(addr)
s=ssl.wrap_socket(s)
s.write(b"GET / HTTP/1.0\r\n\r\n")
print(s.read(4096))
s.close()

2018年4月28日土曜日

[ESP32]Window上でmicropythonをビルドする(デュアルコア対応化)

ESP32ってデュアルコアなのにビルド済みのMicropython for ESP32はシングルコアしか使っていないのが分かった。。(2018年4月時点)
なので自前ビルドを実践する事にした。


Step1.環境一式ダウンロード
https://esp-idf.readthedocs.io/en/latest/get-started/windows-setup.html
600MB弱のファイルをダウンロードして任意のフォルダに展開する。
例:D:\msys32


Step2.環境構築
d:\msys32\mingw32.exeを起動
$ cd
$ mkdir -p esp
$ cd esp
$ mv esp-idf esp-idf.old
$ git clone --recursive https://github.com/espressif/esp-idf.git


Step3.micropythonのコードをクローン
$ pacman -S python2
$ curl https://bootstrap.pypa.io/get-pip.py
$ python get-pip.py
$ pip install pyserial

$ mv /mingw32/bin/envsubst.exe /mingw32/bin/envsubst.exe.del
$ pacman -S gettext
2$ vim ~/.profile
最後の行に
 export IDF_PATH=~/esp/esp-idf
 export ESPIDF=$IDF_PATH
を追加。
$ source ~/.profile

$ git clone --recursive https://github.com/micropython/micropython.git
$ git clone --recursive https://github.com/micropython/micropython-lib.git
https://github.com/micropython/micropython/blob/master/ports/esp32/mpthreadport.c
の136行目
TaskHandle_t id = xTaskCreateStaticPinnedToCore(freertos_entry, name, *stack_size / sizeof(StackType_t), arg, priority, stack, tcb, 0);
これを
TaskHandle_t id = xTaskCreateStaticPinnedToCore(freertos_entry, name, *stack_size / sizeof(StackType_t), arg, priority, stack, tcb, 1);
にする。

※Windowsだとシンボリック問題が発生するので、置換マクロ組んで全部置き換えました。。


Step4.ビルド開始
$ cd ~/esp/micropython/ports/esp32
$ make

★ここでHASHが異なるからビルドできないってエラーメッセージが表示されたら
ハッシュコードの部分は出力メッセージのに書き換えて
$ cd ~/esp/esp-idf
$ git checkout 3ede9f011b50999b0560683f9419538c066dd09e -b micropython
$ git submodule update

$ cd ~/esp/micropython
$ make -C mpy-cross
$ cd ~/esp/micropython/ports/esp32
$ make
$ make erase
$ make deploy

消去や書込めない場合、
$vim Makefile
ポート名は/dev/ttyS0 
など、各自環境に合わせて要調整。




諦めてビルド済みのを使う場合は、


ここからバイナリイメージをダウンロードしてきて書込み実行。

$ easy_install -U pip
$ pip install esptool
$ esptool.py --port /dev/ttyS0 --baud 460800 write_flash --flash_mode dio --flash_size=detect 0x1000 esp32-20171006-v1.9.2-276-ga9517c04.bin


追記:
Ubuntu on Windows 上で環境構築した場合、
Makefileの設定で

ポート名は、/dev/ttyS1 = COM1になります。
通信速度はデバイスマネージャに記載した通信レートを指定します。


以上!

2018年4月24日火曜日

[FreeRTOS]現在アクティブのタスクハンドラ・タスク名を取得する。

色々と検索すると古い情報だったり、カーネルをカスタマイズしないといけないとか
情報が散乱していて良く分からない状態だったのでまとめます。

結局は英語も良く分からないから、分からないなりに読めるソースコードを頼りに調べました。

タスクハンドラはTaskTCBのポインタになっているようですが、
Task.cに構造体が定義されていて直接参照したりすることができないようになっています。
構造体の部分を抜き出すやり方も検討しましたが、
最終的にはAPI関数のみでやる方法で落ち着きました。

現在のタスクハンドラを取得する方法
TaskHandle_t handle = xTaskGetCurrentTaskHandle();


タスクハンドラからタスク名を取得する
char* taskname = pcTaskGetName(handle);


これ知っておけばタスク間をまたぐような処理で
自タスクなのか他タスクなのかが判別できるようになりますね。

2018年4月21日土曜日

レディプレイヤーワン良かった

 スピルバーグ作品といえばやっぱり「激突!」
激突はトラックが永遠と追いかけてきて、振り切ったかと思っても
「またあのトラックあるやん!」って
見てる側もハラハラドキドキさせてくれる作品だったことを思い出します。
あれから色々な作品を世にだして巨匠となりますが
2000年以降は低迷続きでもう大作は難しいのかなって思ってた矢先に出してきたSF作品。
彼の思い描いている強烈な映画感を色濃く出してきた上に
80年代からの有名作品全部入り!
いくら映画好きでも昔の作品はまったく知らないし、
そういうのをいろんなシーンに挿入されてても元ネタが分からないんだよねー
それって「ラ・ラ・ランド」もそうだったじゃん!という人でも
アクション好きであればOKですw
全部入りシリーズは大体は不作に終わるジンクスがあると個人的に思っていましたが
久々にぶっ飛ばしてきましたね。

2018年4月17日火曜日

WindowsにAmazon Alexaをインストールする

本記事はalexa-avs-sample-appを動かすメモです。

2018年4月現在は、MSYS2上にインストールする方法がありますので
そちらを参照するといいかもしれません。

【元記事】

【修正するファイル】・samples/companionService/config.js
・samples/javaclient/config.json
・samples/javaclient/pom.xml
・samples/javaclient/ssl.cnf


ではスタートです。

Step1.Amazon developerにログインしてAVSデバイスを追加
ProductID、ClientID、ClientSecretキーを取得する。


Step2.サンプルプログラムをダウンロードする。
例:c:\project\alexsaフォルダに展開する場合、
DOSプロンプト上でクローンするフォルダに移動してから
> c:
> cd \project
> mkdir alexsa
> cd alexsa
> git clone https://github.com/alexa/alexa-avs-sample-app.git


Step3.依存アプリのインストール
・VLCをインストール http://www.videolan.org/
 環境変数に登録する
 例:
  環境変数名:VLC_PATH
  パス:C:\Program Files(x86)\VideoLAN\VLC

・Node.jsをインストール
 https://nodejs.org/en/download/


・Movenをインストール
 https://maven.apache.org/download.cgi
 ※環境パスを登録する事
 例:JAVA_HOME=C:\Program Files\Java\jdk1.8.0_162


Step4.SSL証明書を生成する
・OpenSSLをインストール
 http://slproweb.com/products/Win32OpenSSL.html
環境変数「Path」に「Bin」フォルダを登録する。
例「C:\tool\OpenSSL-Win64\bin」
・[C:\project\alexa\alexa-avs-sample-app\samples\javaclient]を編集する
YOUR_****の部分を全て変更する
countryName = JP
stateOrProvinceName = Tokyo
localityName = Nakano-Ku
organizationName = NA
organizationalUnitName = NA

・DOSプロンプト上でGenerate.batを起動する。
ここで適当な
プロダクトID、シリアルナンバー、パスワードを入力する。
例:
ProductID:Dispatcher
SerialNumber:123456
Password:1234
ちゃんとうまく証明書が生成できれば
「1 個のファイルをコピーしました」
というのが表示される。

・設定ファイルに生成した証明書の参照パスを設定する。

「c:\project\alexa\alexa-avs-sample-app\samples\companionService\config.js」を開き、
 sslKey: 'C:\\project\\alexa\\alexa-avs-sample-app\\samples\\javaclient\\certs\\server\\node.key',
 sslCert: 'C:\\project\\alexa\\alexa-avs-sample-app\\samples\\javaclient\\certs\\server\\node.crt',
 sslCaCert: 'C:\\project\\alexa\\alexa-avs-sample-app\\samples\\javaclient\\certs\\ca\\ca.crt',
 "products":"Dispatcher" : ["Dispatcher"],
を入力する。


「C:\project\alexa\alexa-avs-sample-app\samples\javaclient\config.json」を開き、
    "productId":"Dispatcher",
    "dsn":"123456",
    "provisioningMethod":"companionService",
 "clientId":"*********",
 "clientSecret":"*********",
 "locale":"ja-JP"
 "sslKeyStore":"C:\\project\\alexa\\alexa-avs-sample-app\\samples\\javaclient\\certs\\server\\jetty.pkcs12",
 "sslClientKeyStore":"C:\\project\\alexa\\alexa-avs-sample-app\\samples\\javaclient\\certs\\client\\client.pkcs12",
 "sslClientKeyStorePassphrase":"1234",
 "sslCaCert":"C:\\project\\alexa\\alexa-avs-sample-app\\samples\\javaclient\\certs\ca\\ca.crt"


「clientID」「clientSecret」は最初のAVS登録時の情報で
「sslClientKeyStorePassphrase」は証明書作成時に入力したパスワードになります。
「products」はKey:Value型になっていて
 KeyはAVS登録時のProductIDで、
 ValueはSSL証明書作成時に入力したProductIDになります。


「C:\project\alexa\alexa-avs-sample-app\samples\javaclient\」を開き
17行目付近にある部分を下記のように編集
8.1.12.v20180117


・AndroidスマホにAmazonAlexaアプリをインストールする
 https://play.google.com/store/apps/details?id=com.amazon.dee.app&hl=ja&rdid=com.amazon.dee.app


Step5.ビルドと実行、そしてNode.jsサーバによる認証
Dosプロンプト上で
> c:
> cd project\alexa\alexa-avs-sample-app\samples\companionService
> npm install
> npm start
別のDosプロンプト上で
> c:
> cd project\alexa\alexa-avs-sample-app\samples\examples\javaclient
> mvn validate
> mvn install
> mvn exec:exec
を実行する。
これでJAVAアプリが起動する。
クラウドとやり取りするのは1つめのコンパニオン
GUIは2つ目のjavaアプリ
という2構成になっています。



ブラウザで「https://developer.amazon.com/lwa/sp/overview.html」を開き
最初に作成したAVSデバイスを選択して
Consent Privacy Notice URLは暫定のURLでも張り付けておく。

cd project\alexa\alexa-avs-sample-app\samples\companionService


【インストール時に引っかかった事】
設定ファイルで未記入の所でエラー。(エラーが出なくなるまで項目を埋めていった)
Jsonファイルの構文にひっかかった。(\\が2つになっていない箇所があった)
JAVAコンパイラが見つからなかった(パスの問題)
VLCのバージョンが32bitでDLL読込み失敗した(64bitのものにインストールし直した)
Localhostを127.0.0.1に直さないと動かない。


【まとめ】
以上の手順をこなせば、Alexaが動作する所まで確認できます。

構成は、
GUIがフロントエンド(JAVA)で
バックエンド(Javascript)にコンパニオンがいます。

動作の流れは、
GUIからログインを行うと、コンパニオンを仲介してAWSにアクセスして認証を通します。
Amazonアカウントのログイン完了後、
OKであればシークレットキーが届いて、これでアレクサと接続状態になります。
ダメな場合は400とかエラーコードが返ってきます。

接続状態の時にアレクサに話しかけてAlexsaスキルを発動すると、
対応する接続中のデバイスに対してNotificationが届きます。

これでESP32でLチカとかもできちゃいますね!

2018年3月27日火曜日

人工知能の限界について思う事

今日は人工知能の限界についてふと感じた事をメモします。

最近はディープラーニング技術によって人工知能ブームが再来しました。
人工知能を突き詰めるとデータの統計処理でクラスタリングして無数のデータからパターンを見つける事が出来る。つまりデータマイニングの自動化。

データの中から次の傾向を導き出すのが得意であって、ある過程を前提に次の手を予測するものではないところがポイントです。

今まで囲碁AIなど人間に勝てるものがあるのですが、
これはルールありきで次の手はどれが良いか評価値を算出できて明確である事が絶対条件。

裏を返せば、ルールなきフロンティアを開拓するのは人間がやるべきことで
データ統計処理はAIに任せた方が良いという事になります。


もし仮に人工知能が人のような振る舞いをするようになったり、人では考えられなかった新しいアイデアも出せるAIが出たとします。
さらに身近で作業してくれるロボットが誕生したとします。

次の壁にぶつかるのは、センサ技術

ロボットが麻薬捜査犬の代わりができますか?
きっとできないよねー。
技術的な壁にぶち当たった時、次にどうするか。

機械と生物が融合するハイブリッド型の強化人間とか強化犬とか、、

もしくは遺伝子操作された特化型生物、、

結局ロボットはモノであって生き物に到底かなわないから
生物にインプラントして脳や生体信号をIoTしていくんだろうなと思いました。

2017年11月4日土曜日

[Arduino]Keyes_CNC基板のgrblファームを書き込む

GRBLファームの書き方

3軸動かせるCNCシールドを買ったのはいいけど、ファームが入っていない事態が発生。。

自分で書き込まないといけないからどうやるのか調べてみました。

必要なもの
grbl controller(2014年で更新が止まっているのでv0.8用)
UGS(grbl controllerの後継)


【ファーム書込み編】
Step1.上の2つをダウンロードします。
ソースコードはArduino/liblaryフォルダに展開します。
フォルダ1つ開いたらソースコードになるようにしてください。

Step2.ArduinoIDEを使ってgrblファームをアップロードする。

nano版は[cpu_map.h]を一部修正があります。

修正箇所「cpu_map.h」

アップロードする時は、
 ファイル→スケッチ例→grbl→grblUpload
を選んでアップロードします。



Step3.Arduino IDEを起動してシリアルモニターを起動して、「$」を送信。
「$」送信した後「$$」送信した図


応答があればファーム書き換え成功。

その次にUGS起動。
注意する事といえばボーレート設定を「115200」にすることくらい。


他の資料ですが、必要な時に参照できるように下に置いておきます。

【日本語マニュアル】


【ジャンパー説明】
ジャンパー設定(オープンでLOW)

【設定一覧】

$0=10 (ステップパルス, μ秒)
$1=25 (ステップアイドル時間, m秒)
$2=0 (ステップポート反転マスク:00000000)
$3=6 (方向ポート反転マスク:0000110)
$4=0 (ステップ有効反転, bool)
$5=0 (リミットpin反転, bool)
$6=0 (探針pin反転, bool)
$10=3 (状態リポートマスク:00000011)
$11=0.020 (接続偏差, mm)
$12=0.002 (円弧寛容性, mm)
$13=0 (リポートインチ, bool)
$20=0 (ソフトリミット, bool)
$21=0 (ハードリミット, bool)
$22=0 (ホーミングサイクル, bool)
$23=1 (ホーミング反転マスク:00000001)
$24=50.000 (ホーミングフィード, mm/min)
$25=635.000 (ホーミングシーク, mm/min)
$26=250 (ホーミング非跳ね返り, msec)
$27=1.000 (ホーミングpull-off, mm)
$100=314.961 (x, step/mm)
$101=314.961 (y, step/mm)
$102=314.961 (z, step/mm)
$110=635.000 (x 最大レート, mm/min)
$111=635.000 (y 最大レート, mm/min)
$112=635.000 (z 最大レート, mm/min)
$120=50.000 (x 加速, mm/sec^2)
$121=50.000 (y 加速, mm/sec^2)
$122=50.000 (z 加速, mm/sec^2)
$130=225.000 (x 最大移動量, mm)
$131=125.000 (y 最大移動量, mm)
$132=170.000 (z 最大移動量, mm)

【エラーリスト】

  "error:1"  : _("G-code words consist of a letter and a value. Letter was not found."),
"error:2"  : _("Numeric value format is not valid or missing an expected value."),
"error:3"  : _("Grbl '$' system command was not recognized or supported."),
"error:4"  : _("Negative value received for an expected positive value."),
"error:5"  : _("Homing cycle is not enabled via settings."),
"error:6"  : _("Minimum step pulse time must be greater than 3usec"),
"error:7"  : _("EEPROM read failed. Reset and restored to default values."),
"error:8"  : _("Grbl '$' command cannot be used unless Grbl is IDLE. Ensures smooth operation during a job."),
"error:9"  : _("G-code locked out during alarm or jog state"),
"error:10" : _("Soft limits cannot be enabled without homing also enabled."),
"error:11" : _("Max characters per line exceeded. Line was not processed and executed."),
"error:12" : _("(Compile Option) Grbl '$' setting value exceeds the maximum step rate supported."),
"error:13" : _("Safety door detected as opened and door state initiated."),
"error:14" : _("(Grbl-Mega Only) Build info or startup line exceeded EEPROM line length limit."),
"error:15" : _("Jog target exceeds machine travel. Command ignored."),
"error:16" : _("Jog command with no '=' or contains prohibited g-code."),
"error:20" : _("Unsupported or invalid g-code command found in block."),
"error:21" : _("More than one g-code command from same modal group found in block."),
"error:22" : _("Feed rate has not yet been set or is undefined."),
"error:23" : _("G-code command in block requires an integer value."),
"error:24" : _("Two G-code commands that both require the use of the XYZ axis words were detected in the block."),
"error:25" : _("A G-code word was repeated in the block."),
"error:26" : _("A G-code command implicitly or explicitly requires XYZ axis words in the block, but none were detected."),
"error:27" : _("N line number value is not within the valid range of 1 - 9,999,999."),
"error:28" : _("A G-code command was sent, but is missing some required P or L value words in the line."),
"error:29" : _("Grbl supports six work coordinate systems G54-G59. G59.1, G59.2, and G59.3 are not supported."),
"error:30" : _("The G53 G-code command requires either a G0 seek or G1 feed motion mode to be active. A different motion was active."),
"error:31" : _("There are unused axis words in the block and G80 motion mode cancel is active."),
"error:32" : _("A G2 or G3 arc was commanded but there are no XYZ axis words in the selected plane to trace the arc."),
"error:33" : _("The motion command has an invalid target. G2, G3, and G38.2 generates this error, if the arc is impossible to generate or if the probe target is the current position."),
"error:34" : _("A G2 or G3 arc, traced with the radius definition, had a mathematical error when computing the arc geometry. Try either breaking up the arc into semi-circles or quadrants, or redefine them with the arc offset definition."),
"error:35" : _("A G2 or G3 arc, traced with the offset definition, is missing the IJK offset word in the selected plane to trace the arc."),
"error:36" : _("There are unused, leftover G-code words that aren't used by any command in the block."),
"error:37" : _("The G43.1 dynamic tool length offset command cannot apply an offset to an axis other than its configured axis. The Grbl default axis is the Z-axis."),
"error:38" : _("An invalid tool number sent to the parser"),

"ALARM:1" : _("Hard limit triggered. Machine position is likely lost due to sudden and immediate halt. Re-homing is highly recommended."),
"ALARM:2" : _("G-code motion target exceeds machine travel. Machine position safely retained. Alarm may be unlocked."),
"ALARM:3" : _("Reset while in motion. Grbl cannot guarantee position. Lost steps are likely. Re-homing is highly recommended."),
"ALARM:4" : _("Probe fail. The probe is not in the expected initial state before starting probe cycle, where G38.2 and G38.3 is not triggered and G38.4 and G38.5 is triggered."),
"ALARM:5" : _("Probe fail. Probe did not contact the workpiece within the programmed travel for G38.2 and G38.4."),
"ALARM:6" : _("Homing fail. Reset during active homing cycle."),
"ALARM:7" : _("Homing fail. Safety door was opened during active homing cycle."),
"ALARM:8" : _("Homing fail. Cycle failed to clear limit switch when pulling off. Try increasing pull-off setting or check wiring."),
"ALARM:9" : _("Homing fail. Could not find limit switch within search distance. Defined as 1.5 * max_travel on search and 5 * pulloff on locate phases."),

"Hold:0" : _("Hold complete. Ready to resume."),
"Hold:1" : _("Hold in-progress. Reset will throw an alarm."),
"Door:0" : _("Door closed. Ready to resume."),
"Door:1" : _("Machine stopped. Door still ajar. Can't resume until closed."),
"Door:2" : _("Door opened. Hold (or parking retract) in-progress. Reset will throw an alarm."),
"Door:3" : _("Door closed and resuming. Restoring from park, if applicable. Reset will throw an alarm."),




Androider