Category Archives: ESP8266 Wemos (c) web

Wemos (c8) Weather Station

IoT-Cloud-Mobile Kitに、Weather Station機能を導入する。

オリジナルのコード ThingPulse Weather Station は、温度センサーは  DHT11 を利用する、IoT-Cloud-Mobile KitはBMP280内蔵のため、修正後のコードは TokyoEC Weather Station を参照する。

I2CのOLED端子配列

I2CのOLED端子配列2種類があり:

  1. VCC,GND,SCL,SDA (Wemos, BMP180, BMP280バス直結可能)
  2. GND,VCC,SCL,SDA (NodeMcu直結可能)

1番目は、Wemos直結に適するので、試してみる。

接線 (Wiring) Wemos –> OLED

  1. Wemos 5V —> OLED Vcc
  2. Wemos GND –> OLED GND
  3. Wemos D4 —-> OLED SCL
  4. Wemos D3 —-> OLED SDA

また下記のセッティングは、自分の環境に合わせて設定。

* Begin Settings
const char* WIFI_SSID = "xxxx"; // your ssid
const char* WIFI_PWD = "xxxx"; // your password
const int I2C_DISPLAY_ADDRESS = 0x3c; // OLED I2C address
const int SDA_PIN = 13; // I2C OLED SDA
const int SDC_PIN = 14; // I2C OLED SCL
const float UTC_OFFSET = 9; // JST = +9
const String WUNDERGRROUND_API_KEY = "xxxxx"; // WUNDERGROUND API KEY
const String WUNDERGROUND_COUNTRY = "JP"; // japan
const String WUNDERGROUND_CITY = "Tokyo"; // tokyo
const String THINGSPEAK_CHANNEL_ID = "xxxxx"; // ThingSpeak CHANNEL
const String THINGSPEAK_API_READ_KEY = "xxxxx"; // ThingSpaek API KEY

ESP8266 IoT Study Kit動作確認

ESP8266 IoT Study Kitでも動くようになった。ただし、I2CのSDA、SCLは、実際の結線に合わせて修正すること。

拡大する

Piggyback (おんぶ)動作確認

それから、Piggyback (おんぶ) する形で、OLED接続する方法も上手くいく。

OLEDだけ繋ぐなら、こちら方法はコンパクトでいいでしょう。ピン・ソケット使わない、OLEDとWemos直結すればもっと薄くコンパクトな実装になる。

ESP-WROOM-02 バッテリー付き動作

ESP-WROOM-02に、Weather Station機能を試した。( esp-wroom-02-2-weather-station/ )

内容は、こちら( Wemos (c11) Weather Station )と殆ど同じ、デジタルクロックを追加した。

WeMos (c7) Web Clock

TM1637 7段4桁LED表示はできたけど、もっと何かWeb関係のものができないかと考えていて、時刻の表示くらいできると思って、やってみた。

WeMos (5) TM1637 7段4桁LED表示

WiFiManagerを利用してWiFiに接続。

結線ができるだけ省けると考えて、GPIOのPinから給電を試してみた。

プログラムはこれ、D4の隣はGNDだから、D4をVCCとして利用する様にプログラミングする。

#include <TM1637Display.h>
#include <time.h>
#include "WiFiManager.h"  
 
const int CLK = D2; //Set the CLK pin connection to the display
const int DIO = D3; //Set the DIO pin connection to the display
const int VCC = D4; //Set the VCC pin connection to the display
 
int numCounter = 0;
int numTime = 0;
String time_value;
 
TM1637Display display(CLK, DIO); //set up the 4-Digit Display.
 
void setup()
{
  Serial.begin(115200);
  Serial.println("Hello!");

  WiFiManager wifiManager;
  if(!wifiManager.autoConnect()) {
    Serial.println("failed to connect and hit timeout");
    //reset and try again, or maybe put it to deep sleep
    ESP.reset();
    delay(1000);
  } 

  configTime(0 * 3600, 0, "pool.ntp.org", "time.nist.gov");

  pinMode(VCC, OUTPUT);
  digitalWrite(VCC, HIGH);
  display.setBrightness(0x04); //set the diplay to 0..7 brightness
}
 
 
void loop()
{
  for(numCounter = 0; numCounter < 1000; numCounter++) //Iterate numCounter
  {
    time_t now = time(nullptr);
    String time = String(ctime(&now));
    Serial.println("time:" + time);

    time_t utc, local;
    struct tm *tm_now;
    utc = now;
    local = utc + 9 *60 * 60;   // Tokyo time
    tm_now = localtime(&local);
    numTime = tm_now->tm_hour * 100 + tm_now->tm_min;
    Serial.printf("numTime: %d  ¥n", numTime);

    display.showNumberDecEx(numTime, 0x40); //Display the numCounter value;
    delay(500);
    display.showNumberDecEx(numTime, 0); //Display the numCounter value;
    delay(500);
  }
}

実動する画面:

デスクトップPCの肩に乗せた様子。

 

WeMos (c6) Thingspeak

数回JSON関連の実験をしたが、いざTinyWebDBのAPIの実験を始まると、また引っかかるところが多い。

色々と検索してところ、ThingspeakのAPIサンプルが見つかったので、ちょっと曲がり道して試すことに。

センサーの温度と気圧をThingspeakにアップして、動きを見て見る。

まずThingspeakのアカウントを申請して、THINGSPEAK_API_KEYを取得する。

https://thingspeak.com/users/sign_up

次はサンプルを見ながら、プログラミング。

#include <Adafruit_BMP280.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
 
#define OLED_RESET 0  // GPIO0
Adafruit_SSD1306 OLED(OLED_RESET);

#define BMP_SCK 13
#define BMP_MISO 12
#define BMP_MOSI 11 
#define BMP_CS 10

Adafruit_BMP280 bmp; // I2C
//Adafruit_BMP280 bmp(BMP_CS); // hardware SPI
//Adafruit_BMP280 bmp(BMP_CS, BMP_MOSI, BMP_MISO,  BMP_SCK);


#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>

/***************************
 * Begin Settings
 **************************/

const char* host = "http://api.thingspeak.com";
const char* THINGSPEAK_API_KEY = "***********";

// Update every 600 seconds = 10 minutes. Min with Thingspeak is ~20 seconds
const int UPDATE_INTERVAL_SECONDS = 600;

//needed for library
#include <DNSServer.h>
#include "WiFiManager.h"          //https://github.com/tzapu/WiFiManager

void configModeCallback (WiFiManager *myWiFiManager) {
  Serial.println("Entered config mode");
  Serial.println(WiFi.softAPIP());
  //if you used auto generated SSID, print it
  Serial.println(myWiFiManager->getConfigPortalSSID());
}

/***************************
 * End Settings
 **************************/
 
void setup() {
  OLED.begin();
  OLED.clearDisplay();
 
  //Add stuff into the 'display buffer'
  OLED.setTextWrap(false);
  OLED.setTextSize(1);
  OLED.setTextColor(WHITE);
  OLED.setCursor(0,0);
  delay(10);
  
  Serial.begin(115200);
  delay(10);

  // We start by connecting to a WiFi network

  // Connect to WiFi network
  OLED.println("wifiManager autoConnect...");
  OLED.display(); //output 'display buffer' to screen  
 
  //WiFiManager
  //Local intialization. Once its business is done, there is no need to keep it around
  WiFiManager wifiManager;
  //reset settings - for testing
  //wifiManager.resetSettings();

  //set callback that gets called when connecting to previous WiFi fails, and enters Access Point mode
  wifiManager.setAPCallback(configModeCallback);

  //fetches ssid and pass and tries to connect
  //if it does not connect it starts an access point with the specified name
  //here  "AutoConnectAP"
  //and goes into a blocking loop awaiting configuration
  if(!wifiManager.autoConnect()) {
    Serial.println("failed to connect and hit timeout");
    //reset and try again, or maybe put it to deep sleep
    ESP.reset();
    delay(1000);
  } 

  // Print the IP address
  OLED.print("http://");
  OLED.print(WiFi.localIP());
  OLED.println("/");
  OLED.println("WiFi connected");
  OLED.display(); //output 'display buffer' to screen  
  
  //if you get here you have connected to the WiFi
  Serial.println("connected...yeey :)");

  if (!bmp.begin(0x76)) 
  {
    OLED.println("Could not find BMP180 or BMP085 sensor at 0x77");
    OLED.display(); //output 'display buffer' to screen  
    while (1) {}
  }

}

void loop() {      
  // read values from the sensor
  float pressure = bmp.readPressure();
  float temperature = bmp.readTemperature();
  
  // We now create a URI for the request
  String url = host;
  url += "/update?api_key=";
  url += THINGSPEAK_API_KEY;
  url += "&field1=";
  url += String(temperature);
  url += "&field2=";
  url += String(pressure);
  
  Serial.print("Requesting URL: ");
  Serial.println(url);

  HTTPClient http;
  Serial.print("[HTTP] begin...\n");
  // configure targed server and url
  http.begin(url);
  
  Serial.print("[HTTP] GET...\n");
  // start connection and send HTTP header
  int httpCode = http.GET();

  if(httpCode == HTTP_CODE_OK) {
    String buffer = http.getString();
    Serial.println(buffer);
  }

  Serial.println("closing connection");

  // Go back to sleep. If your sensor is battery powered you might
  // want to use deep sleep here
  delay(1000 * UPDATE_INTERVAL_SECONDS);
}

 

こちら問題なくデータの蓄積ができた。

WeMos (c5) JSON exchange rate

WeMosをRESPのクライアントとして機能するため、JSONと、HTTPClientを検証する。

前回ArduinoJsonというライブラリを使用したので、ESP8266ならではのWiFi機能を使い、インターネットから情報を取得して表示させてみる。

JSON データ形式

為替レートの情報は、

Foreign exchange rates and currency conversion JSON API

から取得する。

ドル円レートの情報を取得する場合、URLはhttp://api.fixer.io/latest?base=USD&symbols=JPY

応答は下記の通り

HTTP/1.1 200 OK
Server: nginx/1.13.6
Date: Sat, 04 Nov 2017 13:40:46 GMT
Content-Type: application/json
Content-Length: 57
Connection: close
Cache-Control: public, must-revalidate, max-age=900
Last-Modified: Fri, 03 Nov 2017 00:00:00 GMT
Vary: Origin
X-Content-Type-Options: nosniff
{"base":"USD","date":"2017-11-03","rates":{"JPY":113.94}}

closing connection

プログラム

下記の処理をする

  1.  WiFiManagerでWiFi自動接続
  2. get_exchange_rate処理
    1. api.fixer.io JSONデータ取得
    2. parse json data
    3. OLEDへ表示
  3. 60秒待ち
  4. 2へ続き
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <ArduinoJson.h>

#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
 
#define OLED_RESET 0  // GPIO0
Adafruit_SSD1306 OLED(OLED_RESET);

const char* URL = "http://api.fixer.io/latest?base=USD&symbols=JPY";  // http resource
//sample json data used in this sketch
// {"base":"USD","date":"2017-11-03","rates":{"JPY":113.94}}

//needed for library
#include <DNSServer.h>
#include <ESP8266WebServer.h>
#include "WiFiManager.h"          //https://github.com/tzapu/WiFiManager

void configModeCallback (WiFiManager *myWiFiManager) {
  Serial.println("Entered config mode");
  Serial.println(WiFi.softAPIP());
  //if you used auto generated SSID, print it
  Serial.println(myWiFiManager->getConfigPortalSSID());
}

void setup() {
  OLED.begin();
  OLED.clearDisplay();
 
  //Add stuff into the 'display buffer'
  OLED.setTextWrap(false);
  OLED.setTextSize(1);
  OLED.setTextColor(WHITE);
  OLED.setCursor(0,0);
  delay(10);
  
  Serial.begin(115200);
  Serial.println("");
  delay(10);

  // Connect to WiFi network
  OLED.println("wifiManager autoConnect...");
  OLED.display(); //output 'display buffer' to screen  
 
  //WiFiManager
  //Local intialization. Once its business is done, there is no need to keep it around
  WiFiManager wifiManager;
  //reset settings - for testing
  //wifiManager.resetSettings();

  //set callback that gets called when connecting to previous WiFi fails, and enters Access Point mode
  wifiManager.setAPCallback(configModeCallback);

  //fetches ssid and pass and tries to connect
  //if it does not connect it starts an access point with the specified name
  //here  "AutoConnectAP"
  //and goes into a blocking loop awaiting configuration
  if(!wifiManager.autoConnect()) {
    Serial.println("failed to connect and hit timeout");
    //reset and try again, or maybe put it to deep sleep
    ESP.reset();
    delay(1000);
  } 

  // Print the IP address
  OLED.print("http://");
  OLED.print(WiFi.localIP());
  OLED.println("/");
  OLED.println("WiFi connected");
  OLED.display(); //output 'display buffer' to screen  
  
  //if you get here you have connected to the WiFi
  Serial.println("connected...yeey :)");
 
}

void get_exchange_rate() {
  const int BUFFER_SIZE = JSON_OBJECT_SIZE(4) + JSON_ARRAY_SIZE(1);
  StaticJsonBuffer<BUFFER_SIZE> jsonBuffer;
  HTTPClient http;

  Serial.print("[HTTP] begin...\n");
  // configure targed server and url
  http.begin(URL);
  
  Serial.print("[HTTP] GET...\n");
  // start connection and send HTTP header
  int httpCode = http.GET();

  if(httpCode != HTTP_CODE_OK) {
    return;
  }
  String buffer = http.getString();
  Serial.println(buffer);

  //parse json data
  char json[buffer.length() + 1];
  buffer.toCharArray(json, sizeof(json));
  Serial.println(json);
  JsonObject& root = jsonBuffer.parseObject(json);
  if (!root.success()) {
    Serial.println("parseObject() failed");
    return;
  }
  const char* date = root["date"];
  Serial.println(date);
  const char* base = root["base"];
  Serial.println(base);
  JsonObject& rates = root["rates"];
  rates.printTo(Serial);
  Serial.println();
  const char* rate = rates["JPY"];
  Serial.println(rate);
  Serial.println();
  
  Serial.println("closing connection");

  OLED.clearDisplay();
  OLED.setCursor(0,0);
  // Print the IP address
  OLED.print("http://");
  OLED.print(WiFi.localIP());
  OLED.println("/");

  OLED.setCursor(0, 16);
  OLED.print(date);
  OLED.setCursor(0, 24);
  OLED.print("JPY/");
  OLED.print(base);
  OLED.print(": ");
  OLED.print(rate);
  OLED.display(); //output 'display buffer' to screen  

}

void loop() {
  get_exchange_rate();
  delay(60000);
}

 

参考

  • http://blog.boochow.com/article/425016458.html — ESP8266版Arduinoでネットから情報を取ってきてLCDに表示する

WeMos (c4) JSON

WeMosをRESPのクライアントとして機能するため、JSONと、HTTPClientを検証する。

ライブラリの追加

JSONを扱うライブラリに「ArduinoJSON」というのがあるので、ライブラリの追加で、リストが出てくるので、JSONと入力し絞込。

(2018/7現在、5.x と6.x が共存して、6.xはまたベター版のため、エラーが発生する。5.xを利用する)

ArduinoJSONの動作、JsonBuffer size、Parsing program、Serializing programは、下記のURLで確認しながら進める方が便利でしょう。

https://bblanchon.github.io/ArduinoJson/assistant/

動作確認

公式のサンプルJsonParserExampleをそのまんま。

// Copyright Benoit Blanchon 2014-2017
// MIT License
//
// Arduino JSON library
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!

#include <ArduinoJson.h>

void setup() {
  Serial.begin(9600);
  while (!Serial) {
    // wait serial port initialization
  }

  // Memory pool for JSON object tree.
  //
  // Inside the brackets, 200 is the size of the pool in bytes,
  // If the JSON object is more complex, you need to increase that value.
  // See https://bblanchon.github.io/ArduinoJson/assistant/
  StaticJsonBuffer<200> jsonBuffer;

  // StaticJsonBuffer allocates memory on the stack, it can be
  // replaced by DynamicJsonBuffer which allocates in the heap.
  //
  // DynamicJsonBuffer  jsonBuffer(200);

  // JSON input string.
  //
  // It's better to use a char[] as shown here.
  // If you use a const char* or a String, ArduinoJson will
  // have to make a copy of the input in the JsonBuffer.
  char json[] =
      "{\"sensor\":\"gps\",\"time\":1351824120,\"data\":[48.756080,2.302038]}";

  // Root of the object tree.
  //
  // It's a reference to the JsonObject, the actual bytes are inside the
  // JsonBuffer with all the other nodes of the object tree.
  // Memory is freed when jsonBuffer goes out of scope.
  JsonObject& root = jsonBuffer.parseObject(json);

  // Test if parsing succeeds.
  if (!root.success()) {
    Serial.println("parseObject() failed");
    return;
  }

  // Fetch values.
  //
  // Most of the time, you can rely on the implicit casts.
  // In other case, you can do root["time"].as<long>();
  const char* sensor = root["sensor"];
  long time = root["time"];
  double latitude = root["data"][0];
  double longitude = root["data"][1];

  // Print values.
  Serial.println(sensor);
  Serial.println(time);
  Serial.println(latitude, 6);
  Serial.println(longitude, 6);
}

void loop() {
  // not used in this example
}

出力

gps
1351824120
48.756080
2.302038

参考

  • https://bblanchon.github.io/ArduinoJson/assistant/ — ArduinoJson Assistant
  • http://shuzo-kino.hateblo.jp/entry/2016/05/06/203603 — ArduinoでJSONを扱う「ArduinoJSON」

WeMos (c3) Home IoT Server

いよいよWiFiManagerを組み込み、理想のIoT-Cloud-Mobile Study Kit (IoT実験キット)の形ができた。

今回の実験はWeMosにhttpサーバを立ち上げて、ブラウザーから接続 を待機;接続するとBMP280センサー情報を返送する。

つまり、スマートフォンまたはPCから直接接続して利用する。この場合ローカル環境の利用に限られ、出かける時でも利用するため、クラウド(例えばTinyWebDB API)が必要だ。

WiFiManagerを組み込みだ、Home IoT Server。

/*
 * 
 */
#include <Wire.h> 
#include <Adafruit_BMP280.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
 
#define OLED_RESET 0  // GPIO0
Adafruit_SSD1306 OLED(OLED_RESET);

#define BMP_SCK 13
#define BMP_MISO 12
#define BMP_MOSI 11 
#define BMP_CS 10

Adafruit_BMP280 bmp; // I2C
//Adafruit_BMP280 bmp(BMP_CS); // hardware SPI
//Adafruit_BMP280 bmp(BMP_CS, BMP_MOSI, BMP_MISO,  BMP_SCK);

#include <ESP8266WiFi.h>
#include <DNSServer.h>
#include <ESP8266WebServer.h>
#include <WiFiManager.h> 
 
int ledPin = BUILTIN_LED;
WiFiServer server(80);
 
void setup() {
  OLED.begin();
  OLED.clearDisplay();
 
  //Add stuff into the 'display buffer'
  OLED.setTextWrap(false);
  OLED.setTextSize(1);
  OLED.setTextColor(WHITE);
  OLED.setCursor(0,0);
  delay(10);
 
 
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, HIGH);
 
  // Connect to WiFi network
  OLED.println("wifiManager autoConnect...");
  OLED.display(); //output 'display buffer' to screen  
 
  WiFiManager wifiManager;
  wifiManager.autoConnect();

  OLED.println("WiFi connected");
  OLED.display(); //output 'display buffer' to screen  
 
  // Start the server
  server.begin();
  OLED.println("Server started");
  
  // Print the IP address
  OLED.print("http://");
  OLED.print(WiFi.localIP());
  OLED.println("/");
 
  OLED.display(); //output 'display buffer' to screen  
  // OLED.startscrollleft(0x00, 0x0F); //make display scroll 

  if (!bmp.begin(0x76)) 
  {
    OLED.println("Could not find BMP180 or BMP085 sensor at 0x77");
    OLED.display(); //output 'display buffer' to screen  
    while (1) {}
  }
}

void OLED_show()
{

  OLED.clearDisplay();
  OLED.setCursor(0,0);
  // Print the IP address
  OLED.print("http://");
  OLED.print(WiFi.localIP());
  OLED.println("/");
  OLED.setCursor(0,8);
  OLED.print("Temp = ");
  OLED.print(bmp.readTemperature());
  OLED.println(" Celsius");
  // set the cursor to column 0, line 1
  // (note: line 1 is the second row, since counting begins with 0):
  OLED.setCursor(0,16);
  OLED.print("Pres = ");
  OLED.print(bmp.readPressure());
  OLED.println(" Pascal ");
  // print the number of seconds since reset:
  OLED.setCursor(0,24);
  OLED.print(millis() / 1000);

  OLED.display(); //output 'display buffer' to screen  
}

void loop() {
  delay(500);
  // Check if a client has connected
  WiFiClient client = server.available();
  if (!client) {
    OLED_show();
    delay(1);
    return;
  }
 
  // Wait until the client sends some data
  OLED.println("new client");
  // while(!client.available()){
  //   delay(1);
  // }
 
  // Read the first line of the request
  String request = client.readStringUntil('\r');
  OLED.println(request);
  OLED.display(); //output 'display buffer' to screen  
  client.flush();
 
  // Match the request
 
  int value = LOW;
  if (request.indexOf("/LED=ON") != -1) {
    digitalWrite(ledPin, LOW);
    value = HIGH;
  } 
  if (request.indexOf("/LED=OFF") != -1){
    digitalWrite(ledPin, HIGH);
    value = LOW;
  }
 
 
 
  // Return the response
  client.println("HTTP/1.1 200 OK");
  client.println("Content-Type: text/html");
  client.println(""); //  do not forget this one
  client.println("<!DOCTYPE HTML>");
  client.println("<html>");
 
  client.print("Temp = ");
  client.print(bmp.readTemperature());
  client.println(" Celsius <br>");
  client.print("Pres = ");
  client.print(bmp.readPressure());
  client.println(" Pascal <br>");

  client.print("Led pin is now: ");
 
  if(value == HIGH) {
    client.print("On");  
  } else {
    client.print("Off");
  }
  client.println("<br><br>");
  client.println("Click <a href=\"/LED=ON\">here</a> turn the LED ON<br>");
  client.println("Click <a href=\"/LED=OFF\">here</a> turn the LED OFF<br>");
  client.println("</html>");
 
  delay(1);
  OLED.println("Client disconnected");
  OLED.println("");
  OLED.display(); //output 'display buffer' to screen  
 
}

 

実験方法:

  1. プログラム検証
  2. WeMosにプログラムアップロード
  3. WeMosのWiFiManeger で接続、AP設定
  4. WeMosのOLEDでIP確認
  5. 自動的にhttpサーバを立ち上げ、ブラウザーから接続 を待機
  6. 接続するとBMP280センサー情報を返送する。

 

WeMos (c2) WiFiManager

WeMos のWiFiが、前回のようにSSIDとPASSWORDをコードに書き込む方法の他に、オンライン変更できるような方法もある。

WiFiManager というライブラリを使うと簡単にできる

https://github.com/tzapu/WiFiManager

このソースを参考に試してみる。

まず、ライブラリマネージャーから、WiFiManagerを検索して、インストールする。

ライブラリを使える状態にすると,下記のサンプルで、接続するだけで上のユースケースが満たされて大変便利だ…。標準でWebUIもついてる。

#include <ESP8266WiFi.h>          //https://github.com/esp8266/Arduino

//needed for library
#include <DNSServer.h>
#include <ESP8266WebServer.h>
#include "WiFiManager.h"          //https://github.com/tzapu/WiFiManager

void configModeCallback (WiFiManager *myWiFiManager) {
  Serial.println("Entered config mode");
  Serial.println(WiFi.softAPIP());
  //if you used auto generated SSID, print it
  Serial.println(myWiFiManager->getConfigPortalSSID());
}

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  
  //WiFiManager
  //Local intialization. Once its business is done, there is no need to keep it around
  WiFiManager wifiManager;
  //reset settings - for testing
  //wifiManager.resetSettings();

  //set callback that gets called when connecting to previous WiFi fails, and enters Access Point mode
  wifiManager.setAPCallback(configModeCallback);

  //fetches ssid and pass and tries to connect
  //if it does not connect it starts an access point with the specified name
  //here  "AutoConnectAP"
  //and goes into a blocking loop awaiting configuration
  if(!wifiManager.autoConnect()) {
    Serial.println("failed to connect and hit timeout");
    //reset and try again, or maybe put it to deep sleep
    ESP.reset();
    delay(1000);
  } 

  //if you get here you have connected to the WiFi
  Serial.println("connected...yeey :)");
 
}

void loop() {
  // put your main code here, to run repeatedly:

}

 

WiFiManager 動作の流れ

  1. 保存されている認証情報があれば、その情報を使ってAPに接続する
  2. 保存されている情報がないか、あっても接続できなければ、Wi-Fiをスキャンして接続候補となるAPを探し、ESP8266自身がアクセスポイントモードになり、認証情報の入力を待つ
  3. ユーザーがESP8266のAPに接続すると、ESP8266自身が立ち上げたWebサーバーに接続され、表示されているAP候補の中から接続したいAPを選択し、そのパスワードを入力する。
  4. ESP8266は指定されたSSIDとパスワードでAPに接続する

ESP8266アクセスポイントモード

保存されている情報がないか、あっても接続できなければ、Wi-Fiをスキャンして接続候補となるAPを探し、ESP8266自身がアクセスポイントモードになり、認証情報の入力を待つ。

まずスマートフォンの「設定」の中の「Wi-Fi」を開く。自宅のWi-Fiルーターの他に”AutoConnectAP”というAPが見つかります。これがESP8266なので、これを選択。

image

接続したいAPを選択

ユーザーがESP8266のAPに接続すると、ESP8266自身が立ち上げたWebサーバーに接続される。

自動的にブラウザーが立ち上がる場合もありますし、そうでない場合はブラウザーを起動します。するとESP8266のWebサーバーに接続され、次の画面が表示されます。

image

ここで「Configure WiFi」をタップすると、近くにあるWi-Fi APのリストが表示されます。表示されているAP候補の中から接続したいAPを選択し、そのパスワードを入力。するとESP8266は指定されたSSIDとパスワードでAPに接続する。

 

WeMos (c1) Web on WiFi

いよいよ内蔵WiFiを活用する時期が来た!

前回のセンサー情報をWebからでも見れるようにする。

処理の流れ

setup() {
    WiFi初期化
    Web初期化
    センサー初期化
}
loop() {
    If (Webからリクエスト) 
      .1 パラメタよりLED点/滅
      .2 センサー情報取得
      .3 クライアントに返信
    Else
      .1 センサー情報取得
      .2 LCDに情報表示
}

setup()

  • WiFi 初期化:内蔵WiFiをアクセスポイントに接続
  • Web初期化:内蔵Webサーバを立ち上げる
  • センサー初期化:BMP280を初期化

loop()

  • Webからのリクエストをチェックする

システム構成

完成したプログラム

/*
 * 
 */
#include <Wire.h> 
#include <Adafruit_BMP280.h>
#include <LiquidCrystal_I2C.h>
 
//For SPI connection!
#define BMP_SCK D5
#define BMP_MISO D6
#define BMP_MOSI D7 
#define BMP_CS D3

Adafruit_BMP280 bmp; // I2C
// Adafruit_BMP280 bmp(BMP_CS); // hardware SPI
// Adafruit_BMP280 bmp(BMP_CS, BMP_MOSI, BMP_MISO,  BMP_SCK);

// Set the LCD address to 0x27 for a 16 chars and 2 line display
LiquidCrystal_I2C lcd(0x27, 16, 2);

#include <ESP8266WiFi.h>
 
const char* ssid = "SSID";
const char* password = "WIFI PASS";
 
int ledPin = BUILTIN_LED;
WiFiServer server(80);

void setup()
{
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, HIGH);

  lcd.begin(0,2);  // sda=GPIO_0, scl=GPIO_2

  lcd.init();

  // Turn on the backlight.
  lcd.backlight();
    
  // Connect to WiFi network
  lcd.print("Connect to ");
  lcd.println(ssid);
 
  WiFi.begin(ssid, password);
  lcd.setCursor(0, 1);
 
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    lcd.print(".");
  }
  lcd.println("");
  lcd.println("WiFi connected");
 
  // Start the server
  server.begin();
  lcd.println("Server started");
  
  // Print the IP address
  lcd.setCursor(0, 0);
  lcd.print(WiFi.localIP());
  lcd.println("/");

  if (!bmp.begin(0x76)) 
  {
    lcd.println("Could not find BMP180 or BMP085 sensor at 0x77");
    while (1) {}
  }
}

void lcd_show()
{
  lcd.setCursor(0, 1);
  lcd.print(bmp.readTemperature());
  lcd.print("C, ");
  lcd.print(bmp.readPressure() / 100 );
  lcd.print("P ");
  // print the number of seconds since reset:
  lcd.print(millis() / 1000);
  delay(2000);

}

void loop() {
  // Check if a client has connected
  WiFiClient client = server.available();
  if (!client) {
    lcd_show();
    delay(1);
    return;
  }
 
  // Wait until the client sends some data
  lcd.println("new client");
  // while(!client.available()){
  //   delay(1);
  // }
 
  // Read the first line of the request
  String request = client.readStringUntil('\r');
  lcd.println(request);
  client.flush();
 
  // Match the request
 
  int value = LOW;
  if (request.indexOf("/LED=ON") != -1) {
    digitalWrite(ledPin, LOW);
    value = HIGH;
  } 
  if (request.indexOf("/LED=OFF") != -1){
    digitalWrite(ledPin, HIGH);
    value = LOW;
  }
 
 
 
  // Return the response
  client.println("HTTP/1.1 200 OK");
  client.println("Content-Type: text/html");
  client.println(""); //  do not forget this one
  client.println("<!DOCTYPE HTML>");
  client.println("<html>");
 
  client.print("Temp = ");
  client.print(bmp.readTemperature());
  client.println(" Celsius <br>");
  client.print("Pres = ");
  client.print(bmp.readPressure());
  client.println(" Pascal <br>");

  client.print("Led pin is now: ");
 
  if(value == HIGH) {
    client.print("On");  
  } else {
    client.print("Off");
  }
  client.println("<br><br>");
  client.println("Click <a href=\"/LED=ON\">here</a> turn the LED ON<br>");
  client.println("Click <a href=\"/LED=OFF\">here</a> turn the LED OFF<br>");
  client.println("</html>");
 
  delay(1);
  lcd.println("Client disconnected");
 
}