The use of the ESP8266 in the world of IoT

User avatar
By youngestEVer
#95916 Hello everyone,

ESP8266 NodeMCU:

I have been working on this project that pulls battery management system parameters from CAN bus, and sends them to MQTT server. Everything about that works great, but this morning I added captive portal wifi setup from a youtube tutorial. I added some logic so it will only go into setup mode if the setupWifi input is pulled low. All of that works good.

The portal works great, but the issues start when trying to reconfigure the wifi to a mobile hotspot. If I configure to my home wifi network, it works perfectly on any device I config it on. If I configure to connect to my mobile hotspot ("Adam's iPhone 13 Pro"), it only works if I do the setup on safari on my iphone or ipad. I have tried with 2 PCs, firefox, chrome, and edge browsers, amazon fire tablet, and a mac pro, and the ESP won't connect. In the serial monitor, it shows trying to connect to "Adam's iPhone 13 Pro", so it appears to have saved correctly, but it never connects. But if I do the config with my iPad or an iPhone, it connect right away.

In the hotspot settings "maximize compatibility" is also turned on, I found out that needs to be on to work

Any feedback would be greatly appreciated, I have no clue what this problem could be - very odd to me, especially since it still formats the SSID correctly on the serial monitor. Don't understand how the config settings don't work on a standard browser, but if the same thing is done on my iphone or ipad, it works perfectly. I'm completely stumped

Code: Select allHere's the code:

#include <ESP8266WebServer.h>
#include <EEPROM.h>
ESP8266WebServer    server(80);

struct settings {
  char ssid[30];
  char password[30];
} user_wifi = {};

const int setupPin = 4;
int restartCounter = 0;

#include <ESP8266WiFi.h>
#include <PubSubClient.h>

#include <mcp_can.h>
#include <SPI.h>

long unsigned int rxId;
unsigned char len = 0;
unsigned char rxBuf[8];

#define CAN0_INT 16                              // Set INT to pin 2 (nodemcu = 16, nano = 2)
MCP_CAN CAN0(5);                               // Set CS to pin 10 (nodemcu = 5, nano = 10)


const char* mqtt_server = "test-server";
int MQTTrestartCounter = 0;

WiFiClient espClient;
PubSubClient client(espClient);
unsigned long lastMsg = 0;

char SOCMsg[10];
int SOC = 0;

char averageTempMsg[4];
int averageTemp = 0;

char maxTempMsg[4];
int maxTemp = 0;

char minTempMsg[4];
int minTemp = 0;

char packCurrentMsg[10];
char packCurrentToSend[10];
float packCurrent = 0.0;

char averageCellVoltageMsg[10];
char averageCellVoltageToSend[10];
float averageCellVoltage = 0.000;

char highCellVoltageMsg[10];
char highCellVoltageToSend[10];
float highCellVoltage = 0.000;

char lowCellVoltageMsg[10];
char lowCellVoltageToSend[10];
float lowCellVoltage = 0.000;

char packVoltageMsg[10];
char packVoltageToSend[10];
float packVoltage = 0.0;

void setup_wifi() {

  if(digitalRead(setupPin) == 1){
  delay(10);
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(user_wifi.ssid);

  WiFi.mode(WIFI_STA);
  WiFi.begin(user_wifi.ssid, user_wifi.password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
    restartCounter++;
    if(restartCounter >= 30){
      Serial.println("No WiFi connection...restarting system.");
      ESP.restart();
    }
  }

  randomSeed(micros());

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
  }
  else {
    Serial.println("Going into WiFi Setup Mode");
    wifiConfig();
  }
}

void callback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");
  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);
  }
  Serial.println();

  // Switch on the LED if an 1 was received as first character
  //  if ((char)payload[0] == '1') {
  //    digitalWrite(BUILTIN_LED, LOW);   // Turn the LED on (Note that LOW is the voltage level
  //    // but actually the LED is on; this is because
  //    // it is active low on the ESP-01)
  //  } else {
  //    digitalWrite(BUILTIN_LED, HIGH);  // Turn the LED off by making the voltage HIGH
  //  }

}

void reconnect() {
  // Loop until we're reconnected
  if(digitalRead(setupPin) == 1){
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Create a random client ID
    String clientId = "ESP8266Client-"; //update  name HERE
    clientId += String(random(0xffff), HEX);
    // Attempt to connect
    if (client.connect(clientId.c_str(), "test", "test1234!")) {
      Serial.println("connected");
      // Once connected, publish an announcement...
      //client.publish("device/31415/temp", "hello world");
      // ... and resubscribe
      client.subscribe("device/31415/led");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
      MQTTrestartCounter++;

      if(MQTTrestartCounter >= 3){
        Serial.println("MQTT Connect timeout, restarting the system.");
        ESP.restart();
      }
      }
    }
  }
}

void setup() {
  //pinMode(BUILTIN_LED, OUTPUT);     // Initialize the BUILTIN_LED pin as an output
  Serial.begin(9600);
  pinMode(setupPin, INPUT_PULLUP);
  EEPROM.begin(sizeof(struct settings) );
  EEPROM.get( 0, user_wifi );
  server.on("/",  handlePortal);
  server.begin();
  setup_wifi();
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);

  if (CAN0.begin(MCP_STDEXT, CAN_250KBPS, MCP_8MHZ) == CAN_OK) Serial.print("MCP2515 Init!\r\n");
  else Serial.print("MCP2515 Init Failed!\r\n");
  pinMode(CAN0_INT, INPUT);                       // Setting pin 2 for /INT input

  CAN0.setMode(MCP_NORMAL);                // Change to normal mode to allow messages to be transmitted
   
  delay(50);
}

void wifiConfig(){
  WiFi.mode(WIFI_AP);
  WiFi.softAP("Setup Portal", "12345678");
}

void handlePortal() {

  if(digitalRead(setupPin) == 0){

  if (server.method() == HTTP_POST) {

    strncpy(user_wifi.ssid,     server.arg("ssid").c_str(),     sizeof(user_wifi.ssid) );
    strncpy(user_wifi.password, server.arg("password").c_str(), sizeof(user_wifi.password) );
    user_wifi.ssid[server.arg("ssid").length()] = user_wifi.password[server.arg("password").length()] = '\0';
    EEPROM.put(0, user_wifi);
    EEPROM.commit();

    server.send(200,   "text/html",  "<!doctype html><html lang='en'><head><meta charset='utf-8'><meta name='viewport' content='width=device-width, initial-scale=1'><title>Wifi Setup</title><style>*,::after,::before{box-sizing:border-box;}body{margin:0;font-family:'Segoe UI',Roboto,'Helvetica Neue',Arial,'Noto Sans','Liberation Sans';font-size:1rem;font-weight:400;line-height:1.5;color:#212529;background-color:#f5f5f5;}.form-control{display:block;width:100%;height:calc(1.5em + .75rem + 2px);border:1px solid #ced4da;}button{border:1px solid transparent;color:#fff;background-color:#007bff;border-color:#007bff;padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem;width:100%}.form-signin{width:100%;max-width:400px;padding:15px;margin:auto;}h1,p{text-align: center}</style> </head> <body><main class='form-signin'> <h1>Wifi Setup</h1> <br/> <p>Your settings have been saved successfully!<br />Device is restarting, please turn off WiFi setup switch.</p></main></body></html>" );
    delay(5000);
    ESP.restart();
  } else {

    server.send(200,   "text/html", "<!doctype html><html lang='en'><head><meta charset='utf-8'><meta name='viewport' content='width=device-width, initial-scale=1'><title>Wifi Setup</title> <style>*,::after,::before{box-sizing:border-box;}body{margin:0;font-family:'Segoe UI',Roboto,'Helvetica Neue',Arial,'Noto Sans','Liberation Sans';font-size:1rem;font-weight:400;line-height:1.5;color:#212529;background-color:#f5f5f5;}.form-control{display:block;width:100%;height:calc(1.5em + .75rem + 2px);border:1px solid #ced4da;}button{cursor: pointer;border:1px solid transparent;color:#fff;background-color:#007bff;border-color:#007bff;padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem;width:100%}.form-signin{width:100%;max-width:400px;padding:15px;margin:auto;}h1{text-align: center}</style> </head> <body><main class='form-signin'> <form action='/' method='post'> <h1 class=''>Wifi Setup</h1><br/><div class='form-floating'><label>SSID</label><input type='text' class='form-control' name='ssid'> </div><div class='form-floating'><br/><label>Password</label><input type='password' class='form-control' name='password'></div><br/><br/><button type='submit'>Save</button><p style='text-align: right'><a href='website.com' style='color: #32C5FF'>website.com</a></p></form></main> </body></html>" );
    }
  }
}

void loop() {

  if (!client.connected()) {
    reconnect();
  }
  client.loop();
 
  if(digitalRead(setupPin) == 0){
  server.handleClient();
  }

  if(digitalRead(setupPin) == 0){ //check if user is requesting setup
      //open wifi config portal
      wifiConfig();
    }

  CAN0.readMsgBuf(&rxId, &len, rxBuf); // Read data: len = data length, buf = data byte(s)

  if (rxId == 0x150) {
    byte averageCellHighByte = rxBuf[0];
    byte averageCellLowByte = rxBuf[1];
    unsigned int together = word(averageCellHighByte, averageCellLowByte);

    averageCellVoltage = together;
    averageCellVoltage = averageCellVoltage / 10000;

    byte lowCellHighByte = rxBuf[2];
    byte lowCellLowByte = rxBuf[3];
    unsigned int together2 = word(lowCellHighByte, lowCellLowByte);
    lowCellVoltage = together2;
    lowCellVoltage = lowCellVoltage / 10000;

    byte highCellHighByte = rxBuf[4];
    byte highCellLowByte = rxBuf[5];
    unsigned int together3 = word(highCellHighByte, highCellLowByte);
    highCellVoltage = together3;
    highCellVoltage = highCellVoltage / 10000;

    byte packVoltageHighByte = rxBuf[6];
    byte packVoltageLowByte = rxBuf[7];
    unsigned int together4 = word(packVoltageHighByte, packVoltageLowByte);
    packVoltage = together4;
    packVoltage = packVoltage / 10;

  }

  if (rxId == 0x151) {
    SOC = rxBuf[0];
    SOC = SOC / 2;

    averageTemp = rxBuf[1];
    maxTemp = rxBuf[2];
    minTemp = rxBuf[3];

    byte packCurrentHighByte = rxBuf[4];
    byte packCurrentLowByte = rxBuf[5];
    int together5 = word(packCurrentHighByte, packCurrentLowByte);
    packCurrent = together5;
    packCurrent = packCurrent / 10;
    //Serial.println(packCurrent);
   
  }


  unsigned long now = millis();
  if (now - lastMsg > 1000) {
    lastMsg = now;
    if(digitalRead(setupPin) == 1){
    sendDataToCloud();
    }
  }
}

void sendDataToCloud() {
      //vales from can message 0x150
   
    sprintf (SOCMsg, "%d", SOC);
    Serial.print("Publish message: ");
    Serial.println(SOCMsg);
    client.publish("device/31415/SOC", SOCMsg);

    delay(5);

    sprintf (averageTempMsg, "%d", averageTemp);
    Serial.print("Publish message: ");
    Serial.println(averageTempMsg);
    client.publish("device/31415/Average_Temperature", averageTempMsg);

    delay(5);

    sprintf (maxTempMsg, "%d", maxTemp);
    Serial.print("Publish message: ");
    Serial.println(maxTempMsg);
    client.publish("device/31415/Max_Temperature", maxTempMsg);

    delay(5);

    sprintf (minTempMsg, "%d", minTemp);
    Serial.print("Publish message: ");
    Serial.println(minTempMsg);
    client.publish("device/31415/Min_Temperature", minTempMsg);

    delay(5);
   
    dtostrf(packCurrent, 6, 1, packCurrentToSend);
    sprintf (packCurrentMsg, "%s", packCurrentToSend);
    Serial.print("Publish message: ");
    Serial.println(packCurrentMsg);
    client.publish("device/31415/Pack_Current", packCurrentMsg);

    delay(5);

    //values from can message 0x151

    dtostrf(averageCellVoltage, 4, 3, averageCellVoltageToSend);
    sprintf (averageCellVoltageMsg, "%s", averageCellVoltageToSend);
    Serial.print("Publish message: ");
    Serial.println(averageCellVoltageMsg);
    client.publish("device/31415/Average_Cell_Voltage", averageCellVoltageMsg);

    delay(5);

    dtostrf(highCellVoltage, 4, 3, highCellVoltageToSend);
    sprintf (highCellVoltageMsg, "%s", highCellVoltageToSend);
    Serial.print("Publish message: ");
    Serial.println(highCellVoltageMsg);
    client.publish("device/31415/High_Cell_Voltage", highCellVoltageMsg);

    delay(5);

    dtostrf(lowCellVoltage, 4, 3, lowCellVoltageToSend);
    sprintf (lowCellVoltageMsg, "%s", lowCellVoltageToSend);
    Serial.print("Publish message: ");
    Serial.println(lowCellVoltageMsg);
    client.publish("device/31415/Low_Cell_Voltage", lowCellVoltageMsg);

    delay(5);

    dtostrf(packVoltage, 5, 1, packVoltageToSend);
    sprintf (packVoltageMsg, "%s", packVoltageToSend);
    Serial.print("Publish message: ");
    Serial.println(packVoltageMsg);
    client.publish("device/31415/Pack_Voltage", packVoltageMsg);

    delay(5);
 
}