ESP8266からMQTT送受信してみる

AdafruitのMQTTライブラリを使ってローカルに立てたブローカー(MQTTサーバー)と通信してみます。

ライブラリのインストール

ArduinoIDEで「ツール→ライブラリを管理」でライブラリマネージャーから「Adafruit MQTT Library」をインストールします。

サンプルプログラムの呼び出し

「スケッチの例→Adafruit MQTT Library→mqtt_esp8266」でサンプルプログラムを呼び出します。

これでESP8266に書き込んで実行すると、リスナー側で

という感じで送信されているのが確認できました。

Arduino IDEのシリアルモニタ側でも

という感じでPublish/Subscribeの確認ができました。

 

ESP8266/ESP32でsyslog出力

ESP32でセンサ情報を収集できるようになったのですが、ESP32は電源を落とすとデータが消えてしまいます。そこでログをsyslogで出力してみます。

ぐぐると、GitHubにちょうど Arduino用の Syslog ライブラリがありましたので、これを試してみます。

GitHubからZIPでダウンロードしてきて、ダウンロードしたファイル(Syslog-master.zip)を展開、展開したディレクトリの名前を Syslog-master から Syslog に変更して、 ~/Arduino/librariesの下に移動します。

その後、Arduino IDEを起動すると、「ファイル→スケッチ例」の中に「Syslog」が出てきますので、この中の AdvancedLoggingESP8266 を開いて、冒頭の部分を修正します。

修正して実行すると、syslogサーバ側に以下のようなログが記録されました。

ESP32でマイクロ波近接センサをロギング

ESP32はしばらく放置している間にすごく使いやすくなっていたので、調子に乗って、以前買ったESP32 DevKitCOLEDモジュールをつけて、ドップラーセンサーモジュールで壁越しに動体検知するのにチャレンジしてみました。

開発はArduino環境で行いました。無線LANの初期化やNTPでの時刻同期、OLEDの表示に関する部分、Webサーバーに関する部分はT-Cameraのソースをベースに不要な部分を削除して用意しました。

今回使用したセンサはUARTで通信します。ESP32にはUARTが3つあり、1つはPC(Arduino IDE)との通信用となっていますので、残り2つが利用可能です。今回はUART1の送信を16ピン、受信を17ピンに割り当てて使用しました。

で初期化しました。

受け取ったセンサ情報は接近時、離別時、停止時の3つのパターンがありますが、それぞれ毎分0秒を境界とした1分毎、毎時0分を境界とした1時間毎に発生数を計数して Chart.js を用いてグラフ化してみました。

 

TTGO T-Camera ファームウェア改造

TTGO T-Cameraのファームウェアを改造してみました。

1.ファームウェア開発環境の準備

ファームウェアはArduino環境で開発しますので、まずはLinuxMint19に開発環境を導入します。

まずは、pyserialをインストールしておきます。

自分のユーザーアカウントを dialout グループに追加した後、一旦ログアウトしてログインし直します。

Aruduino公式サイトから arduino-1.8.9-linux64.tar.xz をダウンロードしてきて展開します。生成された arduino-1.8.9 というディレクトリをホームディレクトリ直下に移動した後、
シェルを開いて、

で Arduino をインストール完了です。インストールが完了したら、 「Menu → プログラミング → Arduino」でArduino IDEを起動します。次にArduino IDEの「ファイル→環境設定」で「追加のボードマネージャのURL」に

を設定します。引き続き、「ツール→ボード→ボードマネージャ」で「esp32 by Espressif Systems」を探してインストールします。インストールが完了したら、「ツール→ボード→ESP32 Wrover module」を選択すれば、Arduino自体の準備は完了です。

2.ソースコードの導入

ソースコードは https://github.com/lewisxhe/esp32-camera-series からZIPでダウンロードしてきます。ダウンロードした esp32-camera-series-master.zip を展開し、展開したディレクトリ名をesp32-camera-seriesに変更して、~/Arduino の下に移動します。

Arduino IDEの「ファイル→開く」で ~/Arduino/esp32-camera-series/esp32-camera-series.ino を開いておきます。

3.ライブラリの準備

Arduino OneButton Library を https://github.com/mathertel/OneButton からZIPでダウンロードしてきて、OneButton-master.zip を展開します。展開したら、ディレクトリ名をOneButtonに変更して、~/Arduino/liraries の下に移動します。

BME280のライブラリについては TTGO T-Cameraでは正常な値を表示しない(そのため、途中から削除されている)のでソースコード中の

の行はコメントアウトしておきます。

esp8266-oled-ssd1306 Library を https://github.com/ThingPulse/esp8266-oled-ssd1306 からZIPでダウンロードしてきて、esp8266-oled-ssd1306-master.zipを展開します。ディレクトリ名をesp8266-oled-ssd1306に変更して、~/Arduino/liraries の下に移動します。

ここまででビルドと書き込みはできるはずです。Arduino IDEのチェックマーク(検証)を押してコンパイルしてみます。うまく行ったら、右矢印マークを押して書き込みもテストしておきます。

4.SoftAPモードからSTAモードへ変更

をコメントアウトして、SoftAPモードを禁止して、

のところに接続先のSSIDとパスワードを設定します。

5.ESP32のIPアドレスを固定IPに変更する

SSID/PASSWORDの設定の箇所の後に以下の記述を追加

WiFi.begin()の直前に以下の記述を追加

6.mDNS対応

ローカルネット内からはIPアドレスではなくホスト名でアクセスできると便利なので、mDNS対応させておきます。

先頭の

の後に

を追加します。続いて、SSID/PASSWORDの設定の箇所の後に以下の記述を追加します。

引き続き、setup()の最後の箇所の

に変更します。更に、void drawFrame1(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) の中の

に書き換えます。(いくつかの行がコメントアウトになっているのは、表示にはIPアドレスもほしいためです。すべてURLでいい場合にはコメントを外します)
さらに、void drawFrame2(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)の中の

に書き換えます。

7.カメラの向きとOLEDの表示が上下逆なのを修正

の後あたりに

を追加します。

これでボードに書き込むと同じサブネットのPCからは http://esp32.local で、異なるPCからは http://IPアドレス でアクセスできます。どちらもOLEDディスプレイにも表示されます。

TTGO T-Cameraを開封レビュー

Twitterで見かけたESP32 WROVERとセンサー色々搭載のTTGO T-Cameraを購入してみました。(⇒Aliexpressのページ

ESP32 WROVERにカメラ、人感センサ、温度・湿度・気圧センサなどのセンサ、0.96インチのOLEDディスプレイ、I2Cでの外部拡張端子がついて、魚眼レンズタイプで17.6ドル(今はさらに下がって16.5ドル)で入手できる上に、githubでArduino環境のソースコードまで手に入ります。

梱包は比較的簡易なものでしたが、このようなポリプロピレン製のケースに入っているので、潰れて送られてくる、ということはなさそうです。

ポリプロピレンケースの中に入っていた製品はこのように帯電防止の袋に入れられて密封されていました。

開封するとこんな感じで、電池を接続するためのケーブルも添付されていました。ここにLiPoをつないで充電ができるといいのですが、そこまではまだ調べていません。

裏面はこんな感じです。

MicroUSBの端子がついているので早速適当なUSBの電源アダプタにつないでみると、こんな画面で崩れて表示されてしまいました。

この状態でも無線APとして動作していて、スマートフォンで接続でき、ブラウザで 2.2.2.1 に接続するとカメラ画像の取得などができました。

電源をPCから取ると、このように正常に表示されました。ACアダプタやモバイルバッテリーは軽負荷時にノイズが大きいので、その影響だったのだと思います。
しかし、温度表示が39.61℃と異常な値が表示されています。カメラ右下についているのがBME280だと思いますが、ESP32の自己発熱でかなり温度が上がってしまうのでしょうか??
温度がおかしいと、気圧や湿度も補正できないはずなので、残念です。

・・・と思ったら、バージョンアップ(?)により役に立たないBME280は削除されているようです。

ま、とりあえずおもちゃ入手レポートでした。(なんかおもちゃばっかりですが・・)

追伸

IPS液晶搭載の後継モデルが出ていました。人感センサとスイッチがなくなっているようですが、カラー液晶、MicroSDカードスロット搭載、BME280復活となっています。スイッチが残っていればUIとかも付けられるかな?と思うのですが、スイッチ無しなので用途がいまいち思いつかないところです。(バッテリー駆動するなら不要なときは液晶をOFFにしたいですし)

MKRVIDOR4000_graphicsの中身を見てみる

Quartus Prime LiteでMKRVIDOR4000_graphicsの中身を見てみます。

projectディレクトリの中にMKRVIDOR4000_graphics_lite.qpfがあるので、これをQuartus Prime Liteで開いてみます。

左の方のProject Navigatorのところでソースツリーっぽいところ(Entity)が見えて、ここに MKRVIDOR4000_graphics_top があるので、これをクリックすると、そのソースコードが開きました。トップレベルモジュールの verilog ソースコードのようです。端子の定義と信号の定義、出力バッファ近傍のセレクタなどがあるようです。

Project NavigatorでIP Componentsを選択し、EntityのところでMKRVIDOR4000_graphics_lite_sysをダブルクリックすると、Platform Designerが開いてIPマクロ間の接続の全体像が少しわかります。nios CPUのメモリマップもここで確認することができて、niosの命令バスはオンチップメモリとQSPIフラッシュメモリからフェッチできるようになっているようです。(SDRAM ARBITERとsdramのところを編集するとSDRAMからのアクセスもできるように修正できるっぽい雰囲気です)

上の方の再生ボタンみたいな Start Compilation をクリックすると論理合成して、配置配線、タイミング解析をしてくれます。Task のパネルに進捗が表示されて、完了すると、Entityのところに各モジュールの構造がツリー状に表示されました。このあたりをもう少し見ていくといろいろわかりそうです。

一方で、VidorBitstream-releaseディレクトリの下にipというディレクトリがあり、ここにIPコアのコードが入っているようです。各モジュールの softcore というディレクトリの下にFPGA側のniosのコードが入っています。graphicsの描画処理は ip/GFX/softcore/src/gfx.c というソースの中の gfxRpc() の中で受け取ったリモートプロシージャコールのパラメータに応じて描画関数を呼び出していました。

また、VidorBitstream-release/project/MKDVIDOR4000_graphics/build/software/launcher_lite_bspの下にsummary.html というファイルがあり、これがnios側の諸情報のようです。この中にLinkerのSectionに関する情報があり、nios側のコードもデータもbssもheapもオンチップメモリ上に配置されているようです。また、mem_init.mk というファイルによるとリセットベクターも 0x00a00000 となっているようで、これはメモリマップによればやはりオンチップメモリのようです。nios上のコードはniosとは関係なくオンチップメモリ上に転送しているのかもしれません。(FPGAのコンフィギュレーション時に書き込まれるんでしょうかね??)

まだまだ弄るといろいろわかりそうですが、時間もかかりそうです。

VidorBitstreamがビルドできるようになりました

MKRVIDOR4000_graphicsのサンプルスケッチが中途半端に表示がされる原因についてもわかりました。

中途半端に表示がされるのは、サンプルスケッチ VidorDrawLogo の冒頭にある

のFPGA側での処理が遅いことと、初期化時にそもそも白で全面クリアされていること、ARM側の処理でFPGA側の処理完了を待っていてもタイムアウトするほど遅いことが原因です。初期化時にそもそも白で全面クリアされているので、その上に処理の遅いfillRect()が同色で描画されても、画面上は何も見えません。fillRect()の処理が終わった後に描画要求が飛んでくる部分だけが見える、というわけです。

その証拠に、

と色を変えてやると、ちょっとずつ青く塗っていく処理と、その後で一部の文字が描画されるのがわかります。

というわけで、fillRect()の部分をコメントアウトすることで無事に表示されるようになりました。

まとめ

Linux Mint 19.1 上の Quartus Prime Lite Edition 18.1で MKR Vidor 4000 のFPGAのコードをビルドする場合は以下の点に注意。

  1. apply_quartus_patches.shでパッチを当てる際には、arduino_generic_quad_spi_controller2_sw.tcl に対するパッチ適用は失敗するので、手動で適用すべし。
  2. スケッチサンプルの冒頭のfillRect()はコメントアウトすべし(もしくは、色を変えた上で、Arduinoライブラリの中の VidorMailbox.cpp の冒頭のMB_TIMEOUTを大きく伸ばすべし)

おまけ

Arduino側(ARM側)のライブラリを見ていてARM側からは以下のようにFPGA側にリクエストが伝わるようです。

Vidor_GFX.cpp ⇒ VidorMailbox.cpp ⇒ VidorJTAG.cpp ⇒ jtag_host.cpp ⇒ JTAG信号線

グラフックスの関数はリモートプロシージャコール(rpc)のパラメータの配列(uint32_tの配列)に変換されて、VidorMailbox.sendCommand() が呼び出されます。パラメータはVidorJTAG.writeBuffer()の引数として渡されますが、最終的には jtag_host.cpp で1ビットずつJTAG信号としてFPGA側へ転送されます。すべてソフトウェアでJTAG信号を生成しているようなので、コマンドの転送自体が遅そうです。Mailboxへのコマンド送信後の応答待ち時間は VidorMailbox.cpp の冒頭の MB_TIMEOUT で定義されていて、5000ms=5秒になっているようです。
FPGA側の処理については調べていないのでこれからです。

VidorBitstreamがビルドできない原因を探ってみました

気を取り直して、MKRVIDOR4000_graphicsがビルドできない原因を考えてみます。

まずは改めてビルドして気になるところを洗い出してみます。

途中で

というところがあって、arduino_generic_quad_spi_controller2が絡んで致命的にだめな感じです。

~/intelFPGA_lite/18.1/ip/altera/pgm/arduino_generic_qpsi_controller2 の下でリジェクトされたパッチが2つあったのですが、そのうちの対象の一つが arduino_generic_quad_spi_controller2_sw.tcl というファイル名なので、何か関連がありそうです。リジェクトされたパッチ arduino_generic_quad_spi_controller2_sw.tcl.rej を見てみます。

この中に、

というようなところがあるので、なんか関連はありそうです。arduino_generic_quad_spi_controller2_sw.tcl の中をみても、なぜリジェクトされたのかイマイチよくわかりません(適用されても良さそうな気がする)が、とにかく手動で適用してみます。(追記: 要は、arduino_generic_quad_spi_controller2_sw.tcl というファイルの中の16行目からの10行くらいと、50行目からの11行くらいのところにある「altera_generic_quad_spi_controller2」を「arduino_generic_quad_spi_controller2」に書き換える、ということです。)

もう一つのarduino_generic_qspi_controller2_hw.tclに対して1箇所失敗している方はかなり雰囲気が違うので、まずはこのまま再トライしてみることにしてみます。

ということで、当該箇所では特にエラーなく完了しました。

・・・ということで試してみると、

4:3サイズで全面白になった後、しばらく経ってからこんな表示に。
まあ、全く動いてないわけではないので、だいぶ進歩しました^^;

VidorBitstreamをビルドしてみる

Arduino MKR VIDOR 4000のFPGA部分については、githubのvidor-librariesにいくつかサンプルがあるようです。この中の、VidorBitstreamが詳しそうな感じなのでVidorBitstreamのReadmeを読みながら作業してみます。

冒頭の部分は要約すると、「対象はFPGA開発プロセスに慣れたユーザーである」「FPGAのネイティブ開発はサポートは難しいので限定的」ということみたいです。

ディレクトリ構成は以下の通りのようです。

  • IP IPブロックのソースコード。
  • projects 各ボード用のサンプルプロジェクト。
  • constraints 各ボード用の制約ファイル。ピン配置とタイミング制約を含む。
  • TOOLS FPGAイメージを生成するためのスクリプトとツール
  • distrib コンパイル中にツールチェーンによって作成されたディレクトリ。プロジェクトをコンパイルすることによって作成されたArduinoライブラリが含まれている。

リポジトリのダウンロードと展開

まずはリポジトリをダウンロードして展開します。まず、VidorBitstreamをZIPでダウンロード。ダウンロードしたVidorBitstream-release.zipを~/intelFPGA_liteディレクトリの下に移動し、ここに展開しました。

NIOS II Command Shellの起動

NIOS II Command Shellを開いてシェルスクリプトを起動する必要がある、ということなのですが、Windows版はStartメニュー内にあるようですが、Linux版はnios2edsディレクトリ内にあるようなので、

として起動します。プロンプトは一切変わらないようなので、要注意かもしれません。
(Windows版はCygwinが起動するようですが)

QuartusのIPにパッチ適用

次に、QuartusのIPにパッチをあてます。

うーん、~/interlFPGA_line/18.1/ip/altera/pgm の下のファイルでいくつかパッチ当てに失敗してしまったようですが、このまま進めてみます。

makeCompositeBinaryのコンパイル

make_composite_binary.goをコンパイルするためにはgoが必要ですのでインストールします。

引き続いて、コンパイルします。

TOOLS/scriptsディレクトリにパスを通す、ということなのですが、どうするか考えた挙句、NIOS II Command Shellの実体であるintelFPGA_lite/18.1/nios2eds/nios2_command_shell.sh を修正して、

を179行目付近(env_var_prepend が unset される前あたり)に1行追加して対応しました。

VidorGraphicsのリポジトリダウンロードと展開

VidorGraphicsのリポジトリをZIPでダウンロードして、ダウンロードしたVidorGraphics-release.zipを~/intelFPGA_liteディレクトリの下に移動し、ここに展開しました。

VidorGraphicsのビルド

展開した VidorGraphics-release をビルドしようとしたのですが、 projects ディレクトリがありません。実際には VidorBitstream-release/project の下に、MKRVIDOR4000_graphics ディレクトリがありました。なので、先のリポジトリダウンロードも意味がなかったことになります。

で、結局、別のシェルを起動して、ビルドにトライします。

ということで、11分くらいで一応正常終了したようです。ちなみに使用したPCのスペックは、

  • Intel(R) Core(TM) i3-3220T CPU @ 2.80GHz
    (CPUファンはCeleron G530のものの方が大型で冷えそうなのでそちらを使用。実際TDPもG530の方が大きい。)
  • マザーボード ASRock H61M-ITX
  • メモリ 8GB
  • SSD Crucial CT120M500SSD1(120GB)
  • OS LinuxMint19.1 MATE 64bit

といったところです。

生成したファイルをArduino IDEに取り込む

ビルドに成功すると、VidorBitstream-release ディレクトリの下に distrib というディレクトリができて、更にその下に MKRVIDOR4000_graphics ディレクトリができていました。このディレクトリをZIPで圧縮して、MKRVIDOR4000_graphics.zip を作成します。

Arduino IDEで「スケッチ」→「ライブラリをインクルード」→「ZIP形式のライブラリをインストール」で ~/intelFPGA_lite/VidorBitstream-release/distrib/MKRVIDOR4000_graphics.zip を指定してインストールします。すると、 ~/Arduino/libraries の下に展開して取り込まれました。スケッチ例にもカスタムライブラリのスケッチ例として取り込まれました。

同様に、MKRVIDOR4000_peripheralsでもビルドしてみました。

distribの下の MKRVIDOR4000_peripherals ディレクトリをそのまま~/Arduino/libraries の下にコピーしてもライブラリとして認識されるようです。

生成したものを動かしてみる

Arduino IDE上でカスタムライブラリのスケッチ例を動かしてみました。

  • そもそも書き込みにめったに成功しない・・・・
    ⇒ HDMIケーブルを刺していると、そもそもリセットがなかなか掛からない。
  • HDMIケーブルを抜いてから書き込んでみる
    ⇒ VidorDrawLogoは全く動いてない・・・。VidorEncoderも動いている気がしない・・・。うーん。パッチ当てに失敗しているあたりが関係しているのだろうか・・??

なんか、ARM側とFPGA側の通信が全くうまく行ってない気がする。とりあえず、また明日・・・orz

Quartus Prime Lite と ModelSim Starter をインストール

昨日ダウンロードした Quartus Prime Lite Edition と ModelSim Start Edition をインストールします。といっても、やり方がわからなかったので、適当です。^^;
OSはもちろんLinuxMint19.1 MATE edition 64bitです。

ホームディレクトリにダウンロードした以下のファイルをおいてあります。

  • ModelSimSetup-18.1.0.625-linux.run
  • Quartus-lite-18.1.0.625-linux.tar
  • QuartusLiteSetup-18.1.0.625-linux.run
  • cyclone10lp-18.1.0.625.qdz

この状態で実行属性をつけて、動かしてみました。

すると、ウィザードが立ち上がり、何も考えずに勧めていくと、途中でダウンロードしたファイルをすべて検出した状態でインストールするソフトウェアをすべて表示してくれました。

さらに進めていくと、

という表示が出て、勝手に起動する模様・・・・に見えましたが、

というエラーを出して止まっていまいました。

として、インストールしたディレクトリを削除して再度トライするも、やっぱりだめ。今度は、

を実行してから、再度インストールしたディレクトリを削除してトライ。今度は

という画面が出て、フル機能版のライセンスを買うか聞いてきます。趣味・勉強の範囲なので、そんな余裕もないので、真ん中を選んで実行してみます。

という感じで、Quartus Prime Lite Edition が無事に起動しました。

しかし、デスクトップにショートカットは生成されませんでしたので、デスクトップを右クリックして「ランチャの生成」で手動でランチャを作っておきます。

  • 名前は「Quartus Prime Lite Edition」
  • コマンドは「/home/(ユーザー名)/intelFPGA_lite/18.1/quartus/bin/quartus」
  • アイコンは「intelFPGA_lite/18.1/quartus/adm/quartusii.png」

として作成しておきます。作成したものをダブルクリックすると起動することを確認しておきます。

さらに、こちらの情報によるとModelSimを動かすには、32bit用のライブラリが要るらしいので以下の手順でインストールしておきます。