ESP8266 Projekte

Verfolge die Raumstation ISS am Himmel

iss tracker esp8266

Mit diesem ISS Tracker weißt du immer, wann du die Internationale Raumstation am Himmel beobachten kannst: Eine OLED-Anzeige zeigt Zeit und Dauer des nächsten Überflugs an, und sobald sich die ISS über den Horizont erhebt, signalisiert eine LED, dass es Zeit zum Beobachten ist.

Die ISS umkreist die Erde alle 90 Minuten – nicht immer direkt über deinem Kopf, aber du hast trotzdem jeden Tag mehrere Gelegenheiten, den Überflug der ISS zu beobachten. Die beste Zeit dafür ist früh morgens oder spät abends in der Abenddämmerung. Hier wird die ISS von der Sonne beleuchtet und der Himmel ist noch oder bereits dunkel genug, um die ISS mit bloßem Auge zu sehen.

Anfänger

ca. 1 Stunde

ca. 15 €

Für dieses Projekt benötigst du (Mengen s. Beschreibung):

So funktioniert der ISS Tracker

Der wichtigste Baustein für dieses Projekt ist die API von open-notify.org – ein kostenloser Dienst, der berechnet, wann die ISS an deinem Standort am Himmel zu sehen sein wird. Dazu benötigst du deine Koordinaten und optional die Höhe deines Standortes über dem Meeresspiegel.

Du fragst die nächsten Flugzeiten der ISS von der API ab und baust dir damit einen Timer. Auf dem OLED-Display wird die nächste Beobachtungszeit angezeigt. Sobald sich die ISS über den Horizont erhebt, erscheint für die Dauer des Fluges eine animierte Raumstation auf dem Display und eine LED leuchtet auf.

Hinweis: Da dieses Projekt auf externe APIs aufbaut, ist es von deren Funktion abhängig. Es kann also sein, dass dieses Projekt vorübergehend nicht funktioniert, weil die APIs gewartet werden. Wenn es Veränderungen im Service der APIs gibt, kann es ebenso sein, dass der Sketch verändert werden muss.

Wenn die ISS wieder verschwunden ist, erlischt die LED und das Display zeigt den nächsten Überflug an.

Wichtige Tutorials, die dir beim Verständnis dieses Projekts weiterhelfen, findest du hier:

Der Aufbau des Projekts

Es dauert nur wenige Minuten, um den ISS-Tracker aufzubauen. Schließe zunächst dein OLED-Display an: GND an Masse und VCC an Plus. Dann kümmerst du dich um die Kommunikation per I2C. Verbinde den Display-Pin SCK mit D1 an deinem ESP8266 und den Pin SDA mit Pin D2.

Verbinde nun die Anode (langes Bein) der LED mit Pin D6 und die Kathode über einen geeigneten Widerstand (z.B. 330 Ohm) mit GND an deinem Microcontroller.

Der passende Sketch und deine Anpassungen

Du findest weiter unten den gesamten Sketch für deinen ESP8266. Um den ISS Tracker bei dir zuhause zum Laufen zu bringen, musst du allerdings ein paar Anpassungen vornehmen:

Zugangsdaten zu deinem WLAN-Netzwerk

Trage zunächst deine eigenen Zugangsdaten hier ein:

const char* ssid = "SSID";
const char* password =  "PASSWORT";

Koordinaten deines Standorts

Um zu berechnen, wann die ISS über deinem Kopf erscheint oder zumindest an deinem Standort sichtbar sein wird, benötigst du deine Koordinaten. Wenn du deine Koordinaten nicht kennst, kannst du sie auf latlong.net finden.

Neben Breiten- und Längengrad spielt auch die Höhe über dem Meeresspiegel eine Rolle bei der Berechnung. Je höher du dich befindest, desto früher und länger kannst du die ISS während ihres Überflugs beobachten. Diese Einstellung ist jedoch optional – wenn du nicht selbst eine Höhe angibst, rechnet die API einfach mit 100 Metern.

const float latitude = 00.00; //Dein Breitengrad
const float longitude = 00.00; //Dein Längengrad
const float myAltitude = 100.00;

Die richtige Zeitzone

Alle Daten werden in Koordinierter Weltzeit (UTC) abgerufen und berechnet. In Zeile 148 des Sketchs kannst du deine Abweichung von der UTC eingeben. In diesem Beispiel ist +7200 Sekunden (2 Stunden) die Abweichung für die mitteleuropäische Sommerzeit.

Achte unbedingt darauf beim Wechsel von Sommer- zu Winterzeit den Sketch anzupassen.

Und das war es auch schon! 🙂 Hier nun der vollständige Sketch:

Sketch als .txt anschauen

/*********
  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);
  }
}

Wie geht es weiter?

Du hast jetzt einen ISS Tracker im Rohbau. Wenn du etwas schickeres für deine Wohnung haben möchtest, sind vielleicht diese leuchtenden Würfel eine gute Wahl.

Letzte Aktualisierung am 28.09.2020 / Affiliate Links / Bilder von der Amazon Product Advertising API

Vielleicht interessiert dich das auch

Kommentare sind nicht verfügbar