目的: ESP8266 組み立て基板を複数の WiFi のうち最大強度のssidに自動接続したい --- WiFiMulti
例: 自宅でテストした後に、セカンドハウスに取付ける
実験の準備
HiLetGo ESP-12EにマイクロUSBをつないだだけ。
ESP-12Eをserver にして、PCから GET method で信号を、WiFiルーター経由で信号を送り、ESP-12Eに実装されているLEDを点燈する。
スケッチ
/*
WiFiMulti_HiLetGo3.ino
one board computer : HiLetGo
This sketch trys to Connect to the best AP based on a given list
The first two ssid are always failed
, probably because two ssid cannot be written on SPIFFS.
But after three ssid are effective.
*/
#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
ESP8266WiFiMulti wifiMulti;
WiFiServer server(80);
wl_status_t prevWifiStatus = WL_IDLE_STATUS;
void setup() {
pinMode(16, OUTPUT);
digitalWrite(16, 0);
Serial.begin(115200);
delay(10);
wifiMulti.addAP("D*****G___", "********");
wifiMulti.addAP("D*****G", "********");
Serial.println("");
Serial.println("boot");
// ここではまだ繋ぎに行かない
}
void loop() {
wl_status_t wifiStatus = wifiMulti.run();
if ( prevWifiStatus != wifiStatus ) {
prevWifiStatus = wifiStatus;
if( wifiStatus == WL_CONNECTED) {
Serial.println("WiFi connected");
Serial.print("SSID: ");
Serial.println(WiFi.SSID());
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
delay(100);
}
else {
// ステータス毎にメッセージ変えたほうがいいかも(各自宿題)
Serial.println("WiFi error?");
Serial.println(wifiStatus);
delay(100);
return;
}
}
// Start the server
server.begin();
// Serial.println("Server started");
delay(100);
// Print the IP address
// Serial.println(WiFi.localIP());
// Check if a client has connected
WiFiClient client = server.available();
if (!client) {
return;
}
// Wait until the client sends some data
Serial.println("new client request");
Serial.println(WiFi.localIP());
delay(10);
while(!client.available()){
delay(100);
}
// Read the first line of the request
String req = client.readStringUntil('\r');
delay(100);
Serial.println(req);
client.flush();
delay(10);
// Match the request
int val;
if (req.indexOf("/gpio/0") != -1)
val = 0;
else if (req.indexOf("/gpio/1") != -1)
val = 1;
else {
Serial.println("invalid request");
Serial.println("--------------------");
client.stop();
return;
}
// Set GPIO16 according to the request. Red LED
digitalWrite(16, val);
client.flush();
// Prepare the response
String s = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\n<html>\r\nGPIO is now ";
s += (val)?"high":"low";
s += "</html>\n";
// Send the response to the client
client.print(s);
delay(10);
Serial.println("Client disconnected");
// The client will actually be disconnected
// when the function returns and 'client' object is detroyed
Serial.println("--------------------");
}
結果
下記のように、望んだ動作をしている。
boot
WiFi error?
6
WiFi error?
1
WiFi connected
SSID: D***********G
IP address: 192.168.3.17
new client request
192.168.3.17
GET /gpio/0 HTTP/1.1 <--- LED 点燈
Client disonnected
--------------------
new client request
192.168.3.17
GET /gpio/1 HTTP/1.1 <--- LED 消燈
Client disonnected
--------------------
new client request
192.168.3.17
GET /gpio/8 HTTP/1.1 <--- 無効なGET 情報
invalid request
Client disonnected
--------------------
new client request
192.168.3.17
GET /gpio/4 HTTP/1.1 <--- 無効なGET 情報
invalid request
Client disonnected
--------------------
new client request
192.168.3.17
GET /gpio/0 HTTP/1.1 <--- LED 点燈
Client disonnected
--------------------
考察
今回の実験では、AutoConnectを使わずに複数の ssid につなぐために、あらかじめ複数の ssid をコーディングするという ESP8266WiFiMulti.h を使った。
結果、望んだ動作をして、問題点はなかった。
AutoConnect よりライブラリーのメモリー消費が少ない。さらに、ユーザーは使い方が簡単である。 あらかじめ 接続したい複数の ssid がわかっているなら、AutoConnect よりWiFiMulti が優れている。
さらに、WiFiMultiは、WiFiと切断されても、Loop 内で何度でも自動接続するので信頼性が高い。
一方、AutoConnectはこれができず、一度切断されると、まだ手動でつながなくてはいけない。しかし、誰かがすでに解決しているかもしれない。
有効だったweb site
上記のスケッチは、ほぼ丸写しである
別の例
WiFiMulti deep-sleep
注意事項1
スケッチをESP-12E に書き込むときに、
消すモード、
スケッチだけ消す、
スケッチと WiFi を消す、
その他
がある。
スケッチだけ消すにすると過去の ssid が残っている。
注意事項2
スケッチを描いた後、deep sleepを有効にするには、D0 とRSTを接続すること。
書き込むときは open 。
//
// sensor_to_server12.ino
/***************************************************************************
This is a library for the BME280 humidity, temperature & pressure sensor
These sensors use I2C or SPI to communicate, 2 or 4 pins are required
to interface. The device's I2C address is either 0x76 or 0x77.
Adafruit invests time and resources providing this open source code,
please support Adafruit andopen-source hardware by purchasing products
from Adafruit!
Written by Limor Fried & Kevin Townsend for Adafruit Industries.
BSD license, all text above must be included in any redistribution
2018/09/25
Attention : I2C address in Adafluit Library --- Adafruit_BME280.h
changed to #define BME280_ADDRESS (0x76)
***************************************************************************/
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WiFiMulti.h> // *****
ESP8266WiFiMulti wifiMulti; // *****
WiFiServer server(80); // *****
wl_status_t prevWifiStatus = WL_IDLE_STATUS; // *****
// WiFiClient instance // *****
WiFiClient client; // *****
// Time to sleep (in seconds):
const int sleepTimeS = 51;
// host name of server
#define HOST_NAME "databooster.stars.ne.jp"
// file path of PHP file
#define PHP_PATH "/shangtianblog12/sensorSet12.php"
// port number
#define PORT_NUMBER 80
float sigma_T = 0;
float average_T = 0;
float sigma_H = 0;
float average_H = 0;
float sigma_P = 0;
float average_P = 0;
#include <Wire.h>
#include <SPI.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
#define BME_SCK 13
#define BME_MISO 12
#define BME_MOSI 11
#define BME_CS 10
#define SEALEVELPRESSURE_HPA (1013.25)
Adafruit_BME280 bme; // I2C
unsigned long delayTime;
// host name of server
const char* serverURL = "databooster.stars.ne.jp";
// ****************************************************
// ****************************************************
void setup() {
delay(1000);
Serial.begin(115200);
delay(500);
Serial.println();
Serial.println(F("BME280 test/1min"));
bool status;
// default settings
// (you can also pass in a Wire library object like &Wire2)
status = bme.begin();
if (!status) {
Serial.println("Could not find a valid BME280 sensor, check wiring!");
while (1);
}
Serial.println("-- Default Test --");
wifiMulti.addAP("0*****", "*****"); // *****
wifiMulti.addAP("D*****", "*****); // *****
Serial.println("");
Serial.println("boot");
#define MILLISECONDS_TO_WAIT 60000 // 1800000
unsigned long time_zero = millis();
time_zero = millis();
printValues();
// delay(500);
// read analog input
int count = 0;
int analogOUT_T = 0;
sigma_T = 0;
average_T = 0;
int analogOUT_H = 0;
sigma_H = 0;
average_H = 0;
int analogOUT_P = 0;
sigma_P = 0;
average_P = 0;
while (count < 7) { // 100
analogOUT_T = bme.readTemperature() -2.3;
average_T = average_T + analogOUT_T;
sigma_T = sigma_T + analogOUT_T * analogOUT_T;
analogOUT_H = bme.readHumidity() + 5;
average_H = average_H + analogOUT_H;
sigma_H = sigma_H + analogOUT_H * analogOUT_H;
analogOUT_P = bme.readPressure() / 100.0F;
average_P = average_P + analogOUT_P;
sigma_P = sigma_P + analogOUT_P * analogOUT_P;
delay(1000); // 15000
count++;
}
average_T = (average_T * 10) / count / 10.0;
Serial.println ( average_T );
sigma_T = sqrt( sigma_T / count - average_T * average_T );
average_H = average_H / count;
Serial.println ( average_H );
sigma_H = sqrt( sigma_H / count - average_H * average_H );
average_P = average_P / count;
Serial.println ( average_P );
sigma_P = sqrt( sigma_P / count - average_P * average_P );
// end analog read
wl_status_t wifiStatus = wifiMulti.run();
Serial.print("wifiStatus: ");
Serial.println(wifiStatus);
Serial.print("prevWifiStatus: ");
Serial.println(prevWifiStatus);
if ( prevWifiStatus != wifiStatus ) {
prevWifiStatus = wifiStatus;
if( wifiStatus == WL_CONNECTED) {
Serial.println("WiFi connected");
Serial.print("SSID: ");
Serial.println(WiFi.SSID());
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
delay(100);
}
else {
Serial.println("WiFi error?");
Serial.println(wifiStatus);
delay(100);
return;
}
}
// Start the server
server.begin();
// Serial.println("Server started");
delay(100);
// Print the IP address
// Serial.println(WiFi.localIP());
// make connection to server
void connectServer(); // *****
connectServer();
delay(10);
// if (millis() - time_zero < MILLISECONDS_TO_WAIT) {
// Serial.println ( MILLISECONDS_TO_WAIT - millis() + time_zero );
// delay( MILLISECONDS_TO_WAIT - millis() + time_zero );
// }
delay(1000);
Serial.println("- Sleeping for "+ String(sleepTimeS) +" Seconds");
Serial.println("- ZZZZZZZZZzzzzzzzzzzz z z z z z\n");
ESP.deepSleep(sleepTimeS * 1000000);
delay(1000);
}
void loop() {
// dummy
}
// ***************************************************************
// ***************************************************************
// send data to serverURL
void connectServer() {
int analogOUT = 0;
if (client.connect(serverURL, 80)) { //*******
Serial.println("connected to serverURL");
char aveT[16];
dtostrf(average_T, 3, 1, aveT);
char aveH[16];
dtostrf(average_H, 3, 1, aveH);
char aveP[16];
dtostrf(average_P, 4, 1, aveP);
char sendData[300] = "";
sprintf(sendData, "GET %s?value=%s&value1=%s&value2=%s HTTP/1.1\r\nHost: %s\r\nConnection: close\r\n\r\n", PHP_PATH, aveT, aveH, aveP, HOST_NAME);
Serial.println(sendData);
client.println(sendData);
Serial.println("******** Closed **********");
}
}
void printValues() {
Serial.print("Temperature = ");
Serial.print(bme.readTemperature() -2.3 );
Serial.println(" deg");
Serial.print("Pressure = ");
Serial.print(bme.readPressure() / 100.0F );
Serial.println(" hPa");
// Serial.print("Approx. Altitude = ");
// Serial.print(bme.readAltitude(SEALEVELPRESSURE_HPA));
// Serial.println(" m");
Serial.print("Humidity = ");
Serial.print(bme.readHumidity() + 5);
Serial.println(" %");
Serial.println();
}
// END