ラベル ESP-WROOM-02 の投稿を表示しています。 すべての投稿を表示
ラベル ESP-WROOM-02 の投稿を表示しています。 すべての投稿を表示

2017年3月10日金曜日

ESP-WROOM-02 + ADXL345 で加速度センサを試す

概要

前回 Arduino を使って ADXL345 を試しました
Arduino で動くなら互換ボードでも動作するだろうということで試してみました

環境

Adafruit ADXL345 のインストール

スケッチ -> ライブラリをインクルード -> ライブラリを管理

で「Adafruit ADXL345」と検索してインストールします
ついでに「Adafruit Unified Sensor」でも検索してインストールしましょう

以下のように INSTALLED になれば OK です
wroom_with_adxl345_libs_install.png

配線

配線の全体図は以下の通り
wroom_with_adxl345_circuit.jpg

簡単に説明すると

  • WROOM (以下 W) [VO] -> ブレッドボード (以下 ブ) [+]
  • W [GND] -> ブ [-]
  • ADXL345 (以下 A) [VDD] -> ブ [+]
  • A [GND] -> ブ [-]
  • A [VDD] -> A [Vs]
  • A [Vs] -> A [SDO]
  • A [SDA] -> W [4ピン]
  • A [SCL] -> W [5ピン]

になります
配線できたら microUSB を PC に接続して電源を投入しましょう

スケッチ書き込み

今回書き込むスケッチはサンプルをそのまま使います

ファイル -> スケッチの例 -> Adafrut ADXL345 -> sensortest

をロードして WROOM に書き込んでください
一応ソース全体も記載しておきます

#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_ADXL345_U.h>

/* Assign a unique ID to this sensor at the same time */
Adafruit_ADXL345_Unified accel = Adafruit_ADXL345_Unified(12345);

void displaySensorDetails(void)
{
  sensor_t sensor;
  accel.getSensor(&sensor);
  Serial.println("------------------------------------");
  Serial.print  ("Sensor:       "); Serial.println(sensor.name);
  Serial.print  ("Driver Ver:   "); Serial.println(sensor.version);
  Serial.print  ("Unique ID:    "); Serial.println(sensor.sensor_id);
  Serial.print  ("Max Value:    "); Serial.print(sensor.max_value); Serial.println(" m/s^2");
  Serial.print  ("Min Value:    "); Serial.print(sensor.min_value); Serial.println(" m/s^2");
  Serial.print  ("Resolution:   "); Serial.print(sensor.resolution); Serial.println(" m/s^2");  
  Serial.println("------------------------------------");
  Serial.println("");
  delay(500);
}

void displayDataRate(void)
{
  Serial.print  ("Data Rate:    "); 

  switch(accel.getDataRate())
  {
    case ADXL345_DATARATE_3200_HZ:
      Serial.print  ("3200 "); 
      break;
    case ADXL345_DATARATE_1600_HZ:
      Serial.print  ("1600 "); 
      break;
    case ADXL345_DATARATE_800_HZ:
      Serial.print  ("800 "); 
      break;
    case ADXL345_DATARATE_400_HZ:
      Serial.print  ("400 "); 
      break;
    case ADXL345_DATARATE_200_HZ:
      Serial.print  ("200 "); 
      break;
    case ADXL345_DATARATE_100_HZ:
      Serial.print  ("100 "); 
      break;
    case ADXL345_DATARATE_50_HZ:
      Serial.print  ("50 "); 
      break;
    case ADXL345_DATARATE_25_HZ:
      Serial.print  ("25 "); 
      break;
    case ADXL345_DATARATE_12_5_HZ:
      Serial.print  ("12.5 "); 
      break;
    case ADXL345_DATARATE_6_25HZ:
      Serial.print  ("6.25 "); 
      break;
    case ADXL345_DATARATE_3_13_HZ:
      Serial.print  ("3.13 "); 
      break;
    case ADXL345_DATARATE_1_56_HZ:
      Serial.print  ("1.56 "); 
      break;
    case ADXL345_DATARATE_0_78_HZ:
      Serial.print  ("0.78 "); 
      break;
    case ADXL345_DATARATE_0_39_HZ:
      Serial.print  ("0.39 "); 
      break;
    case ADXL345_DATARATE_0_20_HZ:
      Serial.print  ("0.20 "); 
      break;
    case ADXL345_DATARATE_0_10_HZ:
      Serial.print  ("0.10 "); 
      break;
    default:
      Serial.print  ("???? "); 
      break;
  }  
  Serial.println(" Hz");  
}

void displayRange(void)
{
  Serial.print  ("Range:         +/- "); 

  switch(accel.getRange())
  {
    case ADXL345_RANGE_16_G:
      Serial.print  ("16 "); 
      break;
    case ADXL345_RANGE_8_G:
      Serial.print  ("8 "); 
      break;
    case ADXL345_RANGE_4_G:
      Serial.print  ("4 "); 
      break;
    case ADXL345_RANGE_2_G:
      Serial.print  ("2 "); 
      break;
    default:
      Serial.print  ("?? "); 
      break;
  }  
  Serial.println(" g");  
}

void setup(void) 
{
  Serial.begin(9600);
  Serial.println("Accelerometer Test"); Serial.println("");

  /* Initialise the sensor */
  if(!accel.begin())
  {
    /* There was a problem detecting the ADXL345 ... check your connections */
    Serial.println("Ooops, no ADXL345 detected ... Check your wiring!");
    while(1);
  }

  /* Set the range to whatever is appropriate for your project */
  accel.setRange(ADXL345_RANGE_16_G);
  // displaySetRange(ADXL345_RANGE_8_G);
  // displaySetRange(ADXL345_RANGE_4_G);
  // displaySetRange(ADXL345_RANGE_2_G);

  /* Display some basic information on this sensor */
  displaySensorDetails();

  /* Display additional settings (outside the scope of sensor_t) */
  displayDataRate();
  displayRange();
  Serial.println("");
}

void loop(void) 
{
  /* Get a new sensor event */ 
  sensors_event_t event; 
  accel.getEvent(&event);

  /* Display the results (acceleration is measured in m/s^2) */
  Serial.print("X: "); Serial.print(event.acceleration.x); Serial.print("  ");
  Serial.print("Y: "); Serial.print(event.acceleration.y); Serial.print("  ");
  Serial.print("Z: "); Serial.print(event.acceleration.z); Serial.print("  ");Serial.println("m/s^2 ");
  delay(500);
}

動作確認

スケッチをコンパイル後、シリアルモニタを起動してスケッチを書き込みましょう
すると X, Y, Z に対する加速度が数値で表示されます
wroom_with_adxl345_serial.png

ちなみに上記の値はブレッドボードを机の上においた状態の値です
ブレッドボードを縦にしてみると X 軸の加速度が 10 くらいに上がるのが確認できると思います

最後に

ESP-WROOM-02 と ADXL345 で加速度センサを試してみました
WROOM は Arduino 互換なので前回使ったスケッチもそのまま使えると思います
あとは Wifi と連携してある加速度の時に何かリクエストするとか簡単にできると思います

参考サイト

2017年3月9日木曜日

ESP-WROOM-02 で MacAddress を取得する方法

概要

Arduino スケッチを使って取得する方法を紹介します

環境

  • ESP-WROOM-02開発ボード
  • Mac OS X 10.11.3
  • Arduino IDE 1.6.7
  • Arduino core for ESP8266 2.1.0

スケッチ

#include <ESP8266WiFi.h>

uint8_t MAC_softAP[] = {0, 0, 0, 0, 0, 0};
uint8_t MAC_STA[] = {0, 0, 0, 0, 0, 0};

void setup() {
    Serial.begin(115200);
    Serial.println();

    Serial.print("MAC[SoftAP]");
    uint8_t* MAC = WiFi.softAPmacAddress(MAC_softAP);
    for (int i = 0; i < sizeof(MAC) + 2; ++i) {
         Serial.print(":");
         Serial.print(MAC[i],HEX);
         MAC_softAP[i] = MAC[i];
    }
    Serial.println();
    Serial.print("MAC[STA]");
    MAC = WiFi.macAddress(MAC_STA);
    for (int i = 0; i < sizeof(MAC) + 2; ++i) {
         Serial.print(":");
         Serial.print(MAC[i],HEX);
         MAC_STA[i] = MAC[i];
    }
    Serial.println();
}

void loop() {

}

実行すると一度だけ MacAddress を表示します

wroom_get_mac_address.png

一応何度かスケッチを書き込み直してみましたが、毎回同じ値が取得できました
おそらく被ることはないのでこれを使えば、どの WROOM から送られてきたデータなのかが判断できるようになると思います

参考サイト

ESP-WROOM-02 で圧力センサーを使ってみた

概要

ESP-WROOM-02 のアナログリードを使って圧力センサー (FSR402) と連携してみました
あるある程度の圧力が加わった時に MQTT にその値を Publish してみます
事前に WROOM の Arduino化アナログリードWROOM からの MQTT 接続 あたりの設定を実施しておいてください

環境

配線

配線の全体図は以下の通り
アナログリードなので WROOM の TOUT に入る電圧を分圧回路を使って 1.1 V に下げています
抵抗は全部同じで 10KΩを使用しています
wroom_with_fsr402_circuit.jpg

FSR402 は電極があるので気をつけてください
写真ではちょっと見えないのですが FSR402 の接触部に線が書いてある方を上にして右 (赤) がプラスで左 (青) がマイナス側になります
今回はマイナス側から値を取得します

スケッチ

スケッチ全体は以下の通りです
設定しなければならないのは冒頭の Wifi の設定と MQTT のブローカの設定になります
それ以外は特に変更しないで動作すると思います


#include <ESP8266WiFi.h>
#include <PubSubClient.h>
extern "C" {
  #include "user_interface.h"
}

const char* ssid = "ssid";
const char* password = "password";
const char* mqtt_server = "mqtt_server";
const int mqtt_port = 1883;
const char* mqtt_pub_topic = "mqtt_pub_topic";
const char* mqtt_username = "mqtt_username";
const char* mqtt_password = "mqtt_password";

WiFiClient espClient;
PubSubClient client(espClient);
char msg[50];

void setup_wifi() {
  delay(10);
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

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

void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect
    if (client.connect("ESP8266Client", mqtt_username, mqtt_password)) {
      Serial.println("connected");
      // Once connected, publish an announcement...
      client.publish(mqtt_pub_topic, "test");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

void setup() {
  Serial.begin(115200);
  setup_wifi();
  client.setServer(mqtt_server, mqtt_port);
}

int getToutValue(){
  int res = system_adc_read();
  return res; 
}

void loop() {
  if (!client.connected()) {
    reconnect();
  }
  client.loop();
  int val= getToutValue();
  if (val > 500) {
    Serial.print("value:");
    Serial.println(val);
    snprintf (msg, 75, "Analog value #%ld", val);
    client.publish(mqtt_pub_topic, msg);
  }
  delay(200); 
}

動作確認

シリアルモニタを起動してボーレードを 115200 に設定してください
スケッチを書き込み成功すると以下のように表示されると思います
wroom_with_fsr402_serial.png

Wifi 接続後 MQTT に接続します
今回は読み込んだアナログの値が 500 以上になった場合にシリアルモニタへの表示 + MQTT への Publish を行います
圧力センサーを少し押してみましょう
すると MQTT への Publish が開始されると思います

最後に

ESP-WROOM-02 のアナログリードを使って圧力センサーを試してみました
前回のアナログリード用の配線をそのまま使えたので簡単にできました

ESP-WROOM-02 で MQTT にメッセージを Publish してみた

概要

前回 WROOM を Arduino 化して実際に Wifi に接続するところまで試しました
今回のその応用としてネットワークにつながった WROOM からインターネット上の MQTT のブローカにメッセージを Publish してみました

環境

事前作業

前回の作業+今回は MQTT のブローカも必要になります
無料で使える MQTT as a Service は結構あります
今回は Sango を使ってみました (Sango を使う場合は Github のアカウントが必要になります)
ブローカに接続するための認証情報も Sango ベースの設定になっているので、そのあたりは適宜変更してください

Arduino Client for MQTT のインストール

まず Arduino IDE に MQTT ライブラリを追加します
https://github.com/knolleary/pubsubclient/releases/latest から最新の zip ファイルをダウンロードしましょう
wroom_try_mqtt_download_zip.png

本記事執筆時点でのバージョンは 2.6 でした
Arduino IDE にライブラリを追加するのに zip を解凍する必要はありません

ダウンロードが完了したら Arduino IDE を起動して

スケッチ -> ライブラリをインクルード -> .ZIP形式のライブラリをインクルード

と選択してダウンロードした zip ファイルを選択してください
特に IDE にエラーが出なければインクルード完了です

ライブラリをインクルードの選択肢に「PubSubClient」が追加されており、ファイル -> スケッチの例にも「PubSubClient」が追加されていれば OK です

スケッチの作成

今回はスケッチの例にある「mqtt_esp8266」をベースにスケッチを作成しました
スケッチの全体は以下の通りです

#include <ESP8266WiFi.h>
#include <PubSubClient.h>

const char* ssid = "ssid";
const char* password = "ssid-password";
const char* mqtt_server = "lite.mqtt.shiguredo.jp";
const int mqtt_port = 1883;
const char* mqtt_pub_topic = "yourGithubAccount@github/esp8266";
const char* mqtt_sub_topic = "yourGithubAccount@github/esp8266_sub";
const char* mqtt_username = "yourGithubAccount@github";
const char* mqtt_password = "yourBrokerPassword";

WiFiClient espClient;
PubSubClient client(espClient);
long lastMsg = 0;
char msg[50];
int value = 0;

void setup_wifi() {
  delay(10);
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

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

void callback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");
  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);
  }
  Serial.println();

  // Switch on the LED if an 1 was received as first character
  if ((char)payload[0] == '1') {
    digitalWrite(BUILTIN_LED, LOW);   // Turn the LED on (Note that LOW is the voltage level
    // but actually the LED is on; this is because
    // it is acive low on the ESP-01)
  } else {
    digitalWrite(BUILTIN_LED, HIGH);  // Turn the LED off by making the voltage HIGH
  }
}

void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect
    if (client.connect("ESP8266Client", mqtt_username, mqtt_password)) {
      Serial.println("connected");
      // Once connected, publish an announcement...
      client.publish(mqtt_pub_topic, "hello world");
      // ... and resubscribe
      client.subscribe(mqtt_sub_topic);
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

void setup() {
  pinMode(BUILTIN_LED, OUTPUT);     // Initialize the BUILTIN_LED pin as an output
  Serial.begin(115200);
  setup_wifi();
  client.setServer(mqtt_server, mqtt_port);
  client.setCallback(callback);
}

void loop() {
  if (!client.connected()) {
    reconnect();
  }
  client.loop();

  long now = millis();
  if (now - lastMsg > 10000) {
    lastMsg = now;
    ++value;
    snprintf (msg, 75, "hello world #%ld", value);
    Serial.print("Publish message: ");
    Serial.println(msg);
    client.publish(mqtt_pub_topic, msg);
  }
}

ポイント説明

スケッチ冒頭にある Wifi とブローカの情報を各自の環境に合わせて設定してください

setup() で Wifi の接続と MQTT への接続の準備を行います
Wifi の接続に成功すると取得できた IP アドレスを表示します

loop() ではまず MQTT への接続を行います
接続状態になっていれば接続処理はスルーします
reconnect メソッドで接続処理を行っており、設定したブローカ情報がおかしい場合は再接続をし続けるので、再度スケッチの設定を見なおしてください

reconnect 内で接続が成功するとまず pub/sub を 1 回行います
Subscribe は callback メソッドを設定しており、メッセージが到着すると callback メソッドが呼ばれます

loop() 内で 10 秒おきに Publish を続けます
メッセージは固定で「hello world #N」を送信します
N は送信したメッセージのカウントになので、送信ごとにインクリメントされます

動作確認

スケッチをコンパイルし問題なければ書き込みを開始しましょう
開始する前にシリアルモニタを開いておきましょう
改行を CRおよびLF に設定し、ボーレートを 115200 にします

書き込みが成功すると Wifi に接続を試みます
Wifi への接続が成功すると次に MQTT への接続を試みます
MQTT への接続が成功するとメッセージの Publish が 10 秒おきに行われます
wroom_try_mqtt_debug_serial.png

シリアルモニタはこんな感じで表示され続けます

最後に

紹介は以上です
WROOM を Arduino 化したおかげで Arduino 用のライブラリも WROOM で簡単に使えるようになったで非常に簡単に MQTT も使えるようになりました

一応試してみた感じだと、長時間起動しっぱなしでも特に問題なく動作しており、電源も入れなおすと自動でスケッチが起動して MQTT への Publish も再開されました

参考サイト

ESP-WROOM-02 がリチウムイオンポリマー電池で動作するか検証

概要

400mAh のリチウムイオンポリマー電池が ESP-WROOM-02 で動作するか検証してみました

環境

今回はブレッドボード上でリチウムイオンポリマー電池を動作させるためピッチ変換基盤を使います

ピッチ変換基盤のハンダ付け

lithium_with_wroom_connector_handa.jpg

ヘッダピンの部分を 4 箇所ハンダ付けすれば OK です
なぜか 6 ピンだったので 4 ピンにニッパで切り落としてからハンダしました

リチウムイオンポリマー電池の充電

MicroUSB を普通にコンセントに接続して充電します
充電中は LED が赤色に点灯するようです
lithium_with_wroom_charging.jpg

充電が完了したら LED が消灯します
フル充電まで 1 時間ほどかかりました

コネクタを使って WROOM と配線する

リチウムイオンポリマー電池を使った配線の全体図は以下の通りです
lithium_with_wroom_circuit.jpg

大本の配線は光センサを使ったアナログリードの配線になっています
この配線から電源部分だけをリチウムイオンポリマー電池に交換します

あたりまえですが、microUSB で供給していた電源を抜いてください

簡単に説明すると

  • コネクタGND -> WROOM GND
  • コネクタ + -> WROOM VIN

に接続してください
それ以外の配線は前回の配線のままになります
あとはコネクタにリチウムイオンポリマー電池を繋げば勝手に電源が入って WROOM が起動するはずです
自分はこの配線で問題なく光センサが動作することを確認しました

最後に

ESP-WROOM-02 をリチウムイオンポリマー電池で動作させてみました
今回使ったコネクタはボード上にスイッチも実装されているため電源の ON/OFF も制御できます
「コネクタ + -> WROOM VIN」だった配線を「コネクタ SW -> WROOM VIN」に変更するだけでスイッチを使うことができます

最近使い始めた ESP-WROOM-02 ですが、リチウムイオンポリマー電池でも動くとなるといよいよこれ以外を使う理由がなくなってきました

Tips

プログラムにもよりますが連続稼働の時間を計測してみました
フル充電の状態からずっと WROOM を置きっぱなしにしてみたところ約 5 時間半で充電がなくなり WROOM が停止しました
単純なプログラムでも 1 日連続稼働は厳しいかもしれません

参考サイト

2017年3月8日水曜日

ESP-WROOM-02 で 16 チャネルアナログマルチプレクサを使ってみた

概要

前回 Arduino で 16チャネル アナログマルチプレクサ (CD74HC4067) を使ってみました
今回は Arduino 互換性のある ESP-WROOM-02 で動作確認してみました
結論的には動きました

環境

配線

配線の全体図は以下の通りです
今回ブレッドボードが小さくかなり無理やり配線しています
また、スイッチも 2 つしか配置できなかったので、サンプルも 2ch 分読み込むものになっています
wroom_with_mux_circuit1.jpg

wroom_with_mux_circuit2.jpg

写真だとごちゃごちゃに見えますがそこまで難しい配線ではないです

  • WROOM Vout -> ブレッドボード [+]
  • WROOM GND -> ブレッドボード [-]
  • WROOM GND -> ブレッドボード [-]
  • WROOM TOUT -> Mux SIG
  • WROOM 12 -> Mux S0
  • WROOM 13 -> Mux S1
  • WROOM 14 -> Mux S2
  • WROOM 15 -> Mux S3
  • Mux VCC -> ブレッドボード [+]
  • Mux GND -> ブレッドボード [-]
  • Mux EN -> ブレッドボード [-]

が WROOM と Mux の配線です
あとはスイッチの配線をすれば OK です
写真だとかなり隙間を縫って配線しています

  • ブレッドボード [+] -> スイッチ片側
  • ブレッドボード [-] -> 抵抗1KΩ -> ジャンパ -> ch0, ジャンパ -> スイッチ片側

で、ch0 と ch1 分配置しています

スケッチ

WROOM のスケッチは以下の通りです

extern "C" {
  #include "user_interface.h"
}

//Mux control pins
int s0 = 12;
int s1 = 13;
int s2 = 14;
int s3 = 15;

int muxChannel[16][4] = {
  {0, 0, 0, 0}, //channel 0
  {1, 0, 0, 0}, //channel 1
  {0, 1, 0, 0}, //channel 2
  {1, 1, 0, 0}, //channel 3
  {0, 0, 1, 0}, //channel 4
  {1, 0, 1, 0}, //channel 5
  {0, 1, 1, 0}, //channel 6
  {1, 1, 1, 0}, //channel 7
  {0, 0, 0, 1}, //channel 8
  {1, 0, 0, 1}, //channel 9
  {0, 1, 0, 1}, //channel 10
  {1, 1, 0, 1}, //channel 11
  {0, 0, 1, 1}, //channel 12
  {1, 0, 1, 1}, //channel 13
  {0, 1, 1, 1}, //channel 14
  {1, 1, 1, 1} //channel 15
};

void setup() {
  pinMode(s0, OUTPUT);
  pinMode(s1, OUTPUT);
  pinMode(s2, OUTPUT);
  pinMode(s3, OUTPUT);

  digitalWrite(s0, LOW);
  digitalWrite(s1, LOW);
  digitalWrite(s2, LOW);
  digitalWrite(s3, LOW);

  Serial.begin(115200);
}

void loop() {
  int ch_count = 2;
  for (int i = 0; i < ch_count; i ++) {
    Serial.print("Value at channel ");
    Serial.print(i);
    Serial.print("is : ");
    Serial.println(readMux(i));
    delay(1000);
  }
}

int getToutValue(){
  int res = system_adc_read();
  return res;
}

int readMux(int channel) {
  int controlPin[] = {s0, s1, s2, s3};
  //loop through the 4 sig
  for (int i = 0; i < 4; i ++) {
    digitalWrite(controlPin[i], muxChannel[channel][i]);
  }
  //read the value at the SIG pin
  int val= getToutValue();
  //return the value
  return val;
}

ポイントは WROOM でアナログリードするために system_adc_read を使っている部分です
過去 に WROOM でアナログリードする方法を紹介しましたが、そのときの方法を使っています

あとは Mux をコントロールする s0 - s3 のピンは Arduino のときは 8 から 11 でしたが、WROOM ではないので 12 - 15 を使うように変更しています

動作確認

スケッチを書き込んで動作確認してみます
ボーレートは 115200 にしてシリアルモニタを起動します
wroom_with_mux_serial.png

今回はブレッドボード上の配線の問題でスイッチは 2 つしか使っていないので 2ch 分のスイッチを押して動作確認してみてください
押しているときは 1024 になり、そうでないときは 0 になると思います

最後に

WROOM でも 16チャネルアナログマルチプレクサが動作することを確認しました

Arduino のときと挙動が違ったのは使わないチャネルがある場合は読み込みを行わないようにしなければいけないことでした
例えば 2ch 使いたい場合は 0, 1 ch を使いかつ、0, 1 ch には必ず配線がされていないと WROOM の TOUT から取得できる値がかなり不安定になりました

なので 2ch 使いたい時に 0ch と 15ch を使って 0ch から 15ch まで順番に読み込むようなスケッチになっていると途中の 1ch から 14ch までの値がおかしな値になってしまいます

そもそも使っていないチャネルの情報を読み込む処理をする時点で無駄なので、使うチャネル分だけ読み込むような処理にするようにしてください

ESP-WROOM-02 でアナログリードを試してみた

概要

ESP-WROOM-02 には TOUT というピンが 1 ピンだけあり、これでアナログ情報を読み込むことができます
ただ、Arduino 化しても analogRead() 関数で読み込むことはできず system_adc_read() という関数を使って読み込むことができます
今回は光センサを使って、明るさの情報を TOUT を使って読み込んでみました

環境

配線

全体の配線はこんな感じです
wroom_analog_read_circuit.jpg

ポイントは TOUT のピンに対する入力は 1.1V の電圧以内にする必要があるということです
今回は 3.3V の電圧を 1/3 にする分圧回路を組んでいます

WROOM の 3.3V -> 10KΩ -> 光センサの片方

と接続されており、光センサのもう片方は

光センサのもう片方 -> WROOM の TOUTへ

でここから更に分岐して

光センサのもう片方 -> 10KΩ x2 の並列抵抗 -> WROOM の GND

という接続になっています
全抵抗を 10KΩに統一して、GND 側に繋がる抵抗を並列抵抗にすることで、その間にかかる抵抗を 1/3 にすることができます

アナログリードするスケッチ

配線できたらスケッチを作成しましょう
スケッチの全体は以下の通りです

extern "C" {
  #include "user_interface.h"
}

void setup() {
  Serial.begin(115200);
}

int getToutValue(){
  int res = system_adc_read();
  return res;
}

void loop() {
  int val= getToutValue();
  Serial.print("value:");
  Serial.println(val);
  delay(200);
}

短いコードなので特に説明の必要はないですが、冒頭で system_adc_read を呼び出すために C 用のライブラリ user_interface.h を include しています

TOUT の値を 200ms 間隔で読み込んでシリアルモニタに出力しているだけです

動作確認

スケッチをコンパイルして WROOM に書き込んでみましょう
書き込む前にシリアルモニタを起動しておいてください

ちゃんと配線できていれば以下のように光センサで読み込んだ値が表示されると思います
wroom_analog_read_serial.png

分解能は 10bit なので 最大で 1024 になります
明るいほど値は大きくなり、暗くなると値が小さくなります

最後に

WROOM の唯一のアナログピンを使ってセンサデータを読み込んでみました
問題なく動作はしますが、入力電圧が 1.1V なのには注意する必要がありそうです

参考サイト

2017年1月31日火曜日

ESP-WROOM-02 で赤外線 LED を制御してエアコンを操作してみた

概要

前回 Arduino で赤外線 LED を使って Panasonic のエアコンを制御しました
今回は同じように赤外線 LED を ESP-WROOM-02 (ESPr) で使って制御してみました

環境

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

Arduino のときに IRremote というライブラリを使いましたが、これは ESPr だと使えません
IRremoteESP8266 という専用のライブラリがあるのでこれを使います

Arduino IDE からインストールすることはできないので、Github から zip ファイルをダウンロードしましょう
そして

スケッチ -> ライブラリをインクルード -> .ZIP 形式のライブラリをインストール

でダウンロードした zip ファイルを選択してインストールしましょう
インストールが完了すると IRremoteESP8266.h が include できるようになります

配線

今回の配線は以下の通りです

上から
try_ir_with_espr_circuit1.jpg

サイドから
try_ir_with_espr_circuit2.jpg

逆サイドから
try_ir_with_espr_circuit3.jpg

基本は Arduino ときと同じなのですが、スイッチを 2 つ (冷房の起動と停止) にしたのとトランジスタを使って赤外線 LED の出力を増幅しています

これはあとで気づいたのですが、Arduino と ESPr では ESPr のほうが赤外線の出力が弱いです
なので、ESPr のときはトランジスタを使って赤外線の出力強度をあげています

送信用スケッチ

今回のスケッチは以下の通りです
440 バイト分の配列 start と stop はそれぞれエアコンの冷房ボタンと停止ボタンを学習した信号になります
赤外線の信号の学習は赤外線受信モジュールを使って事前に Arduino で行いました
Arduino + 赤外線受信モジュールを使って信号を学習する方法はこちらを参考にしてください

#include <IRremoteESP8266.h>

int START = 12;
int STOP = 14;
int khz = 38;
IRsend irsend(4);
unsigned int stop[440] = {3568, 1680, 512, 400, 476, 1244, 512, 404, 476, 408, 476, 404, 480, 372, 508, 404, 476, 408, 476, 404, 476, 404, 476, 376, 508, 376, 508, 372, 508, 1244, 512, 400, 476, 380, 504, 408, 476, 404, 476, 404, 476, 408, 476, 404, 476, 1244, 512, 1244, 508, 1252, 508, 376, 504, 376, 504, 1244, 512, 408, 476, 404, 476, 404, 476, 408, 472, 412, 476, 404, 476, 376, 504, 404, 476, 380, 504, 376, 508, 404, 476, 404, 476, 380, 504, 404, 476, 376, 504, 408, 472, 380, 508, 372, 508, 404, 476, 376, 504, 380, 504, 376, 504, 408, 476, 372, 508, 380, 504, 376, 504, 376, 504, 408, 476, 408, 476, 372, 508, 1244, 508, 1248, 508, 408, 476, 404, 476, 408, 472, 376, 508, 372, 504, 9976, 3564, 1684, 508, 376, 504, 1248, 508, 376, 504, 408, 476, 408, 472, 376, 504, 380, 504, 408, 476, 404, 476, 404, 476, 376, 504, 380, 508, 404, 472, 1248, 508, 376, 508, 380, 504, 376, 504, 376, 504, 376, 504, 380, 504, 404, 476, 1244, 512, 1244, 508, 1252, 508, 404, 476, 404, 476, 1248, 508, 380, 504, 404, 476, 408, 472, 408, 476, 408, 476, 376, 504, 404, 476, 404, 476, 380, 504, 376, 504, 376, 508, 404, 476, 380, 504, 376, 504, 408, 472, 376, 508, 408, 472, 1248, 508, 1248, 508, 404, 476, 380, 504, 408, 472, 376, 504, 1248, 508, 408, 476, 1244, 508, 1248, 508, 404, 476, 380, 508, 372, 508, 404, 476, 404, 476, 408, 476, 408, 476, 404, 476, 404, 472, 1256, 508, 404, 476, 1248, 508, 404, 476, 408, 476, 408, 476, 372, 504, 1248, 508, 408, 476, 408, 476, 404, 472, 408, 476, 380, 504, 376, 504, 404, 480, 372, 508, 408, 476, 404, 476, 404, 476, 404, 476, 380, 508, 404, 476, 404, 476, 376, 504, 380, 504, 404, 476, 1244, 512, 1244, 508, 380, 508, 404, 476, 376, 504, 372, 508, 408, 476, 408, 476, 404, 476, 404, 476, 408, 476, 404, 476, 1244, 508, 1244, 512, 408, 476, 408, 472, 376, 508, 404, 476, 380, 504, 404, 476, 408, 472, 408, 476, 408, 476, 404, 476, 372, 508, 404, 476, 412, 476, 372, 508, 404, 476, 372, 508, 408, 476, 404, 476, 404, 476, 408, 476, 408, 476, 376, 504, 404, 476, 404, 476, 1248, 512, 404, 476, 404, 476, 408, 476, 408, 480, 404, 476, 376, 504, 404, 476, 380, 508, 404, 472, 1244, 512, 1244, 512, 412, 476, 404, 476, 372, 508, 404, 476, 412, 476, 376, 504, 404, 476, 404, 476, 1252, 508, 1248, 508, 404, 476, 404, 476, 376, 508};
unsigned int start[440] = {3584, 1664, 532, 352, 524, 1228, 528, 388, 492, 392, 496, 384, 492, 388, 492, 392, 488, 396, 492, 388, 492, 388, 492, 388, 492, 392, 492, 388, 492, 1224, 528, 392, 492, 392, 492, 388, 492, 388, 492, 388, 492, 364, 520, 388, 492, 1228, 524, 1228, 528, 1232, 528, 388, 492, 388, 488, 1228, 532, 360, 524, 388, 488, 360, 524, 388, 492, 360, 524, 388, 492, 388, 496, 388, 488, 360, 524, 360, 524, 388, 492, 388, 412, 472, 492, 388, 492, 388, 492, 360, 520, 364, 520, 392, 492, 388, 488, 360, 524, 392, 492, 392, 488, 388, 496, 388, 416, 468, 412, 468, 412, 436, 524, 388, 492, 392, 492, 388, 488, 1232, 528, 1228, 524, 392, 492, 392, 412, 468, 488, 360, 520, 388, 492, 9956, 3584, 1660, 528, 392, 412, 1304, 528, 388, 492, 360, 524, 360, 520, 392, 492, 356, 444, 440, 520, 392, 488, 360, 524, 388, 416, 440, 520, 388, 492, 1228, 524, 392, 492, 392, 492, 388, 488, 396, 412, 468, 412, 472, 488, 392, 488, 1228, 524, 1228, 528, 1232, 528, 388, 492, 388, 488, 1232, 524, 364, 520, 392, 416, 464, 492, 388, 416, 468, 492, 392, 488, 360, 520, 360, 520, 364, 520, 360, 524, 388, 492, 388, 416, 468, 416, 1304, 448, 468, 488, 392, 488, 396, 488, 1228, 452, 1304, 448, 436, 448, 472, 412, 468, 412, 464, 492, 1228, 528, 360, 520, 1228, 452, 1304, 448, 468, 492, 360, 520, 392, 488, 396, 412, 468, 412, 472, 488, 356, 448, 468, 488, 392, 488, 1240, 524, 388, 416, 1304, 452, 464, 488, 364, 520, 360, 448, 464, 416, 1304, 524, 364, 448, 468, 412, 468, 488, 388, 492, 364, 520, 392, 412, 468, 412, 468, 416, 468, 488, 364, 444, 436, 444, 468, 488, 396, 412, 468, 412, 468, 488, 360, 448, 436, 448, 464, 412, 1304, 452, 1304, 528, 360, 524, 388, 416, 468, 412, 468, 412, 440, 444, 468, 412, 468, 416, 432, 448, 472, 412, 464, 488, 1228, 452, 1304, 452, 472, 412, 468, 412, 468, 488, 392, 412, 472, 412, 468, 488, 364, 444, 464, 416, 472, 412, 468, 412, 468, 412, 468, 412, 472, 416, 468, 412, 432, 448, 468, 412, 440, 444, 468, 412, 468, 412, 468, 412, 472, 416, 464, 416, 468, 412, 464, 416, 1308, 524, 396, 412, 464, 416, 468, 412, 472, 416, 468, 412, 468, 412, 468, 412, 472, 416, 464, 416, 1304, 448, 1304, 524, 400, 416, 432, 448, 464, 416, 468, 412, 472, 412, 1308, 448, 468, 412, 468, 412, 1308, 452, 1304, 452, 468, 412, 468, 412, 468, 412};

void setup() {
  irsend.begin();
  pinMode(START, INPUT);
  pinMode(STOP, INPUT);
  Serial.begin(115200);
}

void loop() {
  if (digitalRead(START) == HIGH) {
    Serial.println("START");
    irsend.sendRaw(start, sizeof(start) / sizeof(start[0]), khz);
  } else if (digitalRead(STOP) == HIGH) {
    Serial.println("STOP");
    irsend.sendRaw(stop, sizeof(stop) / sizeof(stop[0]), khz);
  }
  delay(500);
}

赤外線 LED の信号送信は 4 ピンで制御しています
タクトスイッチはそれぞれ 12, 14 ピンで制御しています

Arduino とほぼ同じように使えるのですが、若干違うところもあります
IRsend irsend(4); という感じで赤外線を送信するピンを指定することができます
Arduino のときは 3 ピン固定でした
また、irsend.begin(); で赤外線 LED を使うことを宣言する必要があります

動作確認

スケッチを書き込んでエアコンに向けてスイッチを押してみましょう
リモコンの信号がちゃんと学習できていればエアコンの起動と停止ができるはずです
今回はトランジスタで信号を増幅しているので距離は数メートル離れても大丈夫でした
自宅で試した感じだと 4 - 5m は全然大丈夫でした

最後に

ESPr で赤外線 LED を制御してみました
ほぼ Arudino と同じように制御できますが、完全互換では動作しませんでした
また、信号の出力が弱いのでトランジスタを挟んだほうが良いです

あとはこれに MQTT を Subscribe する機能を設けて扇風機のときのようにネットから制御できるようにしたいと思います

参考サイト

ESP-WROOM-02 と Arduino Pro mini で DC モータを制御してみた

概要

前回 Arduino を使って制御しましたが、今回は例のごとく「ESP-WROOM-02」と「Arduino Pro mini」で制御してみました
完全互換で動作したので配線だけ紹介します

環境

  • ESP-WROOM-02
  • Arduino Pro mini
  • Arduino IDE 1.6.9
  • トランジスタ 2N5088 x 1
  • 一般用整流ダイオード 1N4007 x 1
  • 抵抗 1kΩ x 1

ESP-WROOM-02 と DC モータの配線

esp_with_dcmotor_circuit.jpg

Arduino Pro mini と DC モータの配線

promini_with_dcmotor.jpg

最後に

久しぶりに完全互換で動作しました
ともに 5v の出力もできるので、モータの動きが鈍い場合は電源を 5v にあげてみてください

2017年1月29日日曜日

ESP-WROOM-02 のピッチ変換フル版を Arduino 化してみた

概要

前回フル版で AT コマンドが送信できるまでやってみました
今回はフル版を Arduino 化して Arduino スケッチが動作するようにしてみたいと思います

環境

Arduino IDE で ESP8266 を扱えるようにする方法はこちらを参考に事前にセットアップしておいてください

配線

ほぼ前回と同じですが違う点が 2 点あります
try_esp_full_ver_arduino_circuit.jpg

Arduino のスケッチを書き込むために「UART Download Mode」にする必要があります
これにするには

  1. IO0 ピンを GND に接続
  2. RST ピンを GND に接続 -> 抜く

ということを行う必要があります
これをすることで ESP-WROOM-02 のモードが変わります

スケッチ

Wifi に接続して MQTT に Publish できるか確認するスケッチです
ここは各自で確認しやすいスケッチにしてください

単純に GPIO (IO14) とかを制御して LED を点滅させるだけでも OK です

#include <ESP8266WiFi.h>
#include <PubSubClient.h>

const char* ssid = "ssid";
const char* password = "ssid password";
const char* mqtt_server = "your.mqtt.broker";
const int mqtt_port = 1883;
const char* mqtt_pub_topic = "pub_topic";
const char* mqtt_username = "broker username";
const char* mqtt_password = "broker password";

WiFiClient espClient;
PubSubClient client(espClient);
long lastMsg = 0;
char msg[50];
int value = 0;

void setup_wifi() {
  delay(10);
  WiFi.begin(ssid, password);
}

void reconnect() {
  while (!client.connected()) {
    if (client.connect("ESP8266Client", mqtt_username, mqtt_password)) {
      client.publish(mqtt_pub_topic, "hello world");
    } else {
      delay(5000);
    }
  }
}

void setup() {
  Serial.begin(115200);
  setup_wifi();
  client.setServer(mqtt_server, mqtt_port);
}

void loop() {
  if (!client.connected()) {
    reconnect();
  }
  client.loop();

  long now = millis();
  if (now - lastMsg > 10000) {
    lastMsg = now;
    ++value;
    snprintf (msg, 75, "hello world #%ld", value);
    Serial.print("Publish message: ");
    Serial.println(msg);
    client.publish(mqtt_pub_topic, msg);
  }
}

Arduino IDE から書き込めるか確認してみましょう
ちゃんとモードが変わっている場合は問題なく書き込めると思います
モードが変わっていないと以下のようなエラーが発生すると思います

warning: espcomm_sync failed
error: espcomm_open failed
error: espcomm_upload_mem failed

最後に

ESP-WROOM-02 のフル版を Arduino 化してみました

面倒なのはスケッチを一度書き込むと実行するためにモードが「Flash Boot Mode」に戻ってしまいます
なので再度スケッチを書き込む場合は RST ピンをまた GND に接続させて抜く必要があります
この辺は開発ボードを使っているとわかるのですが、スイッチ等を実装しておくと押すだけでモードを切り替えられるようになるので楽です

まだフル版でガッツリ開発していないので何とも言えないのですが、フル版はいろいろ面倒です
もし、今回の配線を崩してしまった場合、またフル版で開発したいと思ったら同じ配線をブレッドボード上にしなければなりません
開発ボードの場合、スケッチを書き込むだけであればそんなことは必要ありません
このままブレッドボード上に配線しっぱなししてもいいのですが、それもちょっと、、、

大量に使う場合とか、スケッチをもう書き換える必要がない場合などはフル版の方が安くて小型なので、良いと思います
ゴリゴリスケッチを書き換えたり配線を変える場合は、やはりフル版よりかは開発ボードのほうが断然簡単なのでオススメです

ESP-WROOM-02 を Arduino 化して Wifi に接続してみる

概要

前回 WROOM が Mac で動作するところまで実施しました
今回は Arduino IDE で Wifi に接続するスケッチを作成して WROOM に書き込み実際に Wifi に接続するところまで確認してみます
また、この作業を実施すると WROOM が Arduino 化され前回実施した AT コマンドでの操作ができなくなるので注意してください

環境

Arduino core for ESP8266 のインストール

まずは Arduino IDE に ESP8266 を開発するためのボードタイプを追加します

Arduino -> Preferences -> Settings -> Additional Boards Manager URLs

に以下を記載します

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

OK で追加した

ツール -> マイコンボード -> ボードマネージャー

から esp8266 で検索して新規のボードタイプをインストールします
wroom_con_wifi_install_esp8266_board.png

インストールボタンをクリックするとダウンロードが始まります
プログレスバーが 100% になりダウンロードが完了すればインストール完了です

Arduino core for ESP8266 の設定

各種設定していきます
「ツール」から以下のように設定しましょう

wroom_con_wifi_settings_esp8266.png

  • マイコンボード -> Generic ESP8266 Module
  • Flash Mode -> QIO
  • Flash Frequency -> 80MHz
  • Upload Using -> Serial
  • CPU Frequency -> 160MHz
  • Flash Size -> 4M (3M SPIFFS)
  • Debug port -> Disabled
  • Debug Level -> None
  • Reset Method -> nodemcu
  • Upload Speed -> 115200
  • シリアルポート -> それぞれの環境に合わせてポートを選択してください
  • 書き込み装置 -> USBasp

を設定しました
細かい設定の意味までは確認できていませんが、とりあえず上記の設定で普通の Arduino スケッチを書き込むように WROOM にスケッチを書き込むことができるのを確認しています

スケッチの作成

Arduino IDE の設定ができたらスケッチを作成しましょう
全体は以下の通りです

#include <Arduino.h>
#include <ESP8266WiFi.h>

const char* ssid = "Please input your SSID";
const char* password = "Please input your SSID's password";

boolean continuousResponseFlag = true;

WiFiServer server(80);
WiFiClient client;

void responseHTML() {
  client = server.available();
  delay(1);
  String req;

  while (client) {
    if (client.available()) {
      req = client.readStringUntil('\n');
      Serial.println(req);
      if (req.indexOf("GET / HTTP") != -1) {
        Serial.println("-----from Browser FirstTime HTTP Request---------");
        Serial.println(req);
        while (req.indexOf("\r") != 0) {
          req = client.readStringUntil('\n');
          Serial.println(req);
        }
        req = "";
        delay(10);

        // Headers
        client.print(F("HTTP/1.1 200 OK\r\n"));
        client.print(F("Content-Type:text/html\r\n"));
        client.print(F("Connection:close\r\n\r\n"));
        // Body
        client.println(F("<!DOCTYPE html>"));
        client.println(F("<html>"));
        client.println(F("<font size=30>"));
        client.println(F("Hello World"));
        client.println(F("</html>\r\n"));

        delay(1);
        client.stop();

        Serial.println("\nGET HTTP client stop--------------------");
        req = "";
        continuousResponseFlag = true;
      }
    }
  }
}

void setup() {
  Serial.begin(115200);
  // Connect to WiFi network
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");

  // Start the server
  server.begin();
  Serial.println("Server started");

  // Print the IP address
  Serial.println(WiFi.localIP());
}

void loop() {
  if (continuousResponseFlag == true) {
      responseHTML();
  } else if (client.available()) {
    Serial.print(client.read());
  }
  delay(1);
}

スケッチを作成したら検証が成功するか確認しましょう

ポイント説明

setup() で指定した SSID への Wifi 接続を試みます
接続が成功すると取得できた IP アドレスをシリアルモニタに出力します
指定した SSID やパスワードが間違っている場合はここで IP が表示されないので、SSID やパスワードがあっているかと、Wifi ルータの設定があっているかなど確認してください

loop() でメインの処理を実行します
loop()responseHTML メソッドを呼び続けます
responseHTML はレスポンス用のクライアントオブジェクトを生成し HTTP のヘッダとボディを生成してレスポンスを返却します

今回は GET / HTTP で GET アクセスのみレスポンスを返却するようにしています
GET リクエストがきたら、リクエスト情報をシリアルに 1 行ずつ出力し、その後 client.print でヘッダ情報とボディ情報を返却します

1 リクエストごとにレスポンス用のクライアントオブジェクトは stop され、すぐに次のクライアントオブジェクトが生成されます

動作確認

検証が成功したら WROOM にアプリを書き込みます
書き込みは普通の Arduino スケッチと同じような書き込みます
シリアルモニタを起動しておきましょう

書き込み中は WROOM の TX と RX 用の LED が点滅します
点滅が終了しシリアルモニタに WROOM が取得した IP アドレスが表示されれば OK です
wroom_con_wifi_get_ip.png

今回は WROOM にアクセスすると HTML を返却するようなアプリにしたので実際にブラウザでアクセスしてみましょう
wroom_con_wifi_responsing.png

こんな感じで「Hello World」が表示されば OK です
もちろんブラウザではなく curl コマンドなどでも OK です
シリアルモニタには以下のように表示されていると思います
wroom_con_wifi_debug_response.png

最後に

ESP-WROOM-02 を Arduino 化してスケッチを作成し、そのスケッチを書き込むことで Wifi につながるところまで確認しました
あとは開発ボード上のピン情報を使って、センサなどと連携し、データが取得できたらクラウドに保存するなどができるといいなと思っています

あと、今回の作業をすると AT コマンドが使えなくなると記載しました
確かに起動すると Arduino スケッチが自動で起動してしまうので、シリアルモニタで AT コマンドは実行できなくなります
AT コマンドでも Wifi の設定などを WROOM に書き込めるので頑張ればできますが、プログラマブルに WROOM を操作できたほうが断然楽だし応用が効くので Arduino 化することをオススメします

Arduino 化を解除して出荷時の状態に戻すことってできるのだろうか・・・

Tips

ハマった点があるので紹介します

  • ESP-WROOM-02 を Mac の USB ポートに接続してもシリアルポートとして認識しない

原因は不明ですが接続しても /dev/cu.usbserial-DA01OF0S が現れずハマリました
解決できた方法は Mac の再起動だけでした
とりあえず発生したら再起動してみてください
なおシリアルポートとして認識していなくても WROOM 自体に書き込んだスケッチは問題なく動作していることは確認しました

参考サイト