Skip to content

Instantly share code, notes, and snippets.

@polluxlabs
Last active June 2, 2020 10:19
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save polluxlabs/ce34a6b39425c00540e882fa8cba721f to your computer and use it in GitHub Desktop.
Save polluxlabs/ce34a6b39425c00540e882fa8cba721f to your computer and use it in GitHub Desktop.
ISS Tracker with an ESP8266
/*********
pollux labs, 2020
https://polluxlabs.net
*********/
#include <Wire.h> //I2C
#include <Adafruit_GFX.h> //OLED-Display
#include <Adafruit_SSD1306.h> //OLED-Display
#include <ESP8266WiFi.h> //WiFI
#include <ArduinoJson.h> //JSON
#include <ESP8266HTTPClient.h> //API Call
//Convert Unixtime in readable format
#include <RTClib.h>
// WIFI Credentials
const char* ssid = "YOUR SSID";
const char* password = "YOUR WIFI PASSWORD";
//Your coordinates
const float latitude = 00.00;
const float longitude = 00.00;
const float myAltitude = 100.00;
// 'iss', 128x32px
const unsigned char iss [] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf8, 0x3f, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0f, 0xe0, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0f, 0xe0, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x1b, 0xfa, 0xaf, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xfa, 0xbf, 0xe0, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0e, 0xe0, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0e, 0xe0, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xfa, 0xbf, 0xe0, 0x40, 0x00, 0x01, 0x00, 0x00, 0x00,
0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x84, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x84, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x7c, 0x7c, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xa0, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0xa0, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x7c, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x84, 0x4c, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10,
0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x01, 0x84, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x04, 0x40, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00,
0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x0f, 0xfa, 0xbf, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0e, 0xe0, 0x20, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0e, 0xe0, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xfa, 0xbe, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0xfa, 0xaf, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0f, 0xe0, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x10, 0x0f, 0xe0, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf8, 0x3f, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
//Variables for time and duration
long riseTime = 0;
long currentTime = 0;
int duration = 0;
//OLED Display
#define SCREEN_WIDTH 128 // Breite des Displays in Pixeln
#define SCREEN_HEIGHT 32 // Höhe des Displays in Pixeln
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
void getCurrentTime() {
HTTPClient http;
http.begin("http://worldtimeapi.org/api/timezone/Europe/Berlin"); //URL zur Zeitabfrage
int httpCode = http.GET();
if (httpCode == 200) { //Check for the returning code
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"];
Serial.print("current time= ");
Serial.println(currentTime);
} else {
Serial.println("Error on HTTP request");
}
}
void apiCall() {
if ((WiFi.status() == WL_CONNECTED)) {
getCurrentTime(); //get the current time :)
HTTPClient http;
http.begin("http://api.open-notify.org/iss-pass.json?lat=" + String(latitude) + "&lon=" + String(longitude) + "&alt=" + String(myAltitude) + "&n=5"); //URL for API Call
int httpCode = http.GET();
Serial.println(httpCode);
if (httpCode == 200) {
String payload = http.getString();
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"]; //Duration of the next flyover
riseTime = response[0]["risetime"]; //Time when the ISS rises
if (riseTime < currentTime) { //If the last flyover is already over...take the next one.
duration = response[1]["duration"];
riseTime = response[1]["risetime"];
}
Serial.print("Risetime = ");
Serial.println(riseTime);
DateTime time = riseTime + 7200; //IMPORTANT: Adjust to your deviation from UTC
String flyoverDate = time.timestamp(DateTime::TIMESTAMP_DATE);
String flyoverTime = time.timestamp(DateTime::TIMESTAMP_TIME);
Serial.println(flyoverDate);
Serial.println(flyoverTime);
display.clearDisplay();
display.setCursor(35, 7);
display.println(flyoverDate);
display.setCursor(40, 23);
display.println(flyoverTime);
display.display();
}
else {
Serial.println("Error on HTTP request");
}
}
}
void setup() {
pinMode (12, OUTPUT); //LED Pin (on ESP8266 -> D6)
Serial.begin(115200);
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { //Display address: 0x3C
Serial.println(F("SSD1306 allocation failed"));
for (;;);
}
display.setTextSize(1);
display.setTextColor(WHITE);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
display.clearDisplay();
display.setCursor(0, 10);
display.println("Connecting to WiFi...");
display.display();
}
delay(1000);
display.clearDisplay();
display.setCursor(0, 10);
display.println("Hello, world!");
display.display();
}
void loop() {
apiCall(); //Call the API for ISS flyovers
while (riseTime != currentTime) {
delay(1000);
currentTime += 1;
Serial.println(currentTime);
if ((riseTime - currentTime) <= 60 && riseTime > currentTime) {
digitalWrite(12, HIGH);
}
}
if (riseTime == currentTime) {
int maxDuration = duration; //Save max value of duration for later mapping
for (duration; duration >= 0; duration--) {
display.clearDisplay();
int xOnDisplay = map(duration, maxDuration, 0, -94, 128); //Calculate animation on display
display.drawBitmap(xOnDisplay, 0, iss, 128, 32, WHITE); //show animation
display.display();
delay(1000);
}
digitalWrite(12, LOW);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment