ESP8266 Wifi-Module Wemos D1mini & 温湿度センサーSHT30、mac-ID でMQTT-feed を自動作成&センサーデータvisualization
##プロジェクトアウトライン:
温度・湿度(アップグレードバーションでCO2、PM2.5濃度)のど空気質を評価するセンサーデータを
WiFiでMQTTなどでサーバーに送ってサーバーで処理するプロジェクトをやりました。
今回はデータ保存、表記の為にAdafruit.ioのMQTTサービスを利用しました。
パート2ではFireBase RTDBとCloud Functionを利用します。
フィーギャー
- セットアップWiFi SSID & P/W WifiManager with ad-hoc access point web page
- use WiFiモジュールmac-address as data ID
- Get time from NTP time Client and attach time Stamp to measurement data
##使用するツール
Hardware: | Comment: | Link: |
---|---|---|
Wemos D1 Module (ESP8266) | Arduino IDE | https://wiki.wemos.cc/products:retired:d1_mini_v2.3.0 |
Wemos SHT30 Module | I2C別当用意が必要 | https://wiki.wemos.cc/products:d1_mini_shields:sht30_shield |
Wemos OLED-Sield | https://wiki.wemos.cc/products:d1_mini_shields:oled_shield | |
Wemos Power-Sheeld V1.1 | optional | |
スマホ用の充電器 | ||
マイクロUSBケーブル |
###使用した基盤:
温湿度センサーはI2Cケーブルでフックアップします:
###モジュールケースのSTLデータfor 3Dプリンティング:
Link to STL-file @ Thingiverse.com
##Create a free Adafruit.io MQTT acount:
Link to adafruit.io
Serviceメニューから
-Username
-Active Key
コピーしてArduinoのコードに張り付けって下さい。
###使用するArduino library
Hardware: | Version: | Link: |
---|---|---|
ESP8266WiFi.h | ||
Adafruit_MQTT.h | ||
Adafruit_MQTT_Client.h | ||
WiFiManager.h | ||
ArduinoJson.h | Version 5.13.2 | |
ESP8266httpUpdate.h | ||
ESP8266HTTPClient.h | ||
time.h | ||
WiFiUdp.h | ||
stdio.h | ||
NTPClient.h | ||
ESP8266WiFiMesh.h | ||
ESP8266WiFiMulti.h | ||
DNSServer.h | ||
ESP8266WebServer.h | ||
Adafruit_GFX.h | ||
Adafruit_SSD1306.h | ||
Adafruit_GFX.h | ||
Adafruit_SSD1306.h |
###Source Code
/***************************************************
Adafruit MQTT Library ESP8266 Example Must use ESP8266 Arduino from:
https://github.com/esp8266/Arduino
Works great with Adafruit's Huzzah ESP board & Feather
----> https://www.adafruit.com/product/2471
----> https://www.adafruit.com/products/2821
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing products from Adafruit!
Written by Tony DiCola for Adafruit Industries.
MIT license, all text above must be included in any redistribution
****************************************************/
#include <ESP8266WiFi.h>
#include "Adafruit_MQTT.h"
#include "Adafruit_MQTT_Client.h"
#include <WiFiManager.h>
#include <ArduinoJson.h> // Version 5.13.2
#include <ESP8266httpUpdate.h>
#include <ESP8266HTTPClient.h>
#include <time.h>
#include <WiFiUdp.h>
#include <stdio.h>
#include <NTPClient.h>
#include <ESP8266WiFiMesh.h>
#include <ESP8266WiFiMulti.h>
#include <DNSServer.h>
#include <ESP8266WebServer.h>
//------
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define OLED_RESET 0 // GPIO0
//------
#include <WEMOS_SHT3X.h>
#define USE_SERIAL Serial //from ESP32
#define NTP_OFFSET 9 * 3600 // In seconds
#define NTP_INTERVAL 60 * 1000 // In miliseconds
#define NTP_ADDRESS "europe.pool.ntp.org"
WiFiManager wifiManager;
ESP8266WiFiMulti WiFiMulti;
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, NTP_ADDRESS, NTP_OFFSET, NTP_INTERVAL);
SHT3X sht30(0x45);
HTTPClient http;
Adafruit_SSD1306 display(OLED_RESET);
/************************* MAC ADD and Time Setup *********************************/
uint8_t mac[6];
String macToStr(const uint8_t* mac) {
String result;
char sbuf[30] = "/0";
//sprintf(sbuf, "%02X:%02X:%02X:%02X:%02X:%02X",
sprintf(sbuf, "%02X%02X%02X%02X%02X%02X",
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
result = sbuf;
return result;
}
String macID = macToStr(mac);//MAC as String
String formattedTime = timeClient.getFormattedTime();
int timezone = 9 * 3600;
int dst = 0;
time_t now = time(nullptr);
struct tm* p_tm = localtime(&now);
String tDay = String(p_tm->tm_mday);
String tMon = String(p_tm->tm_mon + 1);
String tYear = String(p_tm->tm_year + 1900);
String tHour = String(p_tm->tm_hour);
String tMin = String(p_tm->tm_min);
String tSec = String(p_tm->tm_sec);
String timeStamp; // = tDay +"-"+tMon +"-"+ tYear;// +" "+ tHour +":"+tMin+":"+tSec;
void printTime() {
Serial.print((*p_tm).tm_mday);
Serial.print("/");
Serial.print(p_tm->tm_mon + 1);
Serial.print("/");
Serial.print(p_tm->tm_year + 1900);
Serial.print(" ");
Serial.print(p_tm->tm_hour);
Serial.print(":");
Serial.print(p_tm->tm_min);
Serial.print(":");
Serial.println(p_tm->tm_sec);
String timeStamp = tDay + "-" + tMon + "-" + tYear; // +" "+ tHour +":"+tMin+":"+tSec;
// Serial.println(timeStamp);
Serial.println(formattedTime);
Serial.print(time(nullptr));
}
uint32_t x = 0;
unsigned long timeEP = millis();
unsigned long timeOld = timeEP;
unsigned long timeIOA = millis();
unsigned long timeOldIOA = timeIOA;
/************************* Firebase Setup *********************************/
// Generate Temperatuer feed name based on MAC address
String feedName; //use for Firebase
String feedNameTemp;
String feedNameHyum;
char CharfeedName[20]; //use for MQTT
char CharfeedNameTemp[20];
char CharfeedNameHyum[20];
/************************* Adafruit.io Setup *********************************/
#define AIO_SERVER "io.adafruit.com"
#define AIO_SERVERPORT 1883 // use 8883 for SSL
#define AIO_USERNAME "XXX" // enter your user name
#define AIO_KEY "XXX" // enter your Key
/********************* Wifi Manager Setting *********************************/
String getSSID();
String getPassword();
bool shouldSaveConfig = false;
void saveConfigCallback () {
Serial.println("Should save config");
shouldSaveConfig = true;
}
void setConfigPortalBlocking(boolean shouldBlock);
WiFiManagerParameter custom_text("<p>Select your home-network, enter password and press [save]. Then continue with the other Units.</p>");
/************ Global State (you don't need to change this!) ******************/
// Create an ESP8266 WiFiClient class to connect to the MQTT server.
WiFiClient client;
// or... use WiFiFlientSecure for SSL
//WiFiClientSecure client;
// Setup the MQTT client class by passing in the WiFi client and MQTT server and login details.
Adafruit_MQTT_Client mqtt(&client, AIO_SERVER, AIO_SERVERPORT, AIO_USERNAME, AIO_KEY);
/****************************** Feeds ***************************************/
// Setup mqtt feed for publishing.
// Notice MQTT paths for AIO follow the form: <username>/feeds/<feedname>
Adafruit_MQTT_Publish swUpgradeCompleat = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME CharfeedName );
Adafruit_MQTT_Publish temperature = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME CharfeedNameTemp );
Adafruit_MQTT_Publish hyumidity = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME CharfeedNameHyum );
// Setup a feed called by mac-address for subscribing to changes.
Adafruit_MQTT_Subscribe softwareUpgrade = Adafruit_MQTT_Subscribe(&mqtt, AIO_USERNAME CharfeedName, MQTT_QOS_1);
/*************************** Random voids for Sketch Code ************************************/
void MQTT_connect();
/************************* Get Time *********************************/
String getTime() {
WiFiClient client;
while (!!!client.connect("google.com", 80)) {
Serial.println("connection failed, retrying...");
}
client.print("HEAD / HTTP/1.1\r\n\r\n");
while(!!!client.available()) {
yield();
}
while(client.available()){
if (client.read() == '\n') {
if (client.read() == 'D') {
if (client.read() == 'a') {
if (client.read() == 't') {
if (client.read() == 'e') {
if (client.read() == ':') {
client.read();
String theDate = client.readStringUntil('\r');
client.stop();
return theDate;
}
}
}
}
}
}
}
}
/************************* gettingdata from SHT30 and putting in io.Adafruit *********************************/
void SHTGet() {
if (sht30.get() == 0) {
////Temperature in Celsius :
initDisplay();
display.setTextSize(1);
display.print("T: ");//display.println("T: ");
display.setTextSize(1);//2
display.println(sht30.cTemp);
//----
Serial.print(F("\nSending temperature val "));
Serial.println("");
//Serial.println(getTime() );
//Serial.println(formattedTime);
Serial.println(sht30.cTemp);
temperature.publish(sht30.cTemp);
time(nullptr);
////hyumidity in rH :
display.setTextSize(1);
display.print("H: ");// display.println("H: ");
display.setTextSize(1);//2
display.println(sht30.humidity);
display.println(WiFi.localIP());
display.println(WiFi.macAddress());
//----
Serial.print(F("\nSending hyumidity val "));
Serial.println("");
Serial.println(sht30.humidity);
hyumidity.publish(sht30.humidity);
// update value
// Serial.println(timeStamp);
display.display();
// delay(10);
}
}
/************************* Update Software *********************************/
void firmwareUpdate() {
delay(100);
Serial.println("Updating...");
swUpgradeCompleat.publish("Updating...");
t_httpUpdate_return ret = ESPhttpUpdate.update("XXX"); //enter path to file location
switch (ret) {
case HTTP_UPDATE_FAILED:
swUpgradeCompleat.publish("FAILED");
Serial.printf("HTTP_UPDATE_FAILD Error (%d): %s", ESPhttpUpdate.getLastError(), ESPhttpUpdate.getLastErrorString().c_str());
swUpgradeCompleat.publish("FAILED");
break;
case HTTP_UPDATE_NO_UPDATES:
swUpgradeCompleat.publish("HTTP_UPDATE_NO_UPDATES");
Serial.println("HTTP_UPDATE_NO_UPDATES");
swUpgradeCompleat.publish("HTTP_UPDATE_NO_UPDATES");
break;
case HTTP_UPDATE_OK:
swUpgradeCompleat.publish("done");
Serial.println("HTTP_UPDATE_OK");
swUpgradeCompleat.publish("done");
break;
}
}
/************************* MQTT Connect *********************************/
void MQTT_connect() {
int8_t ret;
// Stop if already connected.
if (mqtt.connected()) {
return;
}
Serial.print("");
Serial.print("Connecting to MQTT... ");
while ((ret = mqtt.connect()) != 0) { // connect will return 0 for connected
Serial.println(mqtt.connectErrorString(ret));
Serial.println("Retrying MQTT connection in 5 seconds...");
mqtt.disconnect();
delay(5000); // wait 5 seconds
return;
}
Serial.println("MQTT Connected!");
}
/************************* Initializing Display *********************************/
void initDisplay() {
// Clear the buffer.
display.clearDisplay();
display.setTextSize(1);
display.setCursor(0, 0);
display.setTextColor(WHITE);
}
void setup() {
Serial.begin(115200);
delay(10);
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
initDisplay();
// --------------------------------------------------------------------------------------------------
wifiManager.addParameter(&custom_text);
wifiManager.setConfigPortalBlocking(false);
WiFi.begin(wifiManager.getConfigPortalSSID().c_str(), wifiManager.getPass().c_str());
if (wifiManager.autoConnect("TempHyumSensMod")) {
Serial.println("connected...yeey :)");
WiFi.begin(wifiManager.getConfigPortalSSID().c_str(), wifiManager.getPass().c_str());
}
else {
Serial.println("Configportal running");
}
WiFi.begin(wifiManager.getConfigPortalSSID().c_str(), wifiManager.getPass().c_str());
Serial.println("WiFi connected");
Serial.println("IP address: "); Serial.println(WiFi.localIP());
// --------------------------------------------------------------------------------------------------
//printTime();
// confirm successful SW-upgrade via MQTT subscription.
swUpgradeCompleat.publish("done");
// Setup MQTT subscription for onoff feed.
softwareUpgrade.setCallback(softwarecallback);
mqtt.subscribe(&softwareUpgrade);
// --------------------------------------------------------------------------------------------------
Serial.println("WiFi connected");
Serial.println("MAC address: ");
WiFi.macAddress(mac);
Serial.print("MAC: ");
Serial.print(mac[5], HEX);
Serial.print(":");
Serial.print(mac[4], HEX);
Serial.print(":");
Serial.print(mac[3], HEX);
Serial.print(":");
Serial.print(mac[2], HEX);
Serial.print(":");
Serial.print(mac[1], HEX);
Serial.print(":");
Serial.println(mac[0], HEX);
// --------------------------------------------------------------------------------------------------
//Starting Interrupt
attachInterrupt(PWM_IN, RiseTime, CHANGE);
}// Setup
/********************************************* Loop ******************************************************/
void loop() {
wifiManager.process();
FirebaseFeedName();
timeEP = millis() - timeOld;
timeIOA = millis() - timeOldIOA;
if (timeEP >= 1000) {
timeOld = millis();
PWM_Output(); // Reads PWM Input and Give Output based on a fixed array
if (WiFi.status() == WL_CONNECTED && mqtt.connected()) {
FirebaseFeed();
}
}
if (timeIOA >= 60000) {
timeOldIOA = millis();
if (WiFi.status() == WL_CONNECTED && mqtt.connected()) {
SHTGet();
}
}
if (WiFi.status() == WL_CONNECTED) {
MQTT_connect();
}
Adafruit_MQTT_Subscribe *subscription;
while ((subscription = mqtt.readSubscription(5000))) {
if (subscription == &softwareUpgrade) {
Serial.print(F("Got: "));
Serial.println((char *)softwareUpgrade.lastread);
if (strcmp((char *)softwareUpgrade.lastread, "ON") == 0) {
firmwareUpdate();
}
}
if (subscription == &OuterTemperature) {
Serial.print(F("OT Got: "));
Serial.println((char *)OuterTemperature.lastread);
if (strcmp((char *)OuterTemperature.lastread, "ON") == 0) {
Outertemperature();
}
delay(1000);
}
}
} // Loop
##プロジェクトの実現
大量でセンサーモジュールの作成して
住宅に配置して各部屋及び外気の変換を測定する。
各データを一つのグラフに同時表示する。
continue will follow...