2020年2月16日日曜日

ESP-IDF v4をWindowsのVS Codeで使いやすくしてみる(PlatformIOなし)

https://blog.nyancotech.online/2020/02/windowsesp32esp-idf.html
の続きです。
WindowsでESP-IDF v4環境の構築は上記ページをご覧ください。

まずは普通にインストールされたESP-IDF Command Promptを開きます。



Using Python in C:\Users\admin\AppData\Local\Programs\Python\Python37\
Python 3.7.3
Using Git in C:\Program Files\Git\cmd\
git version 2.25.0.windows.1
Setting IDF_PATH: C:\Users\admin\esp\esp-idf
この部分をメモっておきます。


VS CodeでESP-IDFディレクトリを、「フォルダを開く」から開いたあと、
左下の歯車ボタンから設定を開きます。


Workspaceタブを選択し、Terminal欄をクリック、Edit in settings.jsonをクリック


{
    "terminal.integrated.shellArgs.windows": [
        "cmd",
        "/k",
        "..\\.espressif\\idf_cmd_init.bat",
        "C:\\Users\\admin\\AppData\\Local\\Programs\\Python\\Python37\\",
        "C:\\Program Files\\Git\\cmd\\"
    ]
}
ここに上のJSONを環境に合わせて変更して入力後保存します。
..\\.espressif\\idf_cmd_init.bat

の行には、インストールした.espressifディレクトリ内の
idf_cmd_init.batへのパスを入力してください。
自分は

esp- .espressif
     L esp-idf
というディレクトリ構成にしているので
カレントディレクトリのesp-idfディレクトリから見ると
..\.espressifが.espressifの場所になってます。
Python37というのが書いてある行は、
初めにESP-IDF Command Promptで表示されていた
「Using Python in...」の右に書いてあるディレクトリを入力します。
Git\\cmdというのが書いてある行は、同じく
「Using Git in...」に書かれている行を入力します。

それぞれパスの区切り文字はエスケープ文字として認識されてしまうので、
\\と2つ続けて入力してください。




settings.jsonを保存して、Terminal->New Terminalでターミナルを開くと、
VS CodeからESP-IDF Command Promptが使用できます!
idf.py flash -p COM10とかやればこの画面のまま書き込みまでできます!


2020年2月15日土曜日

【令和最新版】WindowsにESP32開発環境ESP-IDFをインストールする

これまでESP32の開発環境はUnixシェル用のものしか用意されておらず、 Windowsではmsysを使って実行する方法が公式で紹介されていました。 そんな中、最近になって、Espressif純正の一括インストーラが出ていたので試してみました。
https://docs.espressif.com/projects/esp-idf/en/latest/get-started/windows-setup.html

ダウンロードしたexeファイルを開き、インストールしていきます。


必要なパッケージをインストールしてくれますが、Pythonやgitなど、
すでに入っているものがあればそれを選択することで
新しくインストールすることなく進むことができます。
よくできてますね


ESP-IDFのレポジトリをすでにダウンロードしてあれば
そのディレクトリを使うことができます。



ESP-IDFをダウンロードする場合はバージョンを選択できます。
使用するコンポーネントの互換性の問題などがなければ、
4.0を選んだほうが後々アップデートする手間を減らせるかもしれません。


ツールチェーンやPythonの仮想環境を保存する先を選択します。


一発でESP-IDF用のターミナルを開くショートカットを
スタートメニューやデスクトップに登録できます。


各種設定が完了するといよいよインストールです。


ESP-IDFレポジトリはとても大きいのでダウンロードに時間がかかります。



しばらくして、インストールができ…


ませんでした。

表示されたログを見ると、Python virtualenvに
--no-site-packeagesなんてオプションないよと言われています。


はてさてexeファイルの中身に入ってるんだろうしどうしたものかと調べていると、
修正版が出ていました。
下のほうに直リン貼ってる人がいます。




気を取り直してやり直し。


インストールできました。


Pythonのパッケージは専用の環境としてインストールされ、
PATHもシステム標準のものではなく専用のPATHが設定されるようです。
ほかの開発環境と競合せずに動いてありがたいですね。
早速esp-idf\examples\get-started\hello-worldディレクトリで
make menuconfig相当の"idf.py menuconfig"をしてみると…
なんかUnicodeDecodeErrorとか言われています…。


ちょっとぐぐったらこんなすばらしいコピペで動きそうな記事を発見

最近のUnicodeDecodeError

.espressif\python_env\idf4.0_py3.7_env\Lib\site-packages\sitecustomize.py
に上記記事のように
import builtins
__original = open
def __open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None):
    if 'b' not in mode and not encoding:
        encoding = 'utf-8'
    return __original(file, mode, buffering, encoding, errors, newline, closefd, opener)
builtins.open = __open

と記述したファイルを置き、標準のopen関数を上書きしてあげます。


すると…

うーんなんか周り文字化けてるけどとりあえず動いた!



このように、Espressif Systems様が提供してくださっている
Windows版インストーラにより、

簡単にWindowsでの開発環境が作れました!

(正直これでも今までよりは楽だと思います)

あとはメモですが
idf.py menuconfig
でmenuconfig
Serial flusher configでフラッシュの設定ができたりします。
idf.py makeでビルド
idf.py flash -p COMxxでCOMxxポートに接続されたESP32へ書き込み
idf.py monitor -p COMxxでシリアルモニタ(トレースバック付き)
monitor中に
Ctrl+T -> Ctrl+Shift+Fで再書き込み

2019年11月16日土曜日

ROHM BP35A1 ローム製Wi-SUN通信モジュールを使ってスマートメーターにBルート接続する

TwitterでM5StickC用にRohmのBP35A1を取り付けるアダプターを
作っておられる方がいて、BOOTHで購入できたので買ってみました。


サンプルコードも配布されていますが、開いてみるとMicroPythonだったので、Arduinoのスケッチを書いてArduinoで使ってみました


そもそもBルートとはなにか?
電力会社の設置している、各家庭にある電力量計は、アラゴの円板を使っていたアナログのものからデジタル化されています。
デジタル化されたメーターは、サブギガ(920MHzあたり)を使う無線で通信ができるようになっています。

なんのために無線通信できるのか?
毎月の検針を、検針員がメーターを直接読み取らなくても手元のプリンターで積算電力量を受信して印刷できます。
植栽や建物の密集度の関係上検針しにくい住宅や、集合住宅などでは集合ポスト前で一括受信・印刷することができるのだと思います。検針員はとても省力化できると思います。実際のところ、電波の到達距離も大したことがないため、どのような運用をしているのかはわかりません。
また、遠隔で電力供給の休止を行えるとされています。

これらはすべて電力会社が電力の使用を監視・制御するための通信で、Aルートと呼ばれています。
今回の話題であるBルートは、需要家(ユーザー)ごとにスマートハウスのようなHEMS機器とスマートメーターを直接無線接続して、使用電力のマネジメントなどを行うための仕組みです。

現在の使用電力量や各電力機器の動作状況をHEMS機器同士で共有することで、効率的に電力の使用ができるとされています。

今回使ったモジュールはこのようなHEMS対応機器を開発するための通信モジュールです。

スマートメーターと通信モジュールをBルート接続して使うためには電力会社にBルート接続用ID、パスワードを発行してもらう必要があります。
東京電力の場合、スマートメーター化されていない電力量計であっても、ID発行の申請を行うことでスマートメーターへの切り替えも行えるようです。(要工事)

BP35A1はUARTでシリアル通信コマンドを使って制御します。
公式のコマンドリファレンスは日本語ですが、この手のモジュールを使ったことがないと、読んでも心が折れそうだと思います。

ざっくりとした流れとしては

Bルート接続用ID/パスワードを設定
スマートメーターの電波をスキャン
スキャン結果からスマートメーターの接続情報を調べる
スキャン結果の接続情報を接続先として設定
接続開始・完了
電力取得コマンド送信
結果受信

と、初期化シーケンスがいろいろあってめんどくさいです。
とりあえずシリアルターミナルで手打ちして接続までいけるようにこれら一連の流れをメモしておきます。
上記のWi-SUN HATの場合、ピンを下にして裏面を向けて、
左側のピンから
GND/NC/NC/TX/RX/NC/3.3V/NC
というピン配置になっているため、電源とUARTを接続すればUSBシリアル変換などを使って使うこともできます。
115200bps 3.3VのUART 改行コード\r\nです。

以下コマンドでスマートメーターの接続までを行います。

Bルートのパスワードを設定
SKSETPWD C passwordhere

BルートのIDを設定
SKSETBID idhere

アクティブスキャンを実行
SKSCAN 2 FFFFFFFF 6

結果が返ってくる
EVENT 20 FE80:0000:0000:0000:xxxx:xxxx:xxxx:xxxx
EPANDESC
   Channel:31
   Channel Page:09
   Pan ID:ABCD
   Addr:xxxxxxxxxxxxxx
   LQI:93
   PairID:00E79995
 EVENT 22 FE80:0000:0000:0000:xxxx:xxxx:xxxx:xxxx


取得したスマートメーターのアドレスをIPv6アドレスに変換
 SKLL64 xxxxxxxxxxxxxx  //Addrの値
 FE80:0000:0000:0000:xxxx:xxxx:xxxx:xxxx

チャンネルを設定
SKSREG S2 31  //Channelの値

Pan IDを設定
SKSREG S3 ABCD  //Pan IDの値

接続開始
SKJOIN FE80:0000:0000:0000:xxxx:xxxx:xxxx:xxxx  //IPv6アドレスに変換後の値

EVENT 25が来ると接続成功です。
私は当初、EVENT 24で接続失敗しかしなかったのですが、
東電のフォームでパスワードを変更依頼したところ、以降つながるようになりました。
以前のパスワードではスマートメーターの設定がうまくできていなかったのかもしれません。

接続完了後、電力取得のコマンドを送信します。

SKSENDTO 1  FE80:0000:0000:0000:xxxx:xxxx:xxxx:xxxx 0E1A 1 000E
000Eのあとに半角スペースを入れて、続いてバイナリで
{0x10, 0x81, 0x00, 0x01, 0x05, 0xFF, 0x01, 0x02, 0x88, 0x01, 0x62, 0x01, 0xE7, 0x00} + \r\n
を送信すると瞬時電力が取得できます。

成功すると
ERXUDP FE80:0000:0000:0000:xxxx:xxxx:xxxx:xxxx
FE80:0000:0000:0000:xxxx:xxxx:xxxx:xxxx 0E1A 0E1A xxxxxxxxxxxxxxx 1 0012 xxxxxxxxxxxxxxxxxxxxxxxxxxxx000000BA
のようなレスポンスが返ってきます。
ここで見るのは最後の8桁、000000BAです。
これをそのまま10進に変換して、0xBA=瞬時電力186W
というような感じで読むようです。
上記サンプルコードでは、M5StickCで本体の液晶画面にこの数字を取得表示するようにしています。
Arduinoのスケッチなので、これを改良して、Wi-Fi経由でデータ送信して、
遠隔地から電力量を確認するような使い方も可能です。

それほど死ぬほど難しいわけではないですが、まだまだ情報量が少なく、
活用例も乏しいためもっと使う人が増えると楽しいのかなと思います。


2019年4月28日日曜日

ESP32をWi-Fi AP/イーサネットコンバーターにする(LAN8720使用)

最近になって、昨年公式githubに”eth2wifi”というサンプルが上がっているのに気づきました。
どうやらこれを使うと、有線LANをつないでWi-Fiアクセスポイントを立ち上げる
あるいはESP32がWi-Fiアクセスポイントに接続して、ESP32を介して有線LANの機器をLANに接続する
ということができるようです。1000円そこらでAPが作れるのは画期的です。

ESP32は、Wi-Fiの他に、物理層の部分以外Ethernetにも対応しています。
実際にEthernetを使うためにはEthernet PHY(フィジカル=物理層)
の回路が必要です。
よく知りませんが、通信用のクロックを作ったり、
信号レベルなどを有線LANの規格にあわせたりしてくれる回路なのだと思います。
これらの回路をESP32内部に入れるのはあまり使う人いないのに不毛ということで
物理層がはじめからは載っていないのだと思います。僕もそれでいいと思います。

調べるとEthernet PHYのICというものがいろいろ出ていて、簡単にブレークアウトボードに乗っているものが手に入るICとして、LAN8720がESP32ではよく使われているようです。

というわけで、LAN8720の載った基板をAliexpressで注文しました。
200円くらいで売っています。
https://www.aliexpress.com/item/1pcs-Smart-Electronics-LAN8720-module-network-module-Ethernet-transceiver-RMII-interface-development-board-for-arduino/32947407343.html?spm=2114.search0204.3.41.18a547acrOaaW9&ws_ab_test=searchweb0_0,searchweb201602_4_10065_10068_319_10059_10884_317_10887_10696_321_322_10084_453_10083_454_10103_10618_10307_537_536,searchweb201603_16,ppcSwitch_0&algo_expid=a53a62b5-87f4-46c8-8fea-e77569fc6b6b-6&algo_pvid=a53a62b5-87f4-46c8-8fea-e77569fc6b6b&transAbTest=ae803_5

届いたので、
冒頭のリンクのURLに書いてあるとおり配線しました。


 まあたくさん配線しないといけなくて、めんどくさいですがジャンパ線で直接接続のバラックです。
リンク先に注意書きが書いてあるのですが、
LAN8720ボードからのクロック出力をGPIO0に入力していますが、
ESP32の起動時にGPIO0がローに落ちていると、ファーム書き込みモードに入ってしまいます。
そこで、調べたら出てきた対策をします。
発振子の足をNCのピンに引き出して、GPIO17につなぎます。
GPIO17はコードの中でクロック出力の有効化・無効化をしてくれています。
こんなやり方でいいのか?という感じがしますがこれでうまくいきました。
基板を立ち上げるなら、トランジスタで電源ごと切ったりするほうが健全な気もします。



eth2wifiサンプルのディレクトリで、make menuconfigで動作の設定ができます。


僕が買ったボードのPHY Addressは1でした。
USE PHY Power pinにチェックが入っていると、PHY Power GPIOで制御ができます。
WiFi station modeにチェックが入っていると、イーサネットコンバーター
チェックを外すとAPになります。

実際通信してみましたが、CATV12Mではほぼ上限の値が出ていたので、実際にはもっと早いスピードで通信できると思います。
ツイッターを見ながらプライムビデオを流すくらいの使い方は余裕でできました。
本当に1000円そこらでAPを自作できるのはすごいですね。
2つ数珠つなぎにしてAP-イーサネットコンバーターとやれば中継機とかも組めそうです。
(それはもっとうまいやり方がありそうですが)

どうやってこれを実現しているのか?コードを見るととてもシンプルで驚きます。

static esp_err_t tcpip_adapter_sta_input_eth_output(void* buffer, uint16_t len, void* eb)
{
    if (ethernet_is_connected) {
        esp_eth_tx(buffer, len);
    }

    esp_wifi_internal_free_rx_buffer(eb);
    return ESP_OK;
}

Wi-Fiに受信バッファがあったらEthernetに送る
Ethernetに受信バッファがあったらWi-Fiに送るというような関数があります
シリアル通信のようなノリでこんなことができているのですね。
パケットをそのまま処理しているので、ESP32自身に宛てられたパケットを判別して処理するようなコードを書かないとESP32自身は通信ができないような気がします。
市販のAPのようにWebUIを実装したりするのは結構たいへんそうです。
ボタンを押しながら起動で別モードとして設定モードが立ち上がるような実装だと特に問題なく作れそうです。

2019年2月24日日曜日

M5CameraでGoogle Driveにアップロードする

結論というか、基本的にはこちらのブログがとてもためになるので読んでください

ESP32にWROVERというSPI RAM付きモデルが出て、大容量のRAMを使えるようになりました。
そこで、200万画素のCMOSセンサーが作る画像をバッファすることも容易になり、M5Stackシリーズを作っているメーカーから出ているM5Cameraをはじめとして、Omnivision OV2640が載ったESP32ボードが続々登場しています。

購入してすぐ、本体がSoftAPモードで立ち上がり、本体のWebサーバーにブラウザでつなぐとカメラの映像がストリーミングできるなどアツい展開になっています。
ただまあ、映像オタク的にはそれをやるなら別にネットワークカメラやWi-Fi付きデジカメのほうが画質もいいしいいじゃんということで、
マイコンにやらせるなら、実際にはなにかのトリガーで写真を撮ってどこかにアップロードさせたいみたいな用途のほうが強みが発揮できそうです。

そこで、M5CameraでGoogle Driveに写真をアップロードしてみました。

Google Driveは、Drive APIというものが用意されており、これを使うとRESTでファイル操作が可能になります。が、
一番冒頭にリンクさせていただいた、cURLでGoogle Driveにアップロードする方法をご覧いただくとわかるように、認証がやや面倒です。

簡単にまとめると
・APIを登録
・クライアントIDとシークレットキーを取得
・ブラウザでクライアントID付きの登録URLを開いて認証コードを取得(OAuth認証)
・認証コードとクライアントIDとシークレットキーをPOSTしてリフレッシュトークンを取得※
ここまでが初期設定です。

次からがファイルをPOSTするたびに行う操作です。
・リフレッシュトークンとクライアントIDとシークレットキーをPOSTしてアクセストークンを取得
・アクセストークンとファイル、ファイル情報をPOSTしてファイルをアップロード

※アクセストークンには有効期限があり、アクセストークンを取得するためのトークンがリフレッシュトークンです。
そのため、毎回リフレッシュトークンから有効なアクセストークンを取得する必要があります。

これらの操作をすべて行い、実際にM5Cameraで画像をアップロードするサンプルをArduinoで作ってみました。この例をちょっといじれば、カメラ画像以外にも、
ローカルのSPIフラッシュやSDカードに貯めたセンサーデータをまとめてCSVでアップロードするなど、ArduinoでGoogle Driveにファイルをアップロードできます。


さて、このサンプルを使う前にはGoogle DriveのAPIキーを取得する必要があります。
この操作がしょっちゅう画面構成が変わって、探してもやり方が見つからない場合があるので自分用にもメモしておきます。

Google Developers Consoleを開く


プロジェクトの選択をクリック


新しいプロジェクトを適当に作成


認証情報→OAuthクライアントID



同意画面を設定


名前を適当につけて保存


アプリケーションの種類:その他
名前適当で作成



クライアントIDとクライアントシークレットが取得できた。

あとはファームを入れ替えたM5Cameraを起動し、シリアルモニターを開くと、これらを聞いてきて、OAuth認証用コード取得URLが表示されるので、
要求されるコードを入力していくと、SPIフラッシュにそれらが保存されて次からは電源を入れるだけでGoogle Driveに写真を撮ってアップロードしてくれます。

2018年12月1日土曜日

ESP-IDFでESP32を開発するときにハマったこといろいろ

2021-01-04追記: 古い記事です。ESP-IDF v4系はだいぶ変わっています。

さて、エスプリのESP32がM5Stackの登場もありMaker界隈で大人気ですね
メーカーが作っているというArduino Coreもあり、お手軽に始めることはできるのですが、Arduino Coreを使うとメモリが足りなくなったり、細かいことをいじろうとすると
IDFの関数を直叩きしたりするので、じゃあ最初からIDFで作ろうよということで、
基本のSDKとして配布されている、ESP-IDFをぼちぼち使っていくことにしました。

正直まだ全然よくわかっていないのですが、とりあえず導入から。
自分が使っているマシンが基本Windows 10なので、Windowsに直に導入してもいいのですが、Windows Subsystem for LinuxにUbuntuがいるので、そこから使おうということで、
WSLから、↑のUbuntuの手順で導入しました。

導入したらとりあえずビルド。
サンプルを読んでもどこで何をしてるかさっぱりだったので一行ずつコメントつけたLチカのデモをgithubにおいておきました。

git clone して、プロジェクトルートでmake menuconfigコマンドを入れると、コンパイルの設定や、コード内で#define CONFIG_VALUE とかやってる設定を簡単に変えられるやーつが出ます。


書き込み設定は、Serial flasher Configで変更できます。
WSLでWindowsのCOMポートを使いたいときは、例えばWindowsでCOM5として認識してる場合は、"/dev/ttyS5"とかやるとそのまま使えます。
Flash sizeは使ってるモジュールに合わせて変更します。
あとおすすめは、Default baud rateを921600くらいに上げたほうがいいと思います。
どうでもいいことしかやってなくても結構ファームのサイズが大きくアップロードに時間がかかりますが、ここで書き込みスピードを上げるとArduino UNOなんかを使うときと遜色ないくらいの速さにできます。

設定が終わったらSave→Exitで終了。ここで作ったコンフィグはプロジェクトルートのsdkconfigに書かれています。


ビルドはmake allでできます。

そしてとりあえず書き込みしたいということで、
make flashすると書き込めます。esptool.pyを呼んで作ったビルドしたファイルを書き込んでくれるのですね。
書き込み時、RSTとIO0を、シリアルポートのRTS/CTSピンで自動的に切り替えて書き込みモードにしてくれてます。当然ESP32、USB-UARTが乗ってるボードにその仕組みがないとできません。うまく書き込まれないときはIO0をLOWにし続けながら、一旦リセットを掛けると手動で同じ状態にできます。

いろいろ作っていくと、Arduinoみたいにライブラリをもらってきて入れて使いたいですね。
そんなときは、プロジェクトルートに”components”ディレクトリを作ってそこへ入れるもののようです。
というわけで、
mkdir components
cd components
で、そこに入れたいコンポーネントをクローンしたりする。
仮にtestcmpntとかいう名前だとしますが
とりあえずその中身を見るとだいたいこんな感じだと思います
$ ls testcmpnt/
component.mk  include  testcmpnt.c  

この中身のcomponent.mkを見ると、こんな感じになっていると思います。
COMPONENT_ADD_INCLUDEDIRS = /include/.
COMPONENT_SRCDIRS := .

これが、SRCDIRSがtestcmpntのルート、INCLUDEDIRSが/include
も見てねって指示のようです。
これがちゃんと書いてあるとmake allしたときに一緒にコンパイルしてくれます
たまにcomponentを借りて持ってくるとこの中身が空だったりして、メインファイルでインクルードしたヘッダーファイルが見つからないよとエラーになったりします。
ここでプチハマりしました。ここに何も書いてなければ知らんがなってことなのですね
プロジェクトルート/mainに全部入れるといろいろ入れたときにゴチャゴチャしてしまいますし、わかってしまえば便利ですね。

とりあえずまだまだ使いこなしてないので一旦ここまでです。
なにか間違えてたら教えてください。

ほかにもぼちぼちわかったことやハマったことがあったら追記していきたいと思います

2017年11月16日木曜日

RS232対応を謳うバーコードリーダーでシリアルが使えなかったのでTTLレベルでシリアルを出せるようにしました。

タイトルが長い。

今春、Aliexpressでバーコードリーダーを買いました。


これです
https://www.aliexpress.com/item/Barcode-Scanners-NT-2012-Film-Portable-Laser-Reader-Handheld-USD-Bar-Code-Scanner-USB-Reader-Mobile/32802257553.html?spm=a2g0s.9042311.0.0.53ws4W

NETUM NT-2012って言うらしいんですが USB or PS/2 or RS232
と書いてあるのでシリアルでも出せるのかぁ。
マイコンで使えるなぁと思っていたら、シリアルが出てなかったのでバラしました。

するとすぐにRS232ドライバ(MAX232?)が載りそうなパターンがあり、USB-UARTから線を出して触れさせると読み込んだデータがbaud=19200で出てきました。
本来はここでTTLのUARTをRS232レベルに変換してコネクタに出力していたのですね。
これは当たりだということで、MAX232のデータシートを読んで、RS232レベルの信号出力のピンにこのピンをUEW線でジャンパ。




無事TTLレベルですがシリアルを出すことができました。
まあ逆に、マイコンに直接入れられるので便利ですね。

早速ESP-WROOM-02で使ってみました。
ESP-WROOM-02ではソフトウェアシリアルで受信したデータをそのままUDPでPCのIPアドレス(ポート9000)へ送信、
PC側はC# .NET でUDP受信のコードを書き、受けたデータをURLエンコードしてAmazonの検索URLに突っ込み、WebBrowserで表示させることで読んだバーコードをAmazon検索するようにしてみました。


Amazonはバーコードをそのまま検索すると商品名が出るので便利ですね。
Amazonの検索URLについては次のブログを参考にさせていただきました。
Amazon.co.jpの検索URL | oitake blog
http://oitake.jugem.jp/?eid=4