Using the new Arduino IDE for ESP8266 and found bugs, report them here

Moderator: igrr

User avatar
By Daemach
#54576 I am trying to get the OTA updating working, but it's in a crash loop. It fails like this every time it runs, Any advice you can offer would be greatly appreciated. I put the update check in the setup function:

attempting HTTP update...

ets Jan 8 2013,rst cause:2, boot mode:(3,6)

load 0x4010f000, len 1384, room 16
tail 8
chksum 0x2d
csum 0x2d
v60000318
@cp:0
ld

This is the bin file - it's a tomcat webserver but the browser downloads it sucessfully: http://u.synaptrix.com/spooky.bin

Here are the compile stats:

Sketch uses 343,982 bytes (32%) of program storage space. Maximum is 1,044,464 bytes.
Global variables use 38,292 bytes (46%) of dynamic memory, leaving 43,628 bytes for local variables. Maximum is 81,920 bytes.

I'm a hack and it often takes a lot of work to get things working - please forgive the ugly code. I'll clean it up later.

Code: Select all#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <ESP8266httpUpdate.h>
#include <Wire.h>
#include <SHT21.h>
#include <Adafruit_Sensor.h>
#include "Adafruit_MCP23008.h"
#include "Adafruit_TSL2591.h"





#include <DNSServer.h>
#include <ESP8266WebServer.h>
#include <WiFiManager.h>          //https://github.com/tzapu/WiFiManager

//for LED status
#include <Ticker.h>
#include "SparkFunMPL3115A2.h"
#include "sensors.h"

//initialize
Ticker ticker;

Adafruit_MCP23008 mcp;
Adafruit_TSL2591 tsl = Adafruit_TSL2591(2591); // pass in a number for the sensor identifier (for your use later)

//Baro
MPL3115A2 myPressure;

// Create an ESP8266 WiFiClient class to connect to the MQTT server.
WiFiClient client;
HTTPClient http;

int redirectTimeout = 10000;

//flag for saving data
bool shouldSaveConfig = false;

//callback notifying us of the need to save config
void saveConfigCallback () {
  Serial.println("Should save config");
  shouldSaveConfig = true;
}


void tick()
{
  //toggle state
  int state = digitalRead(BUILTIN_LED);  // get the current state of GPIO1 pin
  digitalWrite(BUILTIN_LED, !state);     // set pin to the opposite state
}

int getRSSIasQuality(int RSSI) {
  int quality = 0;

  if (RSSI <= -100) {
    quality = 0;
  } else if (RSSI >= -50) {
    quality = 100;
  } else {
    quality = 2 * (RSSI + 100);
  }
  return quality;
}

//gets called when WiFiManager enters configuration mode
void configModeCallback (WiFiManager *myWiFiManager) {
  Serial.println("Entered config mode");
  Serial.println(WiFi.softAPIP());
  //if you used auto generated SSID, print it
  Serial.println(myWiFiManager->getConfigPortalSSID());
  //entered config mode, make led toggle faster
  ticker.attach(1.2, tick);
}


#define DEVICECODE        1
#define VERSION           1



float convertC2F(float value)
{
  return (value * 9.0) / 5.0 + 32.0; // Convert Celcius to Fahrenheit
}


/**************************************************************************/
/*
    Show how to read IR and Full Spectrum at once and convert to lux
*/
/**************************************************************************/
void advancedRead(void)
{
  // More advanced data read example. Read 32 bits with top 16 bits IR, bottom 16 bits full spectrum
  // That way you can do whatever math and comparisons you want!
  uint32_t lum = tsl.getFullLuminosity();
  uint16_t ir, full;
  float lux;
  ir = lum >> 16;
  full = lum & 0xFFFF;
  lux = tsl.calculateLux(full, ir);
  Serial.print("[ "); Serial.print(millis()); Serial.print(" ms ] ");
  Serial.print("IR: "); Serial.print(ir);  Serial.print("  ");
  Serial.print("Full: "); Serial.print(full); Serial.print("  ");
  Serial.print("Visible: "); Serial.print(full - ir); Serial.print("  ");
  Serial.print("Lux: "); Serial.println(lux);
}

/**************************************************************************/
/*
    Configures the gain and integration time for the TSL2591
*/
/**************************************************************************/
void configureSensor(void)
{
  // You can change the gain on the fly, to adapt to brighter/dimmer light situations
  //tsl.setGain(TSL2591_GAIN_LOW);    // 1x gain (bright light)
  tsl.setGain(TSL2591_GAIN_MED);      // 25x gain
  // tsl.setGain(TSL2591_GAIN_HIGH);   // 428x gain

  // Changing the integration time gives you a longer time over which to sense light
  // longer timelines are slower, but are good in very low light situtations!
  tsl.setTiming(TSL2591_INTEGRATIONTIME_100MS);  // shortest integration time (bright light)
  // tsl.setTiming(TSL2591_INTEGRATIONTIME_200MS);
  // tsl.setTiming(TSL2591_INTEGRATIONTIME_300MS);
  // tsl.setTiming(TSL2591_INTEGRATIONTIME_400MS);
  // tsl.setTiming(TSL2591_INTEGRATIONTIME_500MS);
  // tsl.setTiming(TSL2591_INTEGRATIONTIME_600MS);  // longest integration time (dim light)

  /* Display the gain and integration time for reference sake */
  Serial.println("------------------------------------");
  Serial.print  ("Gain:         ");
  tsl2591Gain_t gain = tsl.getGain();
  switch (gain)
  {
    case TSL2591_GAIN_LOW:
      Serial.println("1x (Low)");
      break;
    case TSL2591_GAIN_MED:
      Serial.println("25x (Medium)");
      break;
    case TSL2591_GAIN_HIGH:
      Serial.println("428x (High)");
      break;
    case TSL2591_GAIN_MAX:
      Serial.println("9876x (Max)");
      break;
  }
  Serial.print  ("Timing:       ");
  Serial.print((tsl.getTiming() + 1) * 100, DEC);
  Serial.println(" ms");
  Serial.println("------------------------------------");
  Serial.println("");
}

int delayLen = 20000;
String MAC;
String SN;
char blynk_token[34] = "YOUR_BLYNK_TOKEN";

long sendTimer = millis();
float altitude = -999;
unsigned long IAQ_last = 0;
//String postData;
boolean s1Last = 1;
boolean s2Last = 1;
boolean s3Last = 1;
boolean s4Last = 1;
boolean s1 = 0;
boolean s2 = 0;
boolean s3 = 0;
boolean s4 = 0;

long s1db = 0;
long s2db = 0;
long s3db = 0;
long s4db = 0;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  Wire.begin();
  Wire.setClock(100000);  //Set clock speed to 100KHz for stability

  Serial.println("I live...");
  //  Serial.print(F("Connecting to "));
  //  Serial.println(WLAN_SSID);
  //  unsigned long wifiTimeout = millis();
  //
  //  WiFi.begin(WLAN_SSID, WLAN_PASS);

  //set led pin as output
  pinMode(BUILTIN_LED, OUTPUT);

  mcp.begin();      // use default address 0

  mcp.pinMode(0, INPUT);
  mcp.pullUp(0, HIGH);  // turn on a 100K pullup internally
  mcp.pinMode(1, INPUT);
  mcp.pullUp(1, HIGH);  // turn on a 100K pullup internally
  mcp.pinMode(2, INPUT);
  mcp.pullUp(2, HIGH);  // turn on a 100K pullup internally
  mcp.pinMode(3, INPUT);
  mcp.pullUp(3, HIGH);  // turn on a 100K pullup internally

  Serial.println("Starting TSL2591...!");

  if (tsl.begin())
  {
    Serial.println("Found a TSL2591 sensor");

    /* Configure the sensor */
    configureSensor();
    advancedRead();

  } else
  {
    Serial.println("No TSL2591 sensor found");
  }


  myPressure.begin(); // Get sensor online

  //Configure the sensor
  myPressure.setModeAltimeter(); // Measure altitude above sea level in meters

  myPressure.setOversampleRate(64); // Set Oversample to the recommended 128
  myPressure.enableEventFlags(); // Enable all three pressure and temp event flags

  delay(2000);
  unsigned long start = millis();

  while ((altitude <= 0 | altitude > 9000) & millis() - start < 10000) {
    altitude = myPressure.readAltitude();
    yield();
  }

  if (altitude <= 0 | altitude > 9000) Serial.println("Crap - baro timed out :/");

  myPressure.setModeBarometer(); // Measure pressure in Pascals from 20 to 110 kPa


  WiFiManager wifiManager;

  MAC = WiFi.macAddress();

  Serial.println(MAC);

  MAC.replace(":", "");

  SN = MAC + ESP.getChipId();




  //reset settings - for testing
  //wifiManager.resetSettings();

  wifiManager.bDisableIPhonePortal = true;

  //set callback that gets called when connecting to previous WiFi fails, and enters Access Point mode
  wifiManager.setAPCallback(configModeCallback);

  //  window.setTimeout(function(){ window.location = "http://www.yoururl.com"; },3000);
  String tempURL = "<script>window.setTimeout(function(){ window.location = \"" + redirectURL + SN + "\"; }," + redirectTimeout + ");</script>";
  wifiManager.setRedirectElement(tempURL);

  WiFiManagerParameter custom_text("<p>Please choose the access point that you want to connect to above, then enter the password.</p><p>Paste your token into the field below.</p>");
  wifiManager.addParameter(&custom_text);

  //set config save notify callback
  wifiManager.setSaveConfigCallback(saveConfigCallback);

  WiFiManagerParameter custom_blynk_token("blynk", "blynk token", blynk_token, 32);

  wifiManager.addParameter(&custom_blynk_token);


  //fetches ssid and pass and tries to connect
  //if it does not connect it starts an access point with the specified name
  //here  "AutoConnectAP"
  //and goes into a blocking loop awaiting configuration
  if (!wifiManager.autoConnect()) {
    // start ticker with 0.5 because we start in AP mode and try to connect
    ticker.attach(0.6, tick);
    Serial.println("failed to connect and hit timeout");
    //reset and try again, or maybe put it to deep sleep
    ESP.reset();
    delay(1000);
  }

  Serial.println("WiFi is connected.");

 
  Serial.println("attempting HTTP update...");
 
   t_httpUpdate_return ret = ESPhttpUpdate.update("http://u.synaptrix.com/spooky.bin");
        //t_httpUpdate_return  ret = ESPhttpUpdate.update("https://server/file.bin");

    switch(ret) {
        case HTTP_UPDATE_FAILED:
            Serial.printf("HTTP_UPDATE_FAILED Error (%d): %s", ESPhttpUpdate.getLastError(), ESPhttpUpdate.getLastErrorString().c_str());
            break;

        case HTTP_UPDATE_NO_UPDATES:
            Serial.println("HTTP_UPDATE_NO_UPDATES");
            break;

        case HTTP_UPDATE_OK:
            Serial.println("HTTP_UPDATE_OK");
            break;
    }

  Serial.println();

  digitalWrite(BUILTIN_LED, HIGH);

  ticker.detach();

  strcpy(blynk_token, custom_blynk_token.getValue());

  Serial.println(blynk_token);


  //Initialize switches

  s1Last = mcp.digitalRead(0); Serial.print("Initializing Switch1.  Status: "); Serial.println(s1Last);
  s2Last = mcp.digitalRead(1); Serial.print("Initializing Switch2.  Status: "); Serial.println(s2Last);
  s3Last = mcp.digitalRead(2); Serial.print("Initializing Switch3.  Status: "); Serial.println(s3Last);
  s4Last = mcp.digitalRead(3); Serial.print("Initializing Switch4.  Status: "); Serial.println(s4Last);



  //  while (WiFi.status() != WL_CONNECTED) {
  //    delay(500);
  //    Serial.print(F("."));
  //
  //    if ((millis() - wifiTimeout) >= 10000 && BYPASSWIFITIMEOUT == 0) {
  //      break;
  //    }
  //  }
  //
  //  if (WiFi.status() == WL_CONNECTED) {
  //    Serial.println();
  //
  //    Serial.println(F("WiFi connected"));
  //    Serial.println(F("IP address: "));
  //    Serial.println(WiFi.localIP());
  //
  //  } else {
  //    Serial.println(F("WiFi NOT connected"));
  //  }

  myPressure.readPressure();

}

boolean s1c = 0;
boolean s2c = 0;
boolean s3c = 0;
boolean s4c = 0;
long dbdelay = 100;

boolean gpio0 = 0;
boolean gpio0last =0 ;

void loop() {

  // Check for reset
  gpio0 = digitalRead(0);

  if (gpio0 != gpio0last){

   
  }
 

  boolean sendNow = 0;
  String postData = "sn=" + String(SN) + "&dc=" + String(DEVICECODE) + "&v=" + String(VERSION);

  s1 = mcp.digitalRead(0);

  if (s1 != s1Last) {

    if (s1c == 0) {
      s1db = millis();
      s1c = 1;
    } else if (millis() >=  s1db + dbdelay) {
      postData += "&s1=" + String(s1);
      //change has occurred...
      Serial.print("Switch1 has changed states.  New value: "); Serial.println(s1);
      sendNow = 1;
      s1Last = s1;

      s1c = 0;
    }
  }

  s2 = mcp.digitalRead(1);

  if (s2 != s2Last) {

    if (s2c == 0) {
      s2db = millis();
      s2c = 1;
    } else if (millis() >=  s2db + dbdelay) {
      postData += "&s2=" + String(s2);
      //change has occurred...
      Serial.print("Switch2 has changed states.  New value: "); Serial.println(s2);
      sendNow = 1;
      s2Last = s2;

      s2c = 0;
    }
  }

  s3 = mcp.digitalRead(2);

  if (s3 != s3Last) {

    if (s3c == 0) {
      s3db = millis();
      s3c = 1;
    } else if (millis() >=  s3db + dbdelay) {
      postData += "&s3=" + String(s3);
      //change has occurred...
      Serial.print("Switch3 has changed states.  New value: "); Serial.println(s3);
      sendNow = 1;
      s3Last = s3;

      s3c = 0;
    }
  }

  s4 = mcp.digitalRead(3);

  if (s4 != s4Last) {

    if (s4c == 0) {
      s4db = millis();
      s4c = 1;
    } else if (millis() >=  s4db + dbdelay) {
      postData += "&s4=" + String(s4);
      //change has occurred...
      Serial.print("Switch4 has changed states.  New value: "); Serial.println(s4);
      sendNow = 1;
      s4Last = s4;

      s4c = 0;
    }
  }

  //  s2 = mcp.digitalRead(1); Serial.print("Initializing Switch2.  Status: "); Serial.print(s2Init);
  //  s3 = mcp.digitalRead(2); Serial.print("Initializing Switch3.  Status: "); Serial.print(s3Init);
  //  s4 = mcp.digitalRead(3); Serial.print("Initializing Switch4.  Status: "); Serial.print(s4Init);


  if (millis() >= sendTimer + delayLen) {
    //    Serial.print(postData); Serial.print(" -- ");
    //
    //    Serial.print(millis()); Serial.print(" -- "); Serial.print(delayLen);  Serial.print(" -- "); Serial.println(sendTimer);
    //    Serial.println("sendtimer fired");
    //

    Serial.print("SHT20 here --> ");
    SHT21.readSensor();

    Serial.print("Humidity(%RH): ");
    Serial.print(SHT21.humi, 1);
    Serial.print("     Temperature(C/F): ");
    Serial.print(SHT21.temp, 1);  Serial.print("/");
    Serial.println(convertC2F(SHT21.temp));

    // 9/5 *C + 32

    postData += "&t=" + String(convertC2F(SHT21.temp)) + "&h=" + String(SHT21.humi);


    Serial.print("IAQ-Core here --> ");
    unsigned long IAQCheck = read_IAQ(); // read iAQ-core
    Serial.print(" == "); Serial.print(IAQ_last); Serial.print("/"); Serial.print(IAQCheck); Serial.print(" == ");
    IAQ_last = IAQCheck;
    Serial.println();

    postData += "&iaq=" + String(IAQCheck);




    Serial.print("MPL here --> ");

    Serial.print("Altitude(M/ft):");
    Serial.print(altitude, 2);
    Serial.print("/");
    Serial.print(altitude * 3.28084, 2);

    postData += "&alt=" + String(altitude * 3.28084);

    float pressure = myPressure.readPressure();
    Serial.print(" Pressure(Pa):");
    Serial.print(pressure, 2);

    postData += "&prs=" + String(pressure);

    float temperature = myPressure.readTemp();
    Serial.print(" Temp(C):");
    Serial.print(temperature, 2);

    postData += "&t2=" + String(convertC2F(temperature));

    //References:
    //Definition of "altimeter setting": http://www.crh.noaa.gov/bou/awebphp/definitions_pressure.php
    //Altimeter setting: http://www.srh.noaa.gov/epz/?n=wxcalc_altimetersetting
    //Altimeter setting: http://www.srh.noaa.gov/images/epz/wxcalc/altimeterSetting.pdf
    //Verified against Boulder, CO readings: http://www.crh.noaa.gov/bou/include/webpres.php?product=webpres.txt

    //const int station_elevation_ft = 5374; //Must be obtained with a GPS unit
    float station_elevation_m = altitude * 0.3048; //I'm going to hard code this
    //const int station_elevation_m = 140; //Accurate for the roof on my house
    //1 pascal = 0.01 millibars
    pressure /= 100; //pressure is now in millibars

    float part1 = pressure - 0.3; //Part 1 of formula

    const float part2 = 8.42288 / 100000.0;
    float part3 = pow((pressure - 0.3), 0.190284);
    float part4 = (float)station_elevation_m / part3;
    float part5 = (1.0 + (part2 * part4));
    float part6 = pow(part5, (1.0 / 0.190284));
    float altimeter_setting_pressure_mb = part1 * part6; //Output is now in adjusted millibars
    float baroin = altimeter_setting_pressure_mb * 0.02953;

    Serial.print(" Altimeter setting InHg:");
    Serial.print(baroin, 2);

    postData += "&baro=" + String(baroin);

    Serial.println();

    uint32_t lum = tsl.getFullLuminosity();
    uint16_t ir, full;
    int lux;
    ir = lum >> 16;
    full = lum & 0xFFFF;
    lux = tsl.calculateLux(full, ir);
    Serial.print("TSL2591 here --> ");
    Serial.print("IR: "); Serial.print(ir);  Serial.print("  ");
    Serial.print("Full: "); Serial.print(full); Serial.print("  ");
    Serial.print("Visible: "); Serial.print(full - ir); Serial.print("  ");
    Serial.print("Lux: "); Serial.println(lux);

    postData += "&ir=" + String(ir) + "&full=" + String(full) + "&vis=" + String(full - ir) + "&lux=" + String(lux);

    postData += "&vx=" + String(analogRead(A0));

    sendNow = 1;
  }


  //  delay(delayLen);

  if (sendNow) {
    String URL = dataURL + postData;

    Serial.print(getRSSIasQuality(WiFi.RSSI())); Serial.print("%  -->  ");  Serial.println(URL);

    //  int quality = getRSSIasQuality(WiFi.RSSI(indices[i]))

    http.begin(URL);
    //  http.addHeader("Content-Type", "application/x-www-form-urlencoded");
    //  http.POST(postData);
    http.GET();
    String response = http.getString();
    response.trim();
    int result = response.toInt();
    http.writeToStream(&Serial);
    http.end();

    Serial.print("==="); Serial.print(result); Serial.print("===");

    delayLen = (result !=0 ) ? result * 1000 : 10000;

    Serial.println();
    sendNow = 0;
    sendTimer = millis();
    postData = "";
  }
}



User avatar
By Daemach
#54646 Sorry to bump, but I could really use some advice on this - can someone give me an idea of what I should do next please? Is the file too big?
User avatar
By Daemach
#55178 I'm sorry about the delayed response. I just saw this.

No, it fails using that template too:

[SETUP] WAIT 4...
[SETUP] WAIT 3...
[SETUP] WAIT 2...
[SETUP] WAIT 1...

ets Jan 8 2013,rst cause:2, boot mode:(1,7)


ets Jan 8 2013,rst cause:4, boot mode:(1,7)

wdt reset


Interestingly, when I reset the unit, it just spits out garbage in the serial monitor. I have to upload the sketch every time which makes me think that it's trying to install the bin and it's breaking somehow.

Here's what I've done to create the bin file - maybe it's hosed?

  • Compile blink.ino
  • Open temp folder, sort by date modified and find the most recent build folder.
  • Rename blink.ino.bin to spooky.bin and upload to the server.

I verified that the compiled file uploaded and ran successfully before putting it on the server.