ISS-Position

Internationale Raumstation ISS
Abb.: Internationale Raumstation ISS (Quelle: Pixabay)

Unter open-notify.org wird eine kostenfreie API zur Verfügung gestellt, mit deren Hilfe sich die aktuelle Position der internationalen Raumstation ISS bestimmen lässt. Mit dem Arduino Nano RP2040 Connect lässt sich diese Position auslesen und kann eine LED blinken lassen, sobald sich die ISS über der eigenen Position befindet.

Verwendete Bauteile

Aufbau

Für dieses Experiment benötigt man nur den Arduino Nano RP2040 Connect, der zur Programmierung an den PC bzw. später an eine 5V-Spannungsquelle angeschlossen wird. Als Alarm-Zeichen wird die interne LED verwendet, die blinken soll, sobald sich die ISS in der Nähe der eigenen Position befindet.

Sketch

Für den folgenden Sketch werden zwei Libaries benötigt, die beide über die Arduino-IDE heruntergeladen werden können: WiFiNINA und ArduinoJson. Vor dem Kompilieren sollten noch WIFI_SSID und WIFI_PASSWORD auf das aktuell genutzte WLAN angepasst werden, sowie die Geo-Koordinaten MY_LATITUDE und MY_LONGITUDE der aktuellen Postion auf der Erde.
Kommt nun die ISS in die Nähe dieser Koordinaten, so blinkt die interne LED des Nano RP2040 Connect. (Zu Debug-Zwecken kann die Position der ISS auf http://open-notify.org/Open-Notify-API/ visuell mit einer Weltkarte überprüft werden)

#include <WiFiNINA.h>
#include <ArduinoJson.h>

// WiFi settings:
const char* WIFI_SSID     = "xxxxx";
const char* WIFI_PASSWORD = "xxxxx";

// Geocoordinate settings:
const float MY_LATITUDE  = 45.57; // "Geographische Breite"
const float MY_LONGITUDE = -4.59; // "Geographische Länge"

const char* API_SERVER_HOST = "api.open-notify.org";
const char* API_SERVER_URL  = "/iss-now.json";

const int INTERVAL_LED_BLINK  =   200; // in ms
const int INTERVAL_API_UPDATE = 10000; // in ms

#define lmillis() ((long)millis())
bool isISSnearby = false;
long lastLedUpdate = 0, lastApiUpdate = 0;
WiFiClient client;

void setup()
{
    Serial.begin(9600);
    pinMode(LED_BUILTIN, OUTPUT);
    lastLedUpdate = lmillis();
    lastApiUpdate = lmillis();
}

void loop()
{
    calculateISSPosition();
    if (isISSnearby == true && lmillis() - lastLedUpdate >= 0) {
        lastLedUpdate = lmillis() + INTERVAL_LED_BLINK;
        digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
    }
    if (lmillis() - lastApiUpdate >= 0) {
        lastApiUpdate = lmillis() + INTERVAL_API_UPDATE;
        connectWiFi();
        sendHttpRequest();
    }
}

void connectWiFi()
{
    if (WiFi.status() == WL_CONNECTED) {
        return;
    }

    Serial.print("Connecting to WiFi...");
    WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
    while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print(".");
    }
    Serial.println("[connected]");
}

void sendHttpRequest()
{
    String url = "http://" + String(API_SERVER_HOST) + String(API_SERVER_URL);
    Serial.println("Connecting to " + url + "...");

    client.stop();
    if (client.connect(API_SERVER_HOST, 80)) {
        client.println("GET " + url + " HTTP/1.1");
        client.println("Host: " + String(API_SERVER_HOST));
        client.println("Connection: close");
        client.println();
    } else {
        Serial.println("Connection to server failed!");
    }
}

void calculateISSPosition()
{
    if (!client.available()) {
        return;
    }

    StaticJsonDocument<500> jsonDoc;
    char resultJson[500];
    bool isHeader = true;
    int idx = 0;

    while (client.available()) {
        char c = client.read();
        if (c == '{') {
            isHeader = false;
        }
        if (isHeader == false) {
            resultJson[idx++] = c;
        }
    }
    if (resultJson[0] == '\0') {
        return;
    }

    DeserializationError jsonError = deserializeJson(jsonDoc, resultJson);
    if (jsonError) {
        Serial.print(F("deserializeJson() failed: "));
        Serial.println(jsonError.f_str());
        return;
    }

    double issLatitude = jsonDoc["iss_position"]["latitude"];
    double issLongitude = jsonDoc["iss_position"]["longitude"];

    Serial.println("LONGITUDE diff = " + String(abs(MY_LONGITUDE - issLongitude)));
    Serial.println("LATITUDE diff = " + String(abs(MY_LATITUDE - issLatitude)));

    if (abs(MY_LONGITUDE - issLongitude) < 3.0 && abs(MY_LATITUDE - issLatitude) < 3.0) {
        isISSnearby = true;
        Serial.println("ISS nearby!");
    } else {
        isISSnearby = false;
        digitalWrite(LED_BUILTIN, LOW);
    }
}
zurück