4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

IoTLTAdvent Calendar 2018

Day 9

ESP8266 Wifi-Module Wemos D1mini & 温湿度センサーSHT30、mac-ID でMQTT-feed を自動作成&センサーデータvisualization

Posted at

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ケーブル  

###完成したモジュールのイメージ:
IMG_20181209_003025s25.jpg

###使用した基盤:
IMG_20181209_001315.jpg
温湿度センサーはI2Cケーブルでフックアップします:
IMG_20181209_002528s10.jpg
###モジュールケースの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

mqtt_esp8266.ino
/***************************************************
  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


##プロジェクトの実現
大量でセンサーモジュールの作成して
image.png
住宅に配置して各部屋及び外気の変換を測定する。
image.png
各データを一つのグラフに同時表示する。
image.png
continue will follow...

4
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?