ISS Tracker- Debug Now?

The program tracks the ISS using internet time and a JSON thing to get the real-time location of the station. There are two problems.

I added something that messed up the time procedure of the ESP8266 chip and added ’ ESP.wdtFeed();’ to buffer in that time procedure. Now serial output works. According to serial output, the whole program works. We get the session start time, and then it counts down the seconds until flyover. When it gets to zero, it outputs the overhead stuff.

Problem 1: The Neopixel doesn’t light. Two LEDs were lit, and I reconnected all three wires to be sure it wasn’t just odd powerup behavior. They stayed lit, so I was optimistic that it was working, but there was no change when flyover happened.

Problem 2: It’s wrong. Coordinates are correct, but the flyover is off by hours.

I haven’t read anything about debugging yet. I think it’s time to learn it. I have too many early-stage projects going, so I put them all on hold to focus on this one program.

This is the.ini:

[env:esp12e]

platform = espressif8266

board = esp12e

framework = arduino

build_flags = -D SERIAL_DEBUG

monitor_filters = esp8266_exception_decoder

build_type = debug

monitor_speed = 9600

lib_deps = 

    ESP8266WiFi

    ArduinoJson

    ESP8266HTTPClient

    adafruit/Adafruit NeoPixel@^1.6.0

    Wire

    SPI

    https://github.com/adafruit/Adafruit-GFX-Library.git

    https://github.com/adafruit/Adafruit_SSD1306.git

    https://github.com/adafruit/Adafruit_BusIO.git

This is the code:

/*********
pollux labs, 2020
*********/
#include <Arduino.h>
#include <Wire.h>
#include "ESP8266WiFi.h"
#include "ArduinoJson.h"
#include "ESP8266HTTPClient.h"
#include "Adafruit_NeoPixel.h"
#include "Adafruit_GFX.h"
#include "Fonts/FreeSansBold9pt7b.h"
#include "Fonts/Org_01.h"
#include "Adafruit_SSD1306.h"

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

/*** Your coordinates ***/
const float latitude = 37.25;
const float longitude = 121.9;
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, 3, 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))
  {
    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();
    }
  }
  ESP.wdtFeed();
}

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

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

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

  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();
  }
  

  ESP.wdtFeed();
}

How many hours? Is it the same as the number of hours behind UTC aka GMT that Los Ageles is? 8 hours by any chance?

I had a look at the details of the ISS overhead API call that you are using, it says:

The international space station (ISS) is an orbital outpost circling high above out heads. Sometimes it’s overhead, but when? It depends on your location. Given a location on Earth (latitude, longitude, and altitude) this API will compute the next n number of times that the ISS will be overhead.

Overhead is defined as 10° in elevation for the observer. The times are computed in UTC and the length of time that the ISS is above 10° is in seconds.

(My emphasis)

You probably need to be using GMT for your internet time call, not Los Angeles. At the moment, Europe/London is running GMT but that will change to GMT+1 in March.

Does the world time api let you ask for the time in UTC or do you have to extract the offset, and add/subtract from unix time? (“utc_offset”:“-08:00” in the JSON.)

Cheers,
Norm.

I investigated further. Within the JSON returned from the World Time API, is a field:

"raw_offset":-28800

Which is the number of seconds away from UTC your current time is. The value above is for your location. You are 8 hours behind UTC. 8 hours is 28,800 seconds.

You are using the Unix Time extracted from the JSON, you would need to add 28,800 to the Unix Time to get UTC, then check if you are close to the ISS time overhead returned from the other API call.

Something like this in your getCurrentTime() function:

currentTime = doc["unixtime"];
rawOffset = doc["raw_offset"];

// Add -ve offsets, subtract +ve offsets
// to get UTC for ISS.
currentTime += (-rawOffset);

Cheers,
Norm.

2 Likes