Skip to content

Instantly share code, notes, and snippets.

@gomako
Created May 15, 2019 15:07
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save gomako/4bcd3731af11896e7985f0d88a0af0a5 to your computer and use it in GitHub Desktop.
Save gomako/4bcd3731af11896e7985f0d88a0af0a5 to your computer and use it in GitHub Desktop.
// Wifi Credentials
const WIFI_NAME = "YOURSSID";
const WIFI_PASS = "YOURPASS";
// Your location latitude and longitude
const lat = 'YOURLAT';
const lon = 'YOURLON';
// Required libs
const http = require("http");
const np = require("neopixel");
// Variable to store the time
let now;
// Variable to store ISS pass info
let iss;
// Variable to set the interval so we can clear it
let intervalId;
// Setup Wifi Shim according to instructions found here:
// https://www.espruino.com/ESP8266
digitalWrite(B9, 1); // enable on Pico Shim V2
Serial2.setup(115200, { rx: A3, tx: A2 });
// Turn LED off
np.write(B5, [0,0,0]);
/**
* Connect to WIFI
*/
var wifi = require("ESP8266WiFi_0v25").connect(Serial2, function (err) {
if (err) throw err;
console.log("Connecting to WiFi");
wifi.connect(WIFI_NAME, WIFI_PASS, err => {
if (err) throw err;
console.log("Connected");
// Once we have connected, set the UTC time
setTime();
});
});
/**
* Set the UTC time to sync with the ISS API
*/
function setTime() {
console.log("Setting Time");
http.get('http://worldclockapi.com/api/json/utc/now', res => {
let contents = '';
res.on("data", data => contents += data);
res.on("close", () => {
let timeJson = JSON.parse(contents);
now = new Date(timeJson.currentDateTime);
// Now we have set the time, let's get the ISS pass data
fetchData();
});
}).on("error", e => console.log("Error getting time: ", e));
}
/**
* Fetch the ISS Pass Data
*/
function fetchData() {
console.log("Fetching Data");
let url = `http://api.open-notify.org/iss-pass.json?lat=${lat}&lon=${lon}`;
http.get(url, res => {
let contents = '';
res.on("data", data => contents += data);
res.on("close", () => {
try {
iss = JSON.parse(contents);
// If we didn't have an error, all is good
if (iss.hasOwnProperty('message') && iss.message == 'success') {
// Calculate the interval between request time and next rise
let interval = (iss.response[0].risetime * 1000) - now.getTime();
let duration = iss.response[0].duration;
showDebug(iss);
// Set the timeout function (multiply the duration by 1k to convert to ms)
setTimeout(flashLED, interval, duration * 1000);
} else {
// Something went wrong, we'll try again in 30 seconds
setTimeout(fetchData, 30 * 1000);
}
} catch (e) {
// There was an error parsing the data, let's try again in 30 seconds
console.log("ERROR parsing ISS json", e);
setTimeout(fetchData, 30 * 1000);
}
});
}).on("error", (e) => {
// There was an error fetching the data, let's try again in 30 seconds
console.log("ERROR fetching data: ", e);
setTimeout(fetchData, 30 * 1000);
});
}
/**
* Flash the LED to notify us of the
*/
function flashLED(duration) {
console.log('ISS Overhead!');
let state = true;
intervalId = setInterval(() => {
if(state) np.write(B5, [100, 10, 10])
else np.write(B5, [10, 30, 100])
state = !state
}, 1000);
setTimeout(() => {
// Clear the interval
clearInterval(intervalId);
// Turn off LED
np.write(B5, [0,0,0]);
// Fetch more data!
setTime();
}, duration);
}
/**
* Show debug information in terminal
*/
function showDebug() {
console.log("Current time: ", now);
console.log("Next rise: ", new Date(iss.response[0].risetime * 1000));
console.log("Pass duration: ", iss.response[0].duration + " seconds. Or " + iss.response[0].duration / 60 + " minutes. ");
}
@wooghee
Copy link

wooghee commented Jun 13, 2019

thank you so much for helping me!
with some help of the ArduinoJSON examples i got it to work (edit: no it does not, it seems i just programmed a converter, to deserialize a char, not actually pulling it from the API). even better I figured out that i do not need to connect to the worldclock API since the ISS one does already provide an accurate enough time (edit: thats still something I got right I think)

working code: see next comment

@gomako
Copy link
Author

gomako commented Jun 13, 2019

Excellent, glad to hear it's working!

@wooghee
Copy link

wooghee commented Jun 13, 2019

fixed some stuff; now it really works:


#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <ArduinoJson.h>


// Wifi Credentials
const char* ssid = "ssid";
const char* password = "password";

//API server                                                 lat           lon      
const String iss = "http://api.open-notify.org/iss-pass.json?lat=47.0532452&lon=8.356456&alt=";

//number of passes requested
int p = 2;
int i = 2;
int alt = 100;

//long nowtime;
long interval;
int duration;

void setup() 
{
  Serial.begin(115200);
  while (!Serial) continue;
  WiFi.begin(ssid, password);
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, HIGH);    // turn the LED off by making the voltage LOW
  
  while (WiFi.status() != WL_CONNECTED) 
  {
    delay(1000);
    Serial.println("Connecting...");
    digitalWrite(LED_BUILTIN, LOW);    // turn the LED on
    delay(1000);                        
    digitalWrite(LED_BUILTIN, HIGH);   // turn the LED off by making the voltage LOW                       // 
  }
  
}

void loop() 
{
  if (WiFi.status() == WL_CONNECTED)
  {
    HTTPClient http;                                //Object of class HTTPClient
    http.begin(iss+alt);
    int httpCode = http.GET();
    Serial.print("\n\n\n\n\n\n\n================================================================================");
    Serial.print("\nconnected to:      ");
    Serial.println(iss+alt);
    if (httpCode > 0) 
    {
      const size_t capacity = JSON_ARRAY_SIZE(2) + 2*JSON_OBJECT_SIZE(2) + JSON_OBJECT_SIZE(3) + JSON_OBJECT_SIZE(5) + 200;
      DynamicJsonBuffer jsonBuffer(capacity);

      String json = http.getString();
      
      JsonObject& root = jsonBuffer.parseObject(json);

      // test if parsing succeeded
      if (!root.success()) 
      {
        Serial.println("parseObject() failed");
        return;
      }

      String message = root["message"];                                           // "success"

      JsonObject& request = root["request"];
      int request_altitude = request["altitude"];                                 // 437
      long request_datetime = request["datetime"];                         // 1560370729
      float request_latitude = request["latitude"];                             // 47.0243543
      float request_longitude = request["longitude"];                      // 8.3034321
      int request_passes = request["passes"];                                   // 5
      
      int response_0_duration = root["response"][0]["duration"];           // 491
      long response_0_risetime = root["response"][0]["risetime"];          // 1560416345

      //save to global variables
      duration = response_0_duration;
      interval = ((response_0_risetime)-request_datetime);

      int response_1_duration = root["response"][1]["duration"];           // 639
      long response_1_risetime = root["response"][1]["risetime"];          // 1560422032
      
      Serial.print("\nstatus:            ");
      Serial.println(message);

      Serial.print("\nrequest time:      ");
      Serial.print(request_datetime);
      Serial.println(" unix timestamp");

      Serial.print("\nrequested passes:  ");
      Serial.println(request_passes);
      
       
      Serial.print("\nnext risetime:     ");
      Serial.print(response_0_risetime);
      Serial.println(" unix timestamp");

      Serial.print("\nnext flyover in:   ");
      Serial.print(interval);
      Serial.println(" seconds");

      Serial.print("\nduration:          ");
      Serial.print(duration);
      Serial.println(" seconds");

      json = "";                       // delete stored data
    }
    http.end(); //Close connection
  }

  while(interval<=duration) // check if ISS will come up within a the duration of next pass or is already up at this very moment
  {
    digitalWrite(LED_BUILTIN, LOW);    // turn the LED on
    delay(250);                        
    digitalWrite(LED_BUILTIN, HIGH);   // turn the LED off by making the voltage LOW
    delay(250);                        
    digitalWrite(LED_BUILTIN, LOW);    // turn the LED on
    delay(250);                        
    digitalWrite(LED_BUILTIN, HIGH);   // turn the LED off by making the voltage LOW
    delay(250);                              // that makes total 1 second delay
    interval--;
    if(interval==0)
    {
      interval=10000;
    }
  }
  if(interval>=duration)                    // if not, generate new request
  {
   alt++;
   if(alt==10000){  // increase altitude up to 10000
    alt=100;        // reset altitude
   }
  }
  //run setup again if connection is lost
  if (WiFi.status() != WL_CONNECTED) 
  {
    setup();
  }
  delay(60000);                        // wait 1 minute until next request.
}


Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment