Jeremy McGinnis
Published © MIT

Sensor Network for an 18th Century Flour Mill Version 3.0

This IoT implementation outfits 18th century machinery with 21st century control/monitoring mechanisms and a Python server to manage it all!

ExpertFull instructions provided20 hours1,269

Things used in this project

Hardware components

ESP8266 ESP-12E
Espressif ESP8266 ESP-12E
×1

Software apps and online services

Arduino IDE
Arduino IDE

Hand tools and fabrication machines

Soldering iron (generic)
Soldering iron (generic)

Story

Read more

Custom parts and enclosures

LID

Lid for Custom ESP8266 PCB Case

BOT

Case to hold Custom ESP8266 PCB

Schematics

Sensor Circuitry

This is the circuitry for the sensors connected to different devices

ESP8266 Circuitry

This is the core circuitry for powering and using an ESP8266-12E used for devices

Code

ESP8266_Valve_Program

C/C++
ESP8266 program to generate data from digital inputs then post the data to a web page
#include <ESP8266WiFi.h>
#include <ArduinoJson.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClient.h> 
#include <EEPROM.h>
#include <ESP8266WebServer.h>

const char *broadcastssid = "device";       //Access point mode SSID we see in wifi manager
const char *broadcastpassword = "password";     //Access point password to log in to device
const byte button = 4;                          //Button to activate access point mode
bool doneWithWebpage = false;                   //State of webpage

ESP8266WebServer server(80);      //initialize our webserver

struct{
  float timeToWait = 60;            //time until next reset
  char routerSSID[30] = "";
  char routerPassword[30] = "";
  char deviceID[6] = "";            //id assigned to device
  char postURL[60] = "";            //url where data should be sent
  char flaskKey[30] = "";            //url where data should be sent
  bool secondValve = false;
}eepromData;                        //struct already assigned as eepromData

/* Go to http://192.168.4.1 in a web browser
 * connected to this access point to see this device.
 */
 
void handleRoot() {       //Serves configuration webpage
  server.send(200, "text/html", "<form action=\"/submit\" method=\"POST\"><input type=\"text\" name=\"ssid\" placeholder=\"ssid\"></br><input type=\"password\" name=\"password\" placeholder=\"password\"></br><input type=\"text\" name=\"flaskkey\" placeholder=\"Server Security Key\"></br><input type=\"text\" name=\"post\" placeholder=\"postURL\"></br><input type=\"text\" name=\"time\" placeholder=\"reset delay (mins)\"></br><input type=\"checkbox\" name=\"2valve\" placeholder=\"2 Valves?\"></br><input type=\"submit\" value=\"submit\"></form><p>enter configuration</p>");
  //start server html and declare form
  //make router ssid input
  //make router password input
  //make flask security key input
  //make postURL to server input
  //make reset delay input
  //make 2 valve selection checkbox
  //submit button and text
}

void handleSubmit(){      //handle data after submission
  if( ! server.hasArg("ssid") || ! server.hasArg("password") || server.arg("ssid") == NULL || server.arg("password") == NULL) { // If the POST request doesn't have ssid and password data
    server.send(400, "text/plain", "400: Invalid Request");         // The request is invalid, so send HTTP status 400
    return;
  }else{
    String ssid = "";
    String pass = "";
    for(byte i = 0; i < 30; i++){     //clears routerSSID char array
      eepromData.routerSSID[i] = 0;
    }
    for(byte i = 0; i < 30; i++){     //clears routerPassword char array
      eepromData.routerPassword[i] = 0;
    }
    for(byte i = 0; i < 60; i++){     //clears postURL char array
      eepromData.postURL[i] = 0;
    }
    for(byte i = 0; i < 30; i++){     //clears flaskKey char array
      eepromData.flaskKey[i] = 0;
    }
    if(server.arg("time").length() > 0){  //checks if reset delay field has text
      eepromData.timeToWait = server.arg("time").toFloat(); //set reset delay field after casting string to float
    }
    if(server.arg("2valve") == "on"){  //checks if 2 valve
      eepromData.secondValve = true; //set 2valve option
    }
    if(server.arg("post").length() > 0){  //checks if post url was set
      for(byte i = 0; i < server.arg("post").length(); i++){
        eepromData.postURL[i] = server.arg("post").charAt(i); //set new postURL
      }
    }
    for(byte i = 0; i < server.arg("ssid").length(); i++){
      eepromData.routerSSID[i] = server.arg("ssid").charAt(i);  //set new ssid
      ssid += server.arg("ssid").charAt(i);
    }
    for(byte i = 0; i < server.arg("flaskkey").length(); i++){
      eepromData.flaskKey[i] = server.arg("flaskkey").charAt(i);  //set new flask key
    }
    for(byte i = 0; i < server.arg("password").length(); i++){
      eepromData.routerPassword[i] = server.arg("password").charAt(i);  //set new password
      pass =+ server.arg("password").charAt(i);
    }
    Serial.println("new ssid " + ssid + " and password " + pass);
   writeEEPROM();       //save new credentials to eeprom
  }
  server.send(200, "text/plain", "credentials updated");  //respond to successful submission
  doneWithWebpage = true; //indicate done with ap mode
}

void serveWebserver(){      //setup access point mode
  delay(1000);
  Serial.print("Configuring access point...");
  WiFi.softAP(broadcastssid, broadcastpassword);  //start access point named broadcastssid with password broadcastpassword

  IPAddress myIP = WiFi.softAPIP();               //get ip address
  Serial.print("AP IP address: ");
  Serial.println(myIP);
  server.on("/", HTTP_GET, handleRoot);           //set up root link to webpage
  server.on("/submit", HTTP_POST, handleSubmit);  //set up link to submission webpage
  server.begin();                                 //start server
  Serial.println("HTTP server started");
}

void readEEPROM(){          //read in eeprom with struct eepromData
  EEPROM.begin(256);        //start eeprom read with 256 bytes
  Serial.println();
  EEPROM.get(0,eepromData); //get eeprom data
}
void writeEEPROM(){         //write data to eeprom
  EEPROM.begin(256);        //start eeprom write with 256 bytes
  Serial.println();
  EEPROM.put(0,eepromData); //put data in memory
  EEPROM.commit();          //commit memory to eeprom
}

void checkForDisplay(){                 //check if button is pressed to put device into access point mode
  pinMode(button, INPUT);
  if(digitalRead(button) == LOW){       //if button is LOW
    serveWebserver();                   //start webserver
    while(doneWithWebpage == false){    //serve webpage forever until config submitted
      server.handleClient();            //handle web requests
    }
    WiFi.softAP(broadcastssid, broadcastpassword,1,1);  //set ap mode with hidden ssid
  }
}

void setup() {
  Serial.begin(115200);
  checkForDisplay();      //check if button pressed
  String stosend1 = "";
  String stosend2 = "";
  pinMode(5,INPUT);
  pinMode(14,INPUT);
  pinMode(12,INPUT);
  pinMode(13,INPUT);
  
  if(digitalRead(5)==LOW){ //left side valve 1
    stosend1+="0";
  }else{
    stosend1+="1";
  }
  if(digitalRead(14)==LOW){ //right side valve 1
    stosend1+="0";
  }else{
    stosend1+="1";
  }
  if(eepromData.secondValve == true){
    if(digitalRead(12)==LOW){ //left side valve 1
      stosend2+="0";
    }else{
      stosend2+="1";
    }
    if(digitalRead(13)==LOW){ //right side valve 1
      stosend2+="0";
    }else{
      stosend2+="1";
    }
  }
  readEEPROM();           //read in eeprom
  for(byte j = 0; j < 30; j++){
    Serial.print(eepromData.routerSSID[j]);
  }
  Serial.println();
  for(byte j = 0; j < 30; j++){
    Serial.print(eepromData.routerPassword[j]);
  }

  /*== Wifi initialization ==*/
  WiFi.begin(eepromData.routerSSID, eepromData.routerPassword);     //WiFi connection (network name,network password)
  while (WiFi.status() != WL_CONNECTED) {               //Wait for the WiFI connection completion
    delay(500);                                         //Give the esp some time before attempting wifi connection
    Serial.print(". ");
  }
  Serial.println();

  /*== Format data as JSON to send to server ==*/
  StaticJsonBuffer<200> messageBuffer;                //Create a JSON buffer
  JsonObject& message = messageBuffer.createObject(); //Creaet a JSON object we can add our keys/values into
  message["id"] = eepromData.deviceID;
  message["network_key"] = eepromData.flaskKey;                    //Create a JSON Key called "key" with value FlaskKey
  message["battery_type"] = "1";
  message["battery_level"] = ((analogRead(A0)/1023.0)*11.5);
  JsonArray& sensors = message.createNestedArray("sensors");
  JsonObject& sensor1 = sensors.createNestedObject(); //Create a JSON object we can add our keys/values into
  sensor1["id"] = 1;
  sensor1["type"] = "valve"; 
  sensor1["data"] = stosend1;
  if(eepromData.secondValve == true){
    JsonObject& sensor2 = sensors.createNestedObject(); //Creat a JSON object we can add our keys/values into
    sensor2["id"] = 2;
    sensor2["type"] = "valve"; 
    sensor2["data"] = stosend2;
  }
  char payload[200];                    //Create a char array...
  message.printTo(payload);             //Then print the message object to the char array so we can send it as plaintext over wifi
  Serial.println(String(payload));

  /*== POST data to server ==*/
  if (WiFi.status() == WL_CONNECTED) {                    //Check if we are connected to wifi, if we are then continue with loop
    Serial.println("Wifi Connected");                                        
    HTTPClient http;                                      //Create HTTPClient object (HTTPClient handles our POST and GET requests)
    String sAddress = String(eepromData.postURL); //Make the server address out of components (our URLs should look like this "http://192.168.1.250:5000/sensorpost/this_sensor_id/"
    Serial.println(sAddress);
    http.begin(sAddress);                                 //Begin sending content to URL
    http.addHeader("Content-Type", "text/plain");         //Make a POST header
    int mStatus = http.POST(String(payload));             //POST our message (as a char array) to server, get error response code (200 == success, 404 or 500 == error)
    String returnpayload = http.getString();              //Get response from server (not necessary if server doesnt return a message)
    http.end();                                           //Close connection
    Serial.println(mStatus);
  }

  /*== GET data from server ==*/
  /*if (WiFi.status() == WL_CONNECTED) {
    HTTPClient http;
    http.begin("http://192.168.1.250:5000/getjson/");
    int httpCode = http.GET();                            //Send the request
    if (httpCode > 0) {                                   //Check the returning code (less than 0 is a client error)
      String payload = http.getString();                  //Get the request response payload
      Serial.println(payload);
    }
    http.end();
  }*/
  
  Serial.println("start deepsleep");
  ESP.deepSleep(int(eepromData.timeToWait * 60) * 1000000);    //Put esp into sleep mode for desired amount of time (reset must be tied to wake pin of esp)
}

void loop() {

}

ATTINY84_SHAFT_RPM_Program

C/C++
This code measures the speed at which a shaft is rotating.
#include <avr/sleep.h>
#include <avr/interrupt.h>
#include <avr/delay.h>
#include <SoftwareSerial.h>

const byte trigPin = 7;        //pin attached to reed switch (pullup resistor)
const byte espWrite = 2;       //pin attached to ESP RX
const byte espReset = 3;       //pin attached to ESP_RESET
#define interruptPin PCINT3   //physical pin name for low level configuration

SoftwareSerial espCom(5, espWrite); //create software serial connection to esp [RX is arbitrary] (RX, TX)

void setup() {
  espCom.begin(9600);         //start serial connection with ESP
  pinMode(trigPin, INPUT);    //trigger pin (pin attached to switch)
  pinMode(espReset, INPUT);   //reset pin (pin attached to ESP_RESET pin

  ADCSRA &= ~_BV(ADEN);       // ADC off
}

void forceSleep() {     //Puts attiny into sleep mode

  GIMSK |= _BV(PCIE0);                     // Enable Pin Change Interrupts
  PCMSK0 |= _BV(interruptPin);                   // Use PB3 as interrupt pin
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);    // replaces above statement

  sleep_enable();                         // Sets the Sleep Enable bit in the MCUCR Register (SE BIT)
  sei();                                  // Enable interrupts
  sleep_cpu();                            // sleep

  cli();                                  // Disable interrupts
  PCMSK0 &= ~_BV(interruptPin);                  // Turn off PB3 as interrupt pin
  sleep_disable();                        // Clear SE bit
  sei();
}

void sendESPmessage(float avg){       //Function to reset and send formatted message to ESP device
  pinMode(espReset, OUTPUT);          //set espreset to output mode
  digitalWrite(espReset, LOW);        //then ground the reset of ESP
  _delay_ms(5);
  digitalWrite(espReset, HIGH);       //Make High to end reset
  pinMode(espReset, INPUT);           //Change our espReset pin to Input, more efficient for battery ops
  _delay_ms(100);
  espCom.print("3:");
  espCom.print(avg);    //Send message to ESP
  espCom.println("~");
}

volatile unsigned long recordedHits[4] = {0,0,0,0};   //past 10 data points
float avgHit = 10.0;                 //combined average of recordedHits
unsigned long lastAvg = 0;          //last time we averaged recordedHits
unsigned long lastESPcom = 0;       //last time we sent message to ESP
boolean wasHighLast = false;        //keeps track of last read
byte pos = 0;
unsigned long lastHit = 0;

void loop() {
  unsigned long currentMillis = millis();   //get current time
  
  bool state = digitalRead(trigPin);    //check reed switch state
  if(state == 1 and state != wasHighLast){                         //if state is active
    recordedHits[pos] = currentMillis-lastHit;
    lastHit = currentMillis;
    pos += 1;
    if(pos==4)
      pos = 0;
  }
  if((currentMillis-lastAvg) > 1000){  //Timer for averaging recordedHits
    avgHit = 0.0;     //reset our count
    byte zeroVal = 0;         //counts how many 0s in dataset (meant to prevent weird average on startup)
    for(byte i=0; i<4; i++){   //traverse our recordedHits array
      avgHit += ((float(recordedHits[i])/100.0));  //add difference between two hits to count
      if(recordedHits[i]/100.0 == 0)
        zeroVal++;
    }
    avgHit = (avgHit/float(4-zeroVal)); //calculate average count/datapoints in array
    avgHit = (60.0/avgHit);  //convert to rpm
    lastAvg = currentMillis;   //reset our timer
    }
    //time is only 15 seconds for testing purposes
    if((currentMillis-lastESPcom) > 5000){   //Timer for sending data to esp
      sendESPmessage(avgHit);
      lastESPcom = currentMillis;    //reset our timer
    }
  if((currentMillis-lastHit) > 3000){   //send attiny into sleep mode after 5 times the average of hits are counted (if spinning 60 rpm, turns off in 5 seconds)
    sendESPmessage(0.0);      //tell esp shaft has stopped spinning
    forceSleep();             //go to sleep
  }
  wasHighLast = state;
}

ATTINY84_BEARING_TEMP_Program

C/C++
This code measures the temperature of a MAX31855 module
#include <avr/sleep.h>
#include <avr/delay.h>
#include <avr/wdt.h>
#include <SoftwareSerial.h>
#include <SPI.h>
#include <Adafruit_MAX31855.h>

const int espWrite = 2;       //pin attached to ESP RX
#define espReset PA7       //pin attached to ESP_RESET
#define thrmPower PA1
#define secondThrm PA0
const float timeToWait = 120.0;
#define MAXDO 4     //Digital IO pins for SPI
#define MAXCSR 7    //right thermocouple CS
#define MAXCSL 8    //left thermocouple CS
#define MAXCLK 6

SoftwareSerial espCom(8, espWrite); //create software serial connection to esp [RX is arbitrary] (RX, TX)

Adafruit_MAX31855 thermocoupleL(MAXCLK, MAXCSL, MAXDO); // initialize the Thermocouple
Adafruit_MAX31855 thermocoupleR(MAXCLK, MAXCSR, MAXDO); // initialize the Thermocouple

// watchdog interrupt
ISR(WDT_vect)
{
  wdt_disable();  // disable watchdog
}

void myWatchdogEnable(const byte interval)
{
  MCUSR = 0;                          // reset various flags
  WDTCSR |= 0b00011000;               // see docs, set WDCE, WDE
  WDTCSR =  0b01000000 | interval;    // set WDIE, and appropriate delay

  wdt_reset();
  set_sleep_mode (SLEEP_MODE_PWR_DOWN);
  sleep_mode();            // now goes to Sleep and waits for the interrupt
}

void setup() {
  espCom.begin(9600);         //start serial connection with ESP
  pinMode(espReset, INPUT);   //reset pin (pin attached to ESP_RESET pin
  ADCSRA &= ~_BV(ADEN);       // ADC off
}

void loop() {
  DDRA |= (1 << thrmPower);       //pinMode(thrmPower, OUTPUT);
  PORTA |= (1 << thrmPower);      //digitalWrite(thrmPower, HIGH);
  double tempR = 0.0, tempL = 0.0;

  float ambTemp = thermocoupleL.readInternal();
  ambTemp *= 9.0; ambTemp /= 5.0;  ambTemp += 32;
  boolean second = digitalRead(secondThrm);
  tempL = thermocoupleL.readFarenheit();
  if (second == true)
    tempR = thermocoupleR.readFarenheit();
  PORTA &= ~(1 << thrmPower);     //digitalWrite(thrmPower, LOW);
  pinMode(thrmPower, INPUT);
  
  DDRA |= (1 << espReset);          //set pinmode Output
  PORTA &= ~(1 << espReset);        //then ground the reset of ESP
  _delay_ms(5);
  PORTA |= (1 << espReset);       //Make High to end reset
  pinMode(espReset, INPUT);           //Change our espReset pin to Input, more efficient for battery ops
  _delay_ms(100);

  if (!isnan(tempL)) {
    espCom.print("1:");espCom.print(tempL);
    if (!isnan(tempR) and second) {
      espCom.print("|2:");espCom.print(tempR);
    }
  }
  bool interv = false;
  int sleepIntervalL = 0,sleepIntervalR = 0,finInt;
  if((tempR-ambTemp) >= 0 && (tempR-ambTemp) < 100){
    sleepIntervalR = 5+(50-((tempR-ambTemp)/2.0));
    interv = true;
  }
  if((tempR-ambTemp) >= 0 && (tempR-ambTemp) < 100){
    sleepIntervalL = 5+(50-((tempR-ambTemp)/2.0));
    interv = true;
  }
  if(sleepIntervalL > sleepIntervalR){
    finInt = sleepIntervalR;
  }else if(sleepIntervalR > sleepIntervalL){
    finInt = sleepIntervalL;
  }else{
    finInt = 55;
  }
  for (int j = 0; j < finInt; j ++) {
    myWatchdogEnable (0b100001);  // 8 seconds
  }
}

ESP8266_Attiny_Program

C/C++
ESP8266 program to post data to a flask webpage from serial input sent by an ATTiny84.
#include <ESP8266WiFi.h>
#include <ArduinoJson.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClient.h> 
#include <EEPROM.h>
#include <ESP8266WebServer.h>

const char *broadcastssid = "device";       //Access point mode SSID we see in wifi manager
const char *broadcastpassword = "password";     //Access point password to log in to device
const byte button = 4;                          //Button to activate access point mode
bool doneWithWebpage = false;                   //State of webpage

ESP8266WebServer server(80);      //initialize our webserver

struct{
  float timeToWait = 60;            //time until next reset
  char routerSSID[30] = "";
  char routerPassword[30] = "";
  char deviceID[6] = "";            //id assigned to device
  char postURL[60] = "";            //url where data should be sent
  char flaskKey[30] = "";            //url where data should be sent
}eepromData;                        //struct already assigned as eepromData

/* Go to http://192.168.4.1 in a web browser
 * connected to this access point to see this device.
 */
 
void handleRoot() {       //Serves configuration webpage
  server.send(200, "text/html", "<form action=\"/submit\" method=\"POST\"><input type=\"text\" name=\"ssid\" placeholder=\"ssid\"></br><input type=\"password\" name=\"password\" placeholder=\"password\"></br><input type=\"text\" name=\"flaskkey\" placeholder=\"Server Security Key\"></br><input type=\"text\" name=\"post\" placeholder=\"postURL\"></br><input type=\"text\" name=\"time\" placeholder=\"reset delay (mins)\"></br><input type=\"submit\" value=\"submit\"></form><p>enter configuration</p>");
  //start server html and declare form
  //make router ssid input
  //make router password input
  //make flask security key input
  //make postURL to server input
  //make reset delay input
  //submit button and text
}

void handleSubmit(){      //handle data after submission
  if( ! server.hasArg("ssid") || ! server.hasArg("password") || server.arg("ssid") == NULL || server.arg("password") == NULL) { // If the POST request doesn't have ssid and password data
    server.send(400, "text/plain", "400: Invalid Request");         // The request is invalid, so send HTTP status 400
    return;
  }else{
    String ssid = "";
    String pass = "";
    for(byte i = 0; i < 30; i++){     //clears routerSSID char array
      eepromData.routerSSID[i] = 0;
    }
    for(byte i = 0; i < 30; i++){     //clears routerPassword char array
      eepromData.routerPassword[i] = 0;
    }
    for(byte i = 0; i < 60; i++){     //clears postURL char array
      eepromData.postURL[i] = 0;
    }
    for(byte i = 0; i < 30; i++){     //clears flaskKey char array
      eepromData.flaskKey[i] = 0;
    }
    if(server.arg("time").length() > 0){  //checks if reset delay field has text
      eepromData.timeToWait = server.arg("time").toFloat(); //set reset delay field after casting string to float
    }
    if(server.arg("post").length() > 0){  //checks if post url was set
      for(byte i = 0; i < server.arg("post").length(); i++){
        eepromData.postURL[i] = server.arg("post").charAt(i); //set new postURL
      }
    }
    for(byte i = 0; i < server.arg("flaskkey").length(); i++){
      eepromData.flaskKey[i] = server.arg("flaskkey").charAt(i);  //set new flask key
    }
    for(byte i = 0; i < server.arg("ssid").length(); i++){
      eepromData.routerSSID[i] = server.arg("ssid").charAt(i);  //set new ssid
      ssid += server.arg("ssid").charAt(i);
    }
    for(byte i = 0; i < server.arg("password").length(); i++){
      eepromData.routerPassword[i] = server.arg("password").charAt(i);  //set new password
      pass =+ server.arg("password").charAt(i);
    }
    Serial.println("new ssid " + ssid + " and password " + pass);
   writeEEPROM();       //save new credentials to eeprom
  }
  server.send(200, "text/plain", "credentials updated");  //respond to successful submission
  doneWithWebpage = true; //indicate done with ap mode
}

void serveWebserver(){      //setup access point mode
  delay(1000);
  Serial.print("Configuring access point...");
  WiFi.softAP(broadcastssid, broadcastpassword);  //start access point named broadcastssid with password broadcastpassword

  IPAddress myIP = WiFi.softAPIP();               //get ip address
  Serial.print("AP IP address: ");
  Serial.println(myIP);
  server.on("/", HTTP_GET, handleRoot);           //set up root link to webpage
  server.on("/submit", HTTP_POST, handleSubmit);  //set up link to submission webpage
  server.begin();                                 //start server
  Serial.println("HTTP server started");
}

void readEEPROM(){          //read in eeprom with struct eepromData
  EEPROM.begin(256);        //start eeprom read with 256 bytes
  Serial.println();
  EEPROM.get(0,eepromData); //get eeprom data
}
void writeEEPROM(){         //write data to eeprom
  EEPROM.begin(256);        //start eeprom write with 256 bytes
  Serial.println();
  EEPROM.put(0,eepromData); //put data in memory
  EEPROM.commit();          //commit memory to eeprom
}

void checkForDisplay(){                 //check if button is pressed to put device into access point mode
  pinMode(button, INPUT);
  if(digitalRead(button) == LOW){       //if button is LOW
    serveWebserver();                   //start webserver
    while(doneWithWebpage == false){    //serve webpage forever until config submitted
      server.handleClient();            //handle web requests
    }
    WiFi.softAP(broadcastssid, broadcastpassword,1,1);  //set ap mode with hidden ssid
  }
}

void setup() {
  Serial.begin(9600);
  checkForDisplay();      //check if button pressed
  long start = millis();
  bool gotSensorRead = false;
  String stosend = "";
  while(millis()-start < 1000){
    while(Serial.available() > 0){
      byte nb = Serial.read();
      Serial.print((nb));
      if(nb != byte('~')){
        stosend += char(nb);
      }else{
        start = -1000;
        gotSensorRead = true;
      }
    }
  }
  readEEPROM();           //read in eeprom
  for(byte j = 0; j < 30; j++){
    Serial.print(eepromData.routerSSID[j]);
  }
  Serial.println();
  for(byte j = 0; j < 30; j++){
    Serial.print(eepromData.routerPassword[j]);
  }
  if(gotSensorRead){
    stosend = stosend;
  }else{
    stosend = "None";
  }

  /*== Wifi initialization ==*/
  WiFi.begin(eepromData.routerSSID, eepromData.routerPassword);     //WiFi connection (network name,network password)
  while (WiFi.status() != WL_CONNECTED) {               //Wait for the WiFI connection completion
    delay(500);                                         //Give the esp some time before attempting wifi connection
    Serial.print(". ");
  }
  Serial.println();

  /*== Format data as JSON to send to server ==*/
  StaticJsonBuffer<200> messageBuffer;                //Create a JSON buffer
  JsonObject& message = messageBuffer.createObject(); //Creat a JSON object we can add our keys/values into
  message["id"] = eepromData.deviceID;
  message["network_key"] = eepromData.flaskKey;                    //Create a JSON Key called "key" with value secretFlaskKey
  message["battery_type"] = "1";
  message["battery_level"] = ((analogRead(A0)/1023.0)*11.5);
  
  JsonArray& sensors = message.createNestedArray("sensors");
  JsonObject& sensor1 = sensors.createNestedObject(); //Creat a JSON object we can add our keys/values into
  
  bool sec = false;
  String firstData = "";
  char sensor1Num = 255;
  String secondData = "";
  char sensor2Num = 255;
  int stage = 0;
  
  for(int i = 0; i < stosend.length()-1; i++){
    if(stosend[i] == ':'){
      stage++;
    }
    if(stosend[i] == '|'){
      sec = true;
      stage++;
    }
    if(stage == 0){
      sensor1Num = stosend[i];
    }else if(stage == 1){
      firstData += stosend[i];
    }else if(stage == 2){
      sensor2Num = stosend[i];
    }else if(stage == 3){
      secondData += stosend[i];
    }else{
      Serial.println(stosend[i]);
    }
  }
  sensor1["id"] = sensor1Num;
  if(sensor1Num == '1' or sensor1Num == '2')
    sensor1["type"] = "bearing_temp";
  else if(sensor1Num == '3')
    sensor1["type"] = "shaft_rpm";
  else
    sensor1["type"] = "null";   
  sensor1["data"] = firstData;
  if(!secondData.equals("")){
    JsonObject& sensor2 = sensors.createNestedObject(); //Creat a JSON object we can add our keys/values into
    sensor2["id"] = sensor2Num;
    if(sensor2Num == '1' or sensor2Num == '2')
      sensor2["type"] = "bearing_temp";
    else if(sensor2Num == '3')
      sensor2["type"] = "shaft_rpm";
    else
      sensor2["type"] = "null";  
    sensor2["data"] = secondData;
  }
  char payload[200];                    //Create a char array...
  message.printTo(payload);             //Then print the message object to the char array so we can send it as plaintext over wifi
  Serial.println(String(payload));

  /*== POST data to server ==*/
  if (WiFi.status() == WL_CONNECTED) {                    //Check if we are connected to wifi, if we are then continue with loop
    Serial.println("Wifi Connected");                                        
    HTTPClient http;                                      //Create HTTPClient object (HTTPClient handles our POST and GET requests)
    String sAddress = String(eepromData.postURL); //Make the server address out of components (our URLs should look like this "http://192.168.1.250:5000/sensorpost/this_sensor_id/"
    Serial.println(sAddress);
    http.begin(sAddress);                                 //Begin sending content to URL
    http.addHeader("Content-Type", "text/plain");         //Make a POST header
    int mStatus = http.POST(String(payload));             //POST our message (as a char array) to server, get error response code (200 == success, 404 or 500 == error)
    String returnpayload = http.getString();              //Get response from server (not necessary if server doesnt return a message)
    http.end();                                           //Close connection
    Serial.println(mStatus);
  }

  /*== GET data from server ==*/
  /*if (WiFi.status() == WL_CONNECTED) {
    HTTPClient http;
    http.begin("http://192.168.1.250:5000/getjson/");
    int httpCode = http.GET();                            //Send the request
    if (httpCode > 0) {                                   //Check the returning code (less than 0 is a client error)
      String payload = http.getString();                  //Get the request response payload
      Serial.println(payload);
    }
    http.end();
  }*/
  
  Serial.println("start deepsleep");
  ESP.deepSleep(int(eepromData.timeToWait * 60) * 1000000);    //Put esp into sleep mode for desired amount of time (reset must be tied to wake pin of esp)
}

void loop() {

}

Master Server Program

This is the python program that runs our Flask server

Credits

Jeremy McGinnis

Jeremy McGinnis

5 projects • 17 followers
I am a 24 year old Electrical Engineering student with two 3d printers, a cnc router and a lot of free time on my hands.

Comments