ISS Alert- should this work?

It isn’t getting online, so nothing else is happening. PIO says it’s uploaded. I know the Neopixel works. I’ll keep trying to get online with the 8266 a little longer before going to the 32.

It does a JSON request, something I’m excited to learn.

But it’s crunch time. When I get online, I need this to work for Christmas presents.
Please give it the sanity check/sniff test.

Here’s the link to the project:

3-D printed cubes light up when the ISS is overhead.

Code:

/*********
pollux labs, 2020
*********/
#include <Arduino.h>
#include <Wire.h>
#include "ESP8266WiFi.h"
#include "ArduinoJson.h"
#include "ESP8266HTTPClient.h"
#include "Adafruit_NeoPixel.h"

/*** Your WiFi Credentials ***/
const char *ssid = "Fishing24";
const char *password = "Fishing$602";

/*** Your coordinates ***/
const float latitude = 37.25;
const float longitude = 121.5;
const float altitude = 260.00;

//Variables for times and duration
long riseTime = 0;
long currentTime = 0;
long duration = 0;
long timeUntilFlyover = 0; //difference

Adafruit_NeoPixel pixels = Adafruit_NeoPixel(12, 2, NEO_GRB + NEO_KHZ800);

void success()
{
  for (int i = 0; i < 12; i++)
  {
    pixels.setPixelColor(i, pixels.Color(0, 255, 0));
    pixels.show();
  }
  delay(100);

  for (int i = 11; i >= 0; i--)
  {
    pixels.setPixelColor(i, LOW);
    pixels.show();
  }
}

void fail()
{
  for (int i = 0; i < 12; i++)
  {
    pixels.setPixelColor(i, pixels.Color(255, 0, 0));
    pixels.show();
    delay(100);
  }

  for (int i = 11; i >= 0; i--)
  {
    pixels.setPixelColor(i, LOW);
    pixels.show();
    delay(100);
  }
}

void getCurrentTime()
{

  HTTPClient http;
  http.begin("http://worldtimeapi.org/api/timezone/america/los_angeles/"); //URL for getting the current time

  int httpCode = http.GET();

  if (httpCode == 200)
  { //Check for the returning code

    success();

    String payload = http.getString();

    const size_t capacity = JSON_OBJECT_SIZE(15) + 550;
    DynamicJsonDocument doc(capacity);
    DeserializationError error = deserializeJson(doc, payload);
    http.end();

    if (error)
    {
      Serial.print(F("deserializeJson() failed(current time): "));
      Serial.println(error.c_str());
      return;
    }
    currentTime = doc["unixtime"]; //save current time
    Serial.print("current time= ");
    Serial.println(currentTime);
  }
  else
  {
    Serial.println("Error on HTTP request");
    fail();
  }
}

void apiCall()
{

  if ((WiFi.status() == WL_CONNECTED))
  {
    digitalWrite(LED_BUILTIN, HIGH);

    getCurrentTime(); //call function for getting the current time

    HTTPClient http;

    http.begin("http://api.open-notify.org/iss-pass.json?lat=" + String(latitude) + "&lon=" + String(longitude) + "&alt=" + String(altitude) + "&n=5"); //URL for API call

    int httpCode = http.GET();

    if (httpCode == 200)
    {

      success();

      String payload = http.getString(); //save response

      const size_t capacity = JSON_ARRAY_SIZE(5) + 5 * JSON_OBJECT_SIZE(2) + JSON_OBJECT_SIZE(3) + JSON_OBJECT_SIZE(5) + 190;
      DynamicJsonDocument doc(capacity);
      DeserializationError error = deserializeJson(doc, payload);

      http.end();

      if (error)
      {
        Serial.print(F("deserializeJson() failed: "));
        Serial.println(error.c_str());
        return;
      }

      JsonArray response = doc["response"];
      duration = response[0]["duration"]; // save duration of the next flyover
      riseTime = response[0]["risetime"]; // save start time of the next flyover

      if (riseTime < currentTime)
      { //If ISS has already passed, take the next flyover
        duration = response[1]["duration"];
        riseTime = response[1]["risetime"];
      }

      Serial.print("Risetime [0]= ");
      Serial.println(riseTime);

      //compute time until rise
      timeUntilFlyover = riseTime - currentTime;
      Serial.print("Time until flyover: ");
      Serial.println(timeUntilFlyover);
    }
    else
    {
      Serial.println("Error on HTTP request");
      fail();
    }
  }
}

void setup()
{
  Serial.begin(9600);
  pixels.begin();
  pixels.setBrightness(100);

  pinMode(LED_BUILTIN, OUTPUT);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    Serial.print(".");
  }
  WiFi.begin(ssid, password);
  while (WiFi.status() == WL_CONNECTED)
  {
    digitalWrite(LED_BUILTIN, HIGH);
  }
  delay(1000);
}

void loop()
{
  apiCall(); //API call for the next ISS flyover

  //shut down the NeoPixel until next ISS flyover
  for (int i = 0; i < 12; i++)
  {
    pixels.setPixelColor(i, LOW);
    pixels.show();
  }

  while (timeUntilFlyover > 0)
  { // while the ISS isn't overhead

    delay(1000);
    Serial.println(timeUntilFlyover);

    timeUntilFlyover--;
  }

  //when ISS rises  above the horizon
  Serial.println("ISS overhead!");
  int maxDuration = duration; //save max value of the flyover duration
  Serial.print("max duration = ");
  Serial.println(duration);

  for (duration; duration >= 0; duration--)
  {
    //map remaining flyover time on a color gradient
    int colorRed = map(duration, 0, maxDuration, 200, 0);
    int colorBlue = map(duration, 0, maxDuration, 0, 200);

    //show the current color on all LEDs
    for (int i = 0; i < 12; i++)
    {
      pixels.setPixelColor(i, pixels.Color(colorRed, 0, colorBlue));
      pixels.show();
    }
    delay(1000);
  }

  for (int i = 0; i < 12; i++)
  {
    pixels.setPixelColor(i, LOW);
    pixels.show();
  }
}

That code gets me online with an ESP32, but not with an ESP8266.

I can’t imagine why.
Can you?

Output:

> Executing task in folder ISS_Aler_WeMos: C:\Users\joema\.platformio\penv\Scripts\pio.exe device monitor <

--- Available filters and text transformations: colorize, debug, default, direct, esp8266_exception_decoder, hexlify, log2file, nocontrol, printable, send_on_enter, time
--- More details at http://bit.ly/pio-monitor-filters
--- Miniterm on COM8  9600,8,N,1 ---
--- Quit: Ctrl+C | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H ---
�Hp␎�CGS[�␆xn�␒�.......�␄�|�`,l$�4b8��....�EO,�`�l$�4b:I��.......ISS overhead!
max duration = 0

--------------- CUT HERE FOR EXCEPTION DECODER ---------------

Exception (0):
epc1=0x4000dce5 epc2=0x00000000 epc3=0x00000000 excvaddr=0x00000000 depc=0x00000000

>>>stack>>>

ctx: cont
sp: 3ffffdd0 end: 3fffffc0 offset: 0190
3fffff60:  3ffee508 3ffee4c4 3ffee508 40205280  
3fffff70:  3ffee4a8 3ffee4c4 3ffee4a8 40202132  
3fffff80:  3ffee508 3ffe84e8 3ffee4d0 402011e6  
3fffff90:  feefeffe feefeffe feefeffe 3ffee584  
3fffffa0:  3fffdad0 00000000 3ffee544 40206550  
3fffffb0:  feefeffe feefeffe 3ffe8508 40100cbd  
<<<stack<<<

--------------- CUT HERE FOR EXCEPTION DECODER ---------------
H!�1�@H␂�.......ISS overhead!
max duration = 0

--------------- CUT HERE FOR EXCEPTION DECODER ---------------

Exception (0):
epc1=0x4000dce5 epc2=0x00000000 epc3=0x00000000 excvaddr=0x00000000 depc=0x00000000

>>>stack>>>

ctx: cont

Please format code using Markdown.

Also please add monitor_filters = esp8266_exception_decoder (docs) to the platformio.ini and re-run the firmware. What does it output now?

After adding that code, including ‘(docs)’, I get nothing:

I thought I formatted it. Sorry.

Executing task in folder ISS_Aler_WeMos: C:\Users\joema.platformio\penv\Scripts\pio.exe device monitor <

— Available filters and text transformations: colorize, debug, default, direct, esp8266_exception_decoder, hexlify, log2file, nocontrol, printable, send_on_enter, time
— More details at Redirecting...
Error: ‘esp8266_exception_decoder (docs)’
The terminal process “C:\Users\joema.platformio\penv\Scripts\pio.exe ‘device’, ‘monitor’” terminated with exit code: 1.

Terminal will be reused by tasks, press any key to close it.

The (docs) is not part of what’s going into the platformio.ini, that’s just me putting a link after it. That was supposed to be indicated by putting the code part into backticks so that it’s formatted as code and picked up as such by people.

monitor_filters = esp8266_exception_decoder 

is right.

There’s a lot of yellow in the compiler log.

Fixed .ini.
New output:

> Executing task in folder ISS_Aler_WeMos: C:\Users\joema\.platformio\penv\Scripts\pio.exe device monitor <

--- Available filters and text transformations: colorize, debug, default, direct, esp8266_exception_decoder, hexlify, log2file, nocontrol, printable, send_on_enter, time
--- More details at http://bit.ly/pio-monitor-filters
Error: 'esp8266_exception_decoder (docs)'
The terminal process "C:\Users\joema\.platformio\penv\Scripts\pio.exe 'device', 'monitor'" terminated with exit code: 1.

Terminal will be reused by tasks, press any key to close it.

> Executing task in folder ISS_Aler_WeMos: C:\Users\joema\.platformio\penv\Scripts\pio.exe device monitor <

--- Available filters and text transformations: colorize, debug, default, direct, esp8266_exception_decoder, hexlify, log2file, nocontrol, printable, send_on_enter, time
--- More details at http://bit.ly/pio-monitor-filters

Please build project in debug configuration to get more details about an exception.
See https://docs.platformio.org/page/projectconf/build_configurations.html


--- Miniterm on COM8  9600,8,N,1 ---
--- Quit: Ctrl+C | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H ---
�dn�H�4d�l�:h��.......ISS overhead!
max duration = 0

--------------- CUT HERE FOR EXCEPTION DECODER ---------------

Exception (0):
epc1=0x4000dce5 epc2=0x00000000 epc3=0x00000000 excvaddr=0x00000000 depc=0x00000000

Illegal instruction

>>>stack>>>

ctx: cont
sp: 3ffffdd0 end: 3fffffc0 offset: 0190
3fffff60:  3ffee508 3ffee4c4 3ffee508 40205280
3fffff70:  3ffee4a8 3ffee4c4 3ffee4a8 40202132  
3fffff80:  3ffee508 3ffe84e8 3ffee4d0 402011e6  
3fffff90:  feefeffe feefeffe feefeffe 3ffee584  
3fffffa0:  3fffdad0 00000000 3ffee544 40206550  
3fffffb0:  feefeffe feefeffe 3ffe8508 40100cbd  
<<<stack<<<

0x40205280 in Print::println(long, int) at ??:?
0x40202132 in loop at ??:?
0x402011e6 in setup at ??:?
0x40206550 in loop_wrapper() at core_esp8266_main.cpp:?
0x40100cbd in cont_wrapper at ??:?


--------------- CUT HERE FOR EXCEPTION DECODER ---------------
H!�1�@H�.......ISS overhead!
max duration = 0

--------------- CUT HERE FOR EXCEPTION DECODER ---------------

Exception (0):
epc1=0x4000dce5 epc2=0x00000000 epc3=0x00000000 excvaddr=0x00000000 depc=0x00000000

Illegal instruction

>>>stack>>>

ctx: cont
sp: 3ffffdd0 end: 3fffffc0 offset: 0190
3fffff60:  3ffee508 3ffee4c4 3ffee508 40205280  
3fffff70:  3ffee4a8 3ffee4c4 3ffee4a8 40202132  
3fffff80:  3ffee508 3ffe84e8 3ffee4d0 402011e6  
3fffff90:  feefeffe feefeffe feefeffe 3ffee584  
3fffffa0:  3fffdad0 00000000 3ffee544 40206550  
3fffffb0:  feefeffe feefeffe 3ffe8508 40100cbd  
<<<stack<<<

0x40205280 in Print::println(long, int) at ??:?
0x40202132 in loop at ??:?
0x402011e6 in setup at ??:?
0x40206550 in loop_wrapper() at core_esp8266_main.cpp:?
0x40100cbd in cont_wrapper at ??:?


--------------- CUT HERE FOR EXCEPTION DECODER ---------------
)�

It’s not just you, I get the exact same error when using that firmware on my ESP8266. I’ll see why.

After adding building the project with

[env:esp8266]
platform = espressif8266
board = nodemcuv2
framework = arduino
lib_deps = 
    adafruit/Adafruit NeoPixel @ ^1.7.0
monitor_speed = 74880
monitor_filters = esp8266_exception_decoder
build_type = debug

I now get the full stack trace of

0x40207ff0 in Print::println(long, int) at C:\Users\Maxi\.platformio\packages\framework-arduinoespressif8266\cores\esp8266/Print.cpp:228
0x40203f0b in loop at src/main.cpp:209
0x4020a0da in __delay at C:\Users\Maxi\.platformio\packages\framework-arduinoespressif8266\cores\esp8266/core_esp8266_wiring.cpp:54
0x4020993b in loop_wrapper() at C:\Users\Maxi\.platformio\packages\framework-arduinoespressif8266\cores\esp8266/core_esp8266_main.cpp:197
0x40100d45 in cont_wrapper at C:\Users\Maxi\.platformio\packages\framework-arduinoespressif8266\cores\esp8266/cont.S:81

Yeah absolutely this weird double connect destroys the firmware.

When you replace setup() with

void setup()
{
  Serial.begin(74880);
  pixels.begin();
  pixels.setBrightness(100);

  pinMode(LED_BUILTIN, OUTPUT);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    Serial.print(".");
  }
  /*WiFi.begin(ssid, password);
  while (WiFi.status() == WL_CONNECTED)
  {
    digitalWrite(LED_BUILTIN, HIGH);
  }*/
  delay(1000);
}

the firmware doesn’t crash anymore. It screws up the logic in loop() and doesn’t get the time and duration data and somehow… crashes.

After that the output is

.current time= 1605738793
Risetime [0]= 1605774599
Time until flyover: 35806
35806
35805

(note: I’ve also changed the baud to 74880 so that there’s less serial garbage, which comes from the ESP8266’s bootloader at 74880 baud)

Ahem. This double conect wasn’t in the original sketch. When I read it from the source article you’ve posted I read setup() as

void setup() {

  pixels.begin();
  pixels.setBrightness(100);

  pinMode (2, OUTPUT); //LED Pin (at ESP8266: D4)

  Serial.begin(115200);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.println("Connecting...");
  }
  success();
  delay(1000);
  Serial.println("Hello, world!");
}

you’ve added this double connect yourself there?

1 Like

I’m sorry, that’s artifact. I failed to correctly paste a connect code with a more reliable one that’s almost identical. Imagine there’s only one logon instruction.

Or no- the second while lights the LED to indicate it’s connected.
That’s not a second connect.

The LED comes on and off when this output comes off.
Output looks the same to me:

--- Miniterm on COM8  9600,8,N,1 ---
--- Quit: Ctrl+C | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H ---
  �0�l��H|l$yO�3�.
--------------- CUT HERE FOR EXCEPTION DECODER ---------------

Soft WDT reset

>>>stack>>>

ctx: cont
sp: 3ffffde0 end: 3fffffc0 offset: 01a0
3fffff80:  3ffeec8c 40202984 00000002 40100311  
3fffff90:  3fffdad0 3ffee508 3ffee4d0 402011cb  
3fffffa0:  feefeffe 00000000 3ffee544 40206530  
3fffffb0:  feefeffe feefeffe 3ffe8508 40100cbd  
<<<stack<<<

0x40202984 in ESP8266WiFiSTAClass::status() at ??:?
0x40100311 in digitalWrite at ??:?
0x402011cb in setup at ??:?
0x40206530 in loop_wrapper() at core_esp8266_main.cpp:?
0x40100cbd in cont_wrapper at ??:?


--------------- CUT HERE FOR EXCEPTION DECODER ---------------

You’re tripping the watchdog by blocking code execution to long, somewhere. Can you show the full code you’re running now?

Also in order to see good exception decoding you have to do build_type = debug so that the ELF has all the debug symbol information in it.

monitor_filters = esp8266_exception_decoder
build_type = debug
1 Like

Full code is at the top.

I’ll write that into the .ini, see what happens.

This is what I get now:

Executing task in folder ISS_Aler_WeMos: C:\Users\joema.platformio\penv\Scripts\pio.exe device monitor <

— Available filters and text transformations: colorize, debug, default, direct, esp8266_exception_decoder, hexlify, log2file, nocontrol, printable, send_on_enter, time
— More details at Redirecting...

— Available ports:
— 1: COM1 ‘Communications Port (COM1)’
— 2: COM4 ‘Intel(R) Active Management Technology - SOL (COM4)’
— 3: COM8 ‘USB-SERIAL CH340 (COM8)’
— 4: COM21 ‘USB-SERIAL CH340 (COM21)’
— Enter port index or full name:

Termite serial monitor shows this:
.
--------------- CUT HERE FOR EXCEPTION DECODER ---------------

Soft WDT reset

stack>>>

ctx: cont
sp: 3ffffdb0 end: 3fffffc0 offset: 01a0
3fffff50: 00000001 00029715 3ffee624 00000000
3fffff60: 40235406 3ffee510 00000002 00000001
3fffff70: 402365ef 3ffee548 3ffe862c 40207a44
3fffff80: 3ffeeccc 40204f1c 00000002 40100358
3fffff90: 3fffdad0 00000002 3ffee510 402011cf
3fffffa0: feefeffe 00000000 3ffe8508 402097d8
3fffffb0: feefeffe feefeffe feefeffe 40100d45
<<<stack<<<

--------------- CUT HERE FOR EXCEPTION DECODER ---------------
H!ˆÈ[08]1’@H[02]Æ.
--------------- CUT HERE FOR EXCEPTION DECODER ---------------

Soft WDT reset

stack>>>

ctx: cont
sp: 3ffffde0 end: 3fffffc0 offset: 01a0
3fffff80: 3ffeeccc 00000001 00000002 40100358
3fffff90: 3fffdad0 00000002 3ffee510 402011c0
3fffffa0: feefeffe 00000000 3ffe8508 402097d8
3fffffb0: feefeffe feefeffe feefeffe 40100d45
<<<stack<<<

--------------- CUT HERE FOR EXCEPTION DECODER ---------------
H!ˆÈ[08]1§@H[02]Æ.
--------------- CUT HERE FOR EXCEPTION DECODER ---------------

Soft WDT reset

“WDT” = Watch Dog Timer. You have been reset by the watchdog. Somewhere in your code you need to “feed the dog” to prevent it doing a board reset.

You can read up on the feature of the ESP8266 at ESP8266: Watchdog functions - techtutorialsx but it seems you need to add:

ESP.wdtFeed()

into your loop(s) which take more than around 1 second. For example, this loop delays half a second each time, so after two iterations, you will probably get reset:

while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    Serial.print(".");
}

you would need to add the above code to “feed the dog” into the loop to prevent it taking too long if the WiFi is not quick enough.

Apparently, this board also needs to yield() regularly to allow the WiFi to work.

Sorry if this is too vague, I still haven’t done any ESP8266 work yet.

HTH

Cheers,
Norm.

1 Like

It looks like it jumps online and back off.

This is serial output when I add that line to three parts:

--------------- CUT HERE FOR EXCEPTION DECODER ---------------

Soft WDT reset

>>>stack>>>   

ctx: cont
sp: 3ffffdb0 end: 3fffffc0 offset: 01a0
3fffff50:  00000001 0015cfb5 3ffee6f0 00000000  
3fffff60:  402354fe 3ffee520 00000002 00000001  
3fffff70:  402366e7 3ffee55c 3ffe862c 40207a5c  
3fffff80:  3ffeed94 40204f24 00000002 401003cc  
3fffff90:  3fffdad0 00000002 3ffee520 402011cf  
3fffffa0:  feefeffe 00000000 3ffe8508 40209924  
3fffffb0:  feefeffe feefeffe feefeffe 40100db9  
<<<stack<<<

0x402354fe in wifi_get_opmode at ??:?
0x402366e7 in wifi_station_get_connect_status at ??:?
0x40207a5c in HardwareSerial::write(unsigned char const*, unsigned int) at C:\Users\joema\.platformio\packages\framework-arduinoespressif8266\cores\esp8266/HardwareSerial.h:165
0x40204f24 in ESP8266WiFiSTAClass::status() at C:\Users\joema\.platformio\packages\framework-arduinoespressif8266\libraries\ESP8266WiFi\src/ESP8266WiFiSTA.cpp:636
0x401003cc in digitalWrite at C:\Users\joema\.platformio\packages\framework-arduinoespressif8266\cores\esp8266/core_esp8266_wiring_digital.cpp:86
0x402011cf in setup at src/main.cpp:174 (discriminator 1)
0x40209924 in loop_wrapper() at C:\Users\joema\.platformio\packages\framework-arduinoespressif8266\cores\esp8266/core_esp8266_main.cpp:194
0x40100db9 in cont_wrapper at C:\Users\joema\.platformio\packages\framework-arduinoespressif8266\cores\esp8266/cont.S:81


--------------- CUT HERE FOR EXCEPTION DECODER ---------------

(Edited by moderator to fix stack trace formatting.)

You are still getting reset by the watch dog. Also, once connected to WiFi, you should yield() in loops and any places where the code is “doing a lot of work” otherwise, the WiFi processing will stop.

The ESP8266 has, I believe, a single CPU to handle your code, the WiFi etc while the ESP32 handles your code separately from the background stuff like the WiFi.

I’ve edited you post to fix the stack trce formatting. Please use three backticks to format code etc, thanks.

```
Like  this;
And  this
```

Cheers,
Norm.

This stacktrace shows you’re still stuck in setup() with that while loop of checking the status() and doing a digitalWrite.

  while (WiFi.status() == WL_CONNECTED)
  {
    digitalWrite(LED_BUILTIN, HIGH);
  }

this will block the entire time you’re connected to WiFi and does not do what you want! If you are connected you call digitalWrite a million times with HIGH while not feeding the watchdog and blocking further execution, but if you’re not connected, you break out of the while loop, while not setting the built-in LED to LOW to indicate the other state. You should implement this “turn LED on/off if connected to WiFi” check periodically in the loop() as one single if statement (or ternary expression) as I’ve explained in ESP32 WiFi Yes, ESP8266 No - #2 by maxgerhardt, or even much better, use the WiFi event hooks! See example and lib code.

2 Likes