esp8266 / Arduino

ESP8266 core for Arduino
GNU Lesser General Public License v2.1
15.89k stars 13.35k forks source link

Adding a single global variable causes uploaded binary to not run #547

Closed skandragon closed 8 years ago

skandragon commented 8 years ago

This code compiles, but does not run correctly on the device:

#define USE_HUMIDITY 0

#include "Arduino.h"

#if USE_HUMIDITY
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <SparkFunHTU21D.h>
HTU21D myHumidity;
#endif

void setup() 
{
  Serial.begin(115200);
  Serial.println("\n\nOrientation Sensor Raw Data Test\n");
}

bool first = true;
void loop() 
{
  Serial.println("Loop.");

  if (first) {
    first = false;
    delay(1000);
#if USE_HUMIDITY
    delay(100);
    myHumidity.begin();    
#endif
  }

#if USE_HUMIDITY
  float temp = myHumidity.readTemperature();
  float humd = myHumidity.readHumidity();

  Serial.print(" Temperature:");
  Serial.print(temp, 1);
  Serial.print("C");
  Serial.print(" Humidity:");
  Serial.print(humd, 1);
  Serial.print("%");
  Serial.println();
#endif

  delay(1000);
}

Removing all the parts that are already #ifdef'd out causes it to run properly. Something, somewhere, is insane.

Links2004 commented 8 years ago

please add Serial.setDebugOutput(true); to setup() and poste the Serial output. is there a reason for the "if (first) {" construct normally you can simply move the code to setup.

#include <Arduino.h>
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <SparkFunHTU21D.h>
HTU21D myHumidity;

void setup() 
{
  Serial.begin(115200);
  Serial.setDebugOutput(true);

  delay(1000);
  Serial.println("\n\nOrientation Sensor Raw Data Test\n");
  Serial.flush();
  myHumidity.begin();   
  Serial.println("Setup done.\n");
  Serial.flush();
}

void loop() 
{
  Serial.println("Loop.");

  float temp = myHumidity.readTemperature();
  float humd = myHumidity.readHumidity();

  Serial.print("Temperature:");
  Serial.print(temp, 1);
  Serial.print("C");
  Serial.print(" Humidity:");
  Serial.print(humd, 1);
  Serial.println("%");

  delay(1000);
}
skandragon commented 8 years ago

The original intent of the if (first) clause was there was the setup() code was taking too long, and I wanted to move it into the loop(), thinking that perhaps the WTD did not fire there. I was, wrong, of course, so it could go back into setup() again. However, the code you pasted is not the same as the code I was running. In your code, the part that I have #if'd out is active; in mine, it is disabled, and yet its mere presence causes it to not compile the same.

igrr commented 8 years ago

So it doesn't compile or doesn't run? If it doesn't compile, please post verbose compiler output (enable it in Arduino > Preferences). If it compiles but the sketch does not run, please add Serial.setDebugOutput(true); to setup() and post the Serial output, as advised above. Thanks.

skandragon commented 8 years ago

It doesn't run. Adding setDebugOutput(true) doesn't change the behavior.

Output:

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

wdt reset
load 0x4010f000, len 1464, room 16 
tail 8
chksum 0x57
csum 0x57
~ld

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

wdt reset
load 0x4010f000, len 1464, room 16 
tail 8
chksum 0x57
csum 0x57
~ld

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

wdt reset
load 0x4010f000, len 1464, room 16 
tail 8
chksum 0x57
csum 0x57
~ld

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

wdt reset
load 0x4010f000, len 1464, room 16 
tail 8
chksum 0x57
csum 0x57
~ld
skandragon commented 8 years ago

Note once again that the code Links2004 posted is NOT equivalent to the code that I posted.

Links2004 commented 8 years ago

the code you use has USE_HUMIDITY 0 and this code has the wdt reset? so basic its run this:

#include "Arduino.h"

void setup() 
{
  Serial.begin(115200);
  Serial.println("\n\nOrientation Sensor Raw Data Test\n");
}

bool first = true;
void loop() 
{
  Serial.println("Loop.");

  if (first) {
    first = false;
    delay(1000);
  }

  delay(1000);
}

and the WDT fires?

skandragon commented 8 years ago

@Links2004, the code as you posted it just now does work as expected.

skandragon commented 8 years ago

Do you agree that your code and the effective code from the #if 0'd out lines should be identical?

skandragon commented 8 years ago

It's actually inconsistent what works and what does not. This is all using a bench power supply with an upper limit set to 1A. I've bumped the limit to 2A just in case I can't do math.

Wether or not the code works seems to be dependent on something apparently random. If I flash the above code it works, and then the original works as well. If I flash a longer version (which has the same concept as the shorter version, but adds a gyroscopic sensor and starts to initialize WiFi, all #if'd out) -- it will not. And then, the shorter #if'd out part I originally posted will not work either.

I think I need a young priest and an old priest.

Links2004 commented 8 years ago

yes the precompiler will delete all the code inside the #if USE_HUMIDITY when USE_HUMIDITY is set as 0 and the result will be the second code that i posted.

Links2004 commented 8 years ago

what version do you use? how do you flash? this sounds like very old problem from pre board manager times.

skandragon commented 8 years ago

According to the board manager, I have "1.6.4-673-g8cd3697" installed. I've tried flashing both with the included esptool binary and the Python version. Prior to what appears to be a very recent update, the built-in esptool would not consistently flash, but the python version would. This version seems stable.

I will try removing it, and flashing it again, just to see if that is an issue.

skandragon commented 8 years ago

Wiping the ~/Library/Arduino15 directory entirely and reinstalling still causes the same issue. The version installed matches from my previous comment.

skandragon commented 8 years ago

After tinkering for a bit, the code has morphed into what's shown below. Note that the effective code is still very similar, and yet does not run as expected. I'll paste both the current code and my "effective code" for comparison.

This will not work. It loops with WTD resets with the message:

wdt reset
load 0x40100000, len 28780, room 16 
tail 12
chksum 0x35
ho 0 tail 12 room 4
load 0x3ffe8000, len 1668, room 12 
tail 8
chksum 0xb1
load 0x3ffe8690, len 2124, room 0 
tail 12
chksum 0xe0
csum 0xe0
#include "Arduino.h"

#define USE_WIFI 0
#define USE_HUMIDITY 0
#define USE_GYRO 0

#if USE_GYRO || USE_HUMIDITY
#include <Wire.h>
#include <Adafruit_Sensor.h>
#endif

#if USE_GYRO
#include <Adafruit_BNO055.h>
#endif

#if USE_WIFI
#include <SPI.h>
#include <WiFi.h>
#endif

#define BNO055_SAMPLERATE_DELAY_MS (100)

#if USE_GYRO
#include <utility/imumaths.h>
Adafruit_BNO055 bno = Adafruit_BNO055(12345);
#endif

#if USE_HUMIDITY
#include <SparkFunHTU21D.h>
HTU21D myHumidity;
#endif

#if USE_WIFI
char ssid[] = "TechShop WiFi"; 
char pass[] = "xxxxxxxxx";
int status = WL_IDLE_STATUS;
#endif

void setup() 
{
  Serial.setDebugOutput(true);
  Serial.begin(115200);
  Serial.println("\n\nOrientation Sensor Raw Data Test\n");

  pinMode(13, OUTPUT);
  digitalWrite(13, LOW);
  delay(10);
  digitalWrite(13, HIGH);

#if USE_GYRO || USE_HUMIDITY
  Wire.setClock(200000UL);
  Wire.begin(4, 5);
  delay(100);
#endif

#if USE_GYRO
  /* Initialise the BNO055 sensor */
  while (!bno.begin(Adafruit_BNO055::OPERATION_MODE_NDOF, false)) {
    /* There was a problem detecting the BNO055 ... check your connections */
    Serial.println("Ooops, no BNO055 detected ... Check your wiring or I2C ADDR!");
    yield();
  }
#endif

#if USE_HUMIDITY
  myHumidity.begin();
#endif

  delay(1000);

#if USE_GYRO
  /* Display the current temperature */
  int8_t temp = bno.getTemp();
  Serial.print("Current Temperature: ");
  Serial.print(temp);
  Serial.println(" C");
  Serial.println("");

  bno.setExtCrystalUse(true);
#endif

#if USE_WIFI
  Serial.println("Configuring WiFi");
  while (status != WL_CONNECTED) { 
    Serial.print("Attempting to connect to WPA SSID: ");
    Serial.println(ssid);
    status = WiFi.begin(ssid, pass);
    delay(10000);
  }

  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);
#endif
}

#if USE_GYRO
void print_plus(float x) {
  if (x >= 0.0)
    Serial.print("+");
}
#endif

void loop() 
{
  Serial.println("Loop.");

#if USE_GYRO
  // Possible vector values can be:
  // - VECTOR_ACCELEROMETER - m/s^2
  // - VECTOR_MAGNETOMETER  - uT
  // - VECTOR_GYROSCOPE     - rad/s
  // - VECTOR_EULER         - degrees
  // - VECTOR_LINEARACCEL   - m/s^2
  // - VECTOR_GRAVITY       - m/s^2

  imu::Vector<3> euler = bno.getVector(Adafruit_BNO055::VECTOR_EULER);
  Serial.print("X: ");
  print_plus(euler.x());
  Serial.print(euler.x());
  Serial.print(" Y: ");
  print_plus(euler.y());
  Serial.print(euler.y());
  Serial.print(" Z: ");
  print_plus(euler.z());
  Serial.print(euler.z());
  Serial.print(" - ");

  euler = bno.getVector(Adafruit_BNO055::VECTOR_LINEARACCEL);
  Serial.print("X: ");
  print_plus(euler.x());
  Serial.print(euler.x());
  Serial.print(" Y: ");
  print_plus(euler.y());
  Serial.print(euler.y());
  Serial.print(" Z: ");
  print_plus(euler.z());
  Serial.print(euler.z());
  Serial.print(" Mag:" );
  Serial.print(sqrt(euler.x() * euler.x() + euler.y() * euler.y() + euler.z() * euler.z()));
#endif

#if USE_HUMIDITY
  float temp = myHumidity.readTemperature();
  float humd = myHumidity.readHumidity();

  Serial.print(" Temperature:");
  Serial.print(temp, 1);
  Serial.print("C");
  Serial.print(" Humidity:");
  Serial.print(humd, 1);
  Serial.print("%");
  Serial.println();
#endif

  delay(1000);
}

Effective code (which runs):

#include "Arduino.h"

void setup() 
{
  Serial.setDebugOutput(true);
  Serial.begin(115200);
  Serial.println("\n\nOrientation Sensor Raw Data Test\n");

  pinMode(13, OUTPUT);
  digitalWrite(13, LOW);
  delay(10);
  digitalWrite(13, HIGH);

  delay(1000);
}

void loop() 
{
  Serial.println("Loop.");

  delay(1000);
}
skandragon commented 8 years ago

btw, the staging directory has these:

esp8266-1.6.4-673-g8cd3697.zip
esptool-0.4.4-5-g744c44d-osx.tar.gz
osx-xtensa-lx106-elf-gb404fb9-2.tar.gz
Links2004 commented 8 years ago

the version look good. can you add:

    Serial.println();
    Serial.println();
    Serial.println();

    for(uint8_t t = 4; t > 0; t--) {
        Serial.print(F("[SETUP] BOOT WAIT "));
        Serial.print(t);
        Serial.println(F("..."));
        Serial.flush();
        delay(1000);
    }
    Serial.print("[SETUP] Reset Info: ");
    Serial.println(ESP.getResetInfo());
    Serial.flush();
    delay(1000);

to the top of the setup function. *after Serial.begin(115200); Serial.setDebugOutput(true); you serial messages don't show the Orientation Sensor Raw Data Test, I want to be sure that the problem is not before it. the ESP.getResetInfo() may also give some hints. some note the Serial.setDebugOutput(true); needs to be called after the Serial.begin or it will not work.

skandragon commented 8 years ago

There is no getResetInfo() on the ESP class.

skandragon commented 8 years ago

Regardless, the output is pretty much identical, using ESP.getBootMode() call which does exist. Nothing is printed from within the setup() method at all.

Links2004 commented 8 years ago

ok its not in the release build the 1.6.4-673-g8cd3697 is from May 22, 2015. can you use the latest git version? there are many changes since may.

skandragon commented 8 years ago

Can you give me a rundown or pointer on how to install the latest? I'm more than happy to track it from git, so long as my regular Arduino code continues working!

hamishcunningham commented 8 years ago

hi Michael

To install the latest IDE:

git clone https://github.com/esp8266/Arduino.git cd Arduino/build ant dist

Then unpack the built version as instructed by the ant script (a .xz in build/linux on my platform, IIRR).

This will include the "arduino" script to run the IDE.

It may also a good idea to start with a fresh set of preferences etc., e.g.:

cd mv .arduino15 .arduino15.sav

HTH,

Hamish Cunningham Professor of Computer Science, University of Sheffield, UK +44 7920 765 455 https://twitter.com/@HCunningham hamish@gate.ac.uk https://pi.gate.ac.uk https://hamish.gate.ac.uk https://gate.ac.uk

Links2004 commented 8 years ago

after build run build/build_board_manager_package.sh script, it will build the board manager package and start a local python web server`. more info last post from @igrr on #440

hamishcunningham commented 8 years ago

@Links2004 cool, tnx (though I guess you don't actually save any time or space this way?) h

Links2004 commented 8 years ago

i never build the package :) i directly use the git files with symlinks in my arduino dir. for developing this is the easy-es way i can pull and have the newest version, and also can test my changes very easy before push.

hcunningham commented 8 years ago

ah, sneaky! :-)

skandragon commented 8 years ago

I'm happy to make those symlinks as well. I am a coder; this hardware stuff is for fun :) Running from my live build root does not frighten me at all.

skandragon commented 8 years ago

I followed those steps and pointed at localhost:8000, but now I get:

Arduino: 1.6.5 (Mac OS X), Board: "Adafruit HUZZAH ESP8266, 80 MHz, 115200"
Third-party platform.txt does not define compiler.path. Please report this to the third-party hardware maintainer.
Error while compiling: missing 'recipe.cpp.o.pattern' configuration parameter

Let's go the symlink route if it's not too difficult.

skandragon commented 8 years ago

I'm just running the Arduino.app from the build directory, and it does work, including when I enable the i2c portion of the code. I've not tried the WiFi parts yet, but considering it works and this issue is resolved enough that I can continue the i2c issue in #526, I'll close this one with one final comment.

For the good of all those others wanting to use the ESP8266, please release a new package for the board manager! It's night and day in terms of outcome.