osx のシリアルポートのユーティリティーあれこれ

シリアルをtelnet 経由してつなげるようになったので、ArduinoIDE からシリアルをWiFi で書き込めるようにしてみようとあれこれやること、1日弱。結局、osx では良いツールが見つからずできませんでした。

何ができなかったかと言うと、仮想シリアルポートを作成して、それをArduinoIDE から認識できずで、何かやり方があるんだろうと思います。socat の使い方が悪いんだと思うので、継続して調査。Windows だとこのあたりのツールはたくさんあって、苦労しない感じなので、次回は、Windows でやってみることに。

で、いろいろsocat の使い方を試しているうちに、昨日の疑問が解けました。

・ESP12 の接続IPにつなげて、echo が表示されてしまう問題
・CTL + C など 接続した先でやりたいんだけど、socat の接続元(osx 側)で CTL + C になる問題

これは、以下のようにすれば良いようです。

$ socat STDIN,raw,echo=0 TCP:192.168.1.36:23

raw をつけておけば、そのままコントロール信号も送られるけども、手元のターミナルは中断できないので、ターミナルウィンドウを閉じてしまう感じ。tcpdump とか、WiFi 経由のシリアルから入って採取してるときとか、CTL + C できるし、上矢印のコマンド履歴も、tab 補完キーも効きます。理屈がわかってしまえば、あ、そうかということですが。。。。

 

調べているときに、よくまとまったBlog記事があったので、メモしておきます。

Make RS232 Serial Devices Accessible via Ethernet
http://blog.philippklaus.de/2011/08/make-rs232-serial-devices-accessible-via-ethernet/

最後に、socat でのソケットを分割するには、以下のようにやれば良い事がわかりました。

ishizaka_—_socat_—_ttys008_—_76×23_と_ishizaka_—_socat_—_ttys007_—_76×23_と_ishizaka_—_socat_—_ttys002_—_76×23_と_ishizaka_—_tail_—_ttys009_—_76×36

sudo socat -d -d -d -d -lf /tmp/socat \
pty,\
link=/dev/master,\
raw,\
echo=0,\
user=junkhack,\
group=staff\
\
pty,\
link=/dev/slave,\
raw,\
echo=0,\
user=junkhack,\
group=staff

 

 

どうやって、arduinoIDE のシリアルポートに表示させるかが課題です。

WiFi 経由のシリアルコンソールで、ずっとtcpdump を流してテストしていますが、接続もきれず良い感じです。あと、話は飛びますが、ESP8266 Arduino Core のドキュメント見てましたら、File system も使えるようですね。これはある程度まで、データをメモリに貯めておいて、まとめてWifi 出力でデータを飛ばせば、電力の消費も抑えられそうです。sleep mode の下調べはおおよそ終わったので、コード実装して、電池駆動にしてテストするデバイス作りを夏休み(まだこれからなんですが)にやれればと思っています。ESP8266 、こんなに遊べるとは。まだlua にするのもありますしね。今年いっぱいは遊べる感じです。飽きるか、いきづまらなければね。

ESP-12でraspi2のシリアルコンソールをWiFi化

前から、興味があった透過型のUARTーWiFIブリッジ的に使う方法をあれこれ試していました。

結論から言えば、出来ました。

こんな感じで、電源はRasPi2 から取っていますので蓋の中に収められそうです。

uart-wifi

ESP-12 に収めるプログラムは、なんとサンプルスケッチの中にありました。WiFiTelnetToSerial です。

/*
WiFiTelnetToSerial - Example Transparent UART to Telnet Server for esp8266

Copyright (c) 2015 Hristo Gochkov. All rights reserved. This file is part of the ESP8266WiFi library for Arduino environment.

This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */

include <ESP8266WiFi.h>

//how many clients should be able to telnet to this ESP8266

define MAX_SRV_CLIENTS 1

const char ssid = "yyyyy"; const char password = "xxxxx";

WiFiServer server(23); WiFiClient serverClients[MAX_SRV_CLIENTS];

void setup() { Serial1.begin(115200); WiFi.begin(ssid, password); Serial1.print("\nConnecting to "); Serial1.println(ssid); uint8_t i = 0; while (WiFi.status() != WL_CONNECTED && i++ < 20) delay(500); if(i == 21){ Serial1.print("Could not connect to"); Serial1.println(ssid); while(1) delay(500); } //start UART and the server Serial.begin(115200); server.begin(); server.setNoDelay(true);

Serial1.print("Ready! Use 'telnet "); Serial1.print(WiFi.localIP()); Serial1.println(" 23' to connect"); }

void loop() { uint8_t i; //check if there are any new clients if (server.hasClient()){ for(i = 0; i < MAX_SRV_CLIENTS; i++){ //find free/disconnected spot if (!serverClients[i] || !serverClients[i].connected()){ if(serverClients[i]) serverClients[i].stop(); serverClients[i] = server.available(); Serial1.print("New client: "); Serial1.print(i); continue; } } //no free/disconnected spot so reject WiFiClient serverClient = server.available(); serverClient.stop(); } //check clients for data for(i = 0; i < MAX_SRV_CLIENTS; i++){ if (serverClients[i] && serverClients[i].connected()){ if(serverClients[i].available()){ //get data from the telnet client and push it to the UART while(serverClients[i].available()) Serial.write(serverClients[i].read()); } } } //check UART for data if(Serial.available()){ size_t len = Serial.available(); uint8_t sbuf[len]; Serial.readBytes(sbuf, len); //push UART data to all connected telnet clients for(i = 0; i < MAX_SRV_CLIENTS; i++){ if (serverClients[i] && serverClients[i].connected()){ serverClients[i].write(sbuf, len); delay(1); } } } }

ArduinoIDE へ、ESP8266 Arduino Core の最新(ver. 1.6.5-1044-g170995a, built on Aug 10, 2015)を収めました。

SDK1.3 が収まったものは、以下のStaging versionから入れました。

ESP-12のファームウェアをv1.3.0 に

オフィシャルのツールがWindows のexe だったので、バーチャルボックスでインストール。

Flash download tool Vsersion:v1.2

http://bbs.espressif.com/viewtopic.php?f=57&t=433

DETECTED INFO に 32Mbit って出てました。前回、調査したように、やはりESP-12 には、32M-bit / 4M-byte ( 4,194,304 )あるようです。今まで、512Kb でもarduino とかと比べると、おおーたくさんあるねと思っていましたが、それの4倍です。ちょっと得した気分ですね。クリスタルは26Mhz のようです。

GW-20150812-000341 で、書き込みして、AP に接続できるようにしてリセットかけてみました。ちゃんとフラッシュに設定は保存されて、バージョンも1.3.0 になっていました。UART の都合上、Windows のCoolTerm で接続テストはやりました。

GW-20150812-000919

あと、マニュアルのP.55 に 前からできるみたいなんだけども、UART-WiFi passthrough modeというのがあって、WiFi経由でシリアルにパススルーできるようです。osx 側の nc は brew で netcat を入れています。osx のだとオプションが通らないので。

CoolTerm_0_と_ishizaka_—_ESP8266_—_netcat_—_ttys000_と_名称未設定

この設定は、フラッシュに保存されないようなのですが、IP と Port を打ち込めるようなものをESP側に付ければ、WiFi 経由でシリアルを操れることになりますね。これを、単機能にしてESPのAP に接続しにきたものをシリアルに流すだけのファームが透過のブリッジのファームウェアの原理なのかも。このあたりは、次回以降実験してみたいと思います。

あ、あとWEBにもオフィシャルのAT コマンド(ちょっと古いけど)があったので、メモ。

CIPMODE

https://github.com/espressif/esp8266_at/wiki/CIPMODE

ま、とりあえずフラッシュが4Mあって、SDK1.3も書き込めるということがわかったのでとりあえず今日はここまで。

Arduino と RasPi2 と ESP8266

ここのところ、遊び道具が増えてきて、あれもやりたいこれもありたいと調査していると、結局何も手付かずに終わってしまう不毛な毎日が続いているので、とりあえず、やってみたいことを整理してみます。

 

・ESP8266 の省電力化と、リチウム電池利用した温度湿度照度の単体デバイスの作りこみ

単体ではそこそこ調査は終わっていて、あとは作りこみ。ESP8266(ESP12) + DHT-22(AM2302) + GL5528でセンサー部と、データをWiFi で投げてThingSpeak に投げることまでは完了。残るは、省電力化へのコードの検討、テストと、バッテリー駆動への電力部の作成(というか、パーツ組み合わせるだけ)です。途中で、RasPi2 をゲットしてそっちに気がほうけてしまい手付かずの案件。

2015_05_10_2_14

+

HTB19pQDHXXXXXXyXFXXq6xXFXXX7

+

HTB1NkOvHFXXXXa_aXXXq6xXFXXXt

 

 

・ProMini を活用したモータ制御するロボット(プログラム制御の車とか、リモコン制御のものとか)

極小のギヤモータは、ゲット済みでモータードライバなしでarduino に直結して動作させる予定の案件。基本部分が出来ればあとはセンサー拡張して楽しむ予定の案件

 837293198_862

+gearmoter

・HC-06(Bluetooth) + ProMini で HID USBデバイス

SPPのやつなんですが、HID にできるかもしれないので、一応ゲットしました。だめなら、ちょっと高価なHM-10でやるつもりのもの。まだ、未調査なので、動作確認もしてない放置もの。

a

or

b

・RasPi2(母艦) + Firmata化したarduino との通信

これはつい最近、知ったんですがFirmata という汎用通信規格がやり取りできるよう arduino にスケッチを入れてコントロールはシリアル経由でやるという代物。ソフトウェア実装なので、電子工作が伴う前の基礎技術の研究をしたいなと。コントロールする母艦は、RasPi2 でやるつもりで、実装方法はいろいろあるようです。Python や Ruby や C 、PHP、そしてnode.js とかでも出来るようです。表示やコントロールが伴うものは、HDMI出力があるRasPai からやったほうが良さそうなので、そいういう用途にGUI でラップしたFirmata のアプリケーションを作れないかなと。こちらは、まだ未調査なので、どんな組み合わせがベストなのかは不明。

 

 

このほかにもあれこれと、やりたいことが調べているうちに出てきてしまうんですが、上4つはやりたいですね。今年度中はおそらくこれらで、あそべるはず。特に、ソフトウェア的な組み合わせが出来る、RasPai との連携を考えると、技術が追いつかなさそうなので、ぼちぼと勉強しながらやっていきたいと思っています。

 

さて、とりあえず何からやりますかね。気がノルやつから手をつけていきますか。遊びでは、それが基本スタンスですからね。

ESP12単体で湿度温度照度のIoTデバイス

前回は、Arduino Nano でDHT22の湿度と、温度をゲットしていました。

 

編集後記

その後、リチウム電池と組みあわせ、IoT デバイスを作った記事がこちら
初めてのIoTデバイス完成

image

 

IoTデバイスとしてデータを投げつけたいので、ESP12、単体でコーディングしました。こんな感じで、前回作成したものに、付け加える感じでとりあえずテスト。

写真 1

 

コードは、以下のようにしました。アクセスポイントや、ThingSpeak の書き込みAPI key などはほどよく書き換えてください。

ポイントは、DHT のライブラリを初期化するときの第3のパラメータで、いろいろ試した結果、15だとうまく値が取れるようです。まだ、この値はよくわかっていませんが、CPU Clock に対応する値のようで、Arduino とかは、16Mhz のはデフォルトで、Arduino Due とか 84mhz は、30 にせよとのこと。

 

この値は、以下のコードを見てみると、ESP01 は 11 で動作するようです。

https://learn.adafruit.com/esp8266-temperature-slash-humidity-webserver/code

// Initialize DHT sensor
// NOTE: For working with a faster than ATmega328p 16 MHz Arduino chip, like an ESP8266,
// you need to increase the threshold for cycle counts considered a 1 or 0.
// You can do this by passing a 3rd parameter for this threshold.  It’s a bit
// of fiddling to find the right value, but in general the faster the CPU the
// higher the value.  The default for a 16mhz AVR is a value of 6.  For an
// Arduino Due that runs at 84mhz a value of 30 works.
// This is for the ESP8266 processor on ESP-01
DHT dht(DHTPIN, DHTTYPE, 11); // 11 works fine for ESP8266

ESP12 では、11 だと値がおかしくなり、15 だとうまく取れました。あと、IDE は、arduino 1.6.4 以上で今回は Hourly Build  を使いました。Boards Manager という機能が加わり、ツールメニューのボードからインストールできます。

手動で入れてもいいんですが、まぁ便利な機能がつきましたね。

http://arduino.esp8266.com/package_esp8266com_index.json

 

/
ESP8266 HTTP get webclient.
ADC Read (ESP12 + Light(CdS GL5528)) + DHT22(AM2302) 1-Wire
https://thingspeak.com/channels/42239
Arduino IDE 1.6.5 Hourly Build 2015/06/12 03:13
esp8266 by ESP8266 Community version 1.6.4-673-g8cd3697
JunkHack 2015.06.15
/

include <ESP8266WiFi.h>

include <DHT.h>

define DHTPIN 4

define DHTTYPE DHT22

DHT dht(DHTPIN, DHTTYPE, 15);

const char ssid = "JunkHack"; const char password = "testtest";

const char* host = "184.106.153.149";

int WiFiConLed = 13;// WEB Connect int WEBconLed = 0; // WiFi Connect

void setup() { dht.begin();

pinMode(WiFiConLed, OUTPUT); pinMode(WEBconLed, OUTPUT); Serial.begin(115200); delay(10);

// We start by connecting to a WiFi network

Serial.println(); Serial.println(); Serial.print("Connecting to "); Serial.println(ssid);

WiFi.begin(ssid, password);

while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); digitalWrite(WiFiConLed, HIGH); delay(400); digitalWrite(WiFiConLed, LOW); delay(100); }

Serial.println(""); Serial.println("WiFi connected"); Serial.println("IP address: "); Serial.println(WiFi.localIP());

Serial.println("DHT22 AM2302 test!"); }

int value = 0; int count = 0; int adc = 0; float h = 0; float t = 0;

void loop() { delay(10000); // 10 sec ++value;

Serial.print("connecting to "); Serial.println(host);

// Use WiFiClient class to create TCP connections WiFiClient client; const int httpPort = 80; if (!client.connect(host, httpPort)) { Serial.println("connection failed"); return; }

digitalWrite(WEBconLed, HIGH); delay(1000); count += 1;

Serial.print("ADC: "); adc = analogRead(A0); Serial.println(adc);

float h = dht.readHumidity(); float t = dht.readTemperature();

if (isnan(h) || isnan(t) ) { Serial.println("Failed to read from DHT sensor!"); return; }

Serial.print("Humidity: "); Serial.print(h); Serial.print(" %\t"); Serial.print("Temperature: "); Serial.print(t); Serial.println(" *C ");

// We now create a URI for the request String url = "/update?key=33HJNSWFZ8EZAXD6&field1="; url += adc; url += "&field2="; url += h; url += "&field3="; url += t;

Serial.print("Requesting URL: "); Serial.println(url);

// This will send the request to the server client.print(String("GET ") + url + " HTTP/1.1\r\n" + "Host: " + host + "\r\n" + "Connection: close\r\n\r\n"); delay(10);

// Read all the lines of the reply from server and print them to Serial while(client.available()){ String line = client.readStringUntil('\r'); Serial.print(line); }

// Close connection Serial.println(); Serial.println("closing connection"); digitalWrite(WEBconLed, LOW); }

 

データは、とまっているときもあるかもですが、以下で見れます。

 

https://thingspeak.com/channels/42239

 

2015-06-15 1.19.12

 

部屋の温度がそこそこ高いので、実際に温度計を見てみましたところ、ほぼ適正な値でした。部屋暑すぎ。

写真 2

 

これで、明るさ、温度、湿度が取れました。まだ、GPIO Pin があまっているので、気圧や、雨量、風向、風量など取ろうと思えば可能ですね。また、課題となるのは、電源です。結構シビアに電源品質が問われるようで、ぼろい電源だと途中で止まります。

 

あと、sleep mode にして平常時に、パワーを抑えるように制御する必要があります。

 

まだ、課題はありますね。