In diesem Projekt baust du dir ein cooles Gadget, das leuchtet, sobald die ISS über dir fliegt. Es besteht aus zwei ineinander gesteckten Würfel: Der untere beherbergt die Technik; der obere eine versteckte ISS auf der Innenseite, die erst sichtbar wird, wenn die echte International Space Station an dir vorbeifliegt.
Die ISS umkreist die Erde alle 90 Minuten – nicht immer direkt über deinem Kopf, aber du hast trotzdem jeden Tag theoretisch mehrere Gelegenheiten, ihren Überflug 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
1 – 2 Stunden
10 – 15 € plus ggfs. Kosten für Werkzeug & 3D-Druck
Für dieses Projekt benötigst du:
Dazu benötigst du noch:
- Lötkolben* (um Kabel an den LED Ring zu löten)
- 3D-Drucker* (wenn du unsere Würfel ausdrucken möchtest)
So funktioniert’s
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, der die Zeit herunterzählt, bis die Raumstation über den Horizont steigt. Wenn der große Moment gekommen ist, schaltet dein ESP8266* den NeoPixel LED-Ring* an. Die LEDs leuchten zunächst in Blau und verändern für die Zeit des Überflugs langsam ihre Farbe in Richtung Rot.
Wenn die ISS wieder verschwunden ist, gehen die LEDs aus, dein ESP8266 fragt die nächste Überflugszeit ab zählt die Zeit bis dahin herunter.
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.
Der Aufbau
Da dieses Projekt mit recht wenig Bauteilen auskommt, ist der Aufbau nicht besonders aufwändig. Die meiste Mühe macht das Löten des NeoPixel LED Rings – denn dieser wird meist ohne verlötete Pins ausgeliefert, was bedeutet, dass du das selbst erledigen musst.
Am LED Ring befinden sich vier Anschlüsse, von denen du jedoch nur drei benötigst. DI (Digital In), GND und VCC (5V). Löte hier also drei Header Pins an. Hinweis: Wenn du unsere Würfel als Gehäuse verwenden möchtest, löte die Pins in Richtung Ringmitte an, damit der Ring in den Würfel passt.
Stecke nun 3 Kabel an die Pins des LED Rings und verbinde sie wie folgt mit deinem ESP8266. Wir haben dafür ein Mini-Breadboard verwendet, du kannst die Kabel aber natürlich auch direkt an deinen Microcontroller stecken.
LED Ring | ESP8266 |
VCC (5V) | 3V3 |
DI | D4 |
GND | GND |
Das passende Gehäuse
Du könntest das Projekt natürlich ohne Gehäuse verwenden, aber besonders chic ist nicht. Wenn du einen 3D-Drucker besitzt, kannst du die Würfel ausdrucken, die wir entworfen haben.
Hier geht es zu den STL-Dateien auf Thingiverse.com
Im unteren befindet sich ein Loch auf der Rückseite für die Stromzufuhr und eine Halterung für den LED Ring. Der Deckel besitzt eine Öffnung, in die du den oberen Würfel stecken kannst. So sehen die beiden Würfel aufgebaut aus:
Die beiden Würfel bestehen aus 4 Einzelteilen. Der obere besitzt auf der Innenseite ein Modell der ISS, das von außen erst sichtbar wird, wenn der Würfel anfängt zu leuchten.
Am besten druckst du den unteren Würfel in einer dunklen Farbe, damit das Licht des LED Rings nicht durchscheint. Den oberen solltest du in weiß oder transparent ausdrucken, damit auf jeden Fall genug Licht durchscheinen und der Würfel leuchten kann.
Der Code
Kommen wir nun zum Sketch für deinen ESP8266. Teile davon haben wir bereits in anderen Tutorials besprochen, z.B. wie
- du einen ESP8266 mit der Arduino IDE programmierst
- du einen ESP8266 mit dem Internet verbindest
- du den NeoPixel LED Ring anschließt und verwendest
- du JSON-Strings abrufst und dekodierst
Das Herzstück des Codes ist die Abfrage der Überflugsdaten. Hierfür benötigst du die Koordinaten deines Standorts und optional die Höhe über dem Meeresspiegel. Um deine Koordinaten herauszufinden, kannst du z.B. Google Maps verwenden.
Trage deine Koordinaten dann am Anfang des Sketchs ein. Hier das Beispiel für Karlsruhe:
const float latitude = 49.00;
const float longitude = 8.40;
const float altitude = 115.00;
Bevor der API Call jedoch stattfinden kann, benötigt dein ESP8266 die Zugangsdaten zu deinem WLAN-Netz. Trage auch diese Informationen am Anfang des Sketchs ein:
const char* ssid = "NETZWERKNAME";
const char* password = "PASSWORT";
Hier nun der vollständige Sketch:
/*********
pollux labs, 2020
*********/
/*** Your WiFi Credentials ***/
const char* ssid = "your ssid";
const char* password = "your password";
/*** Your coordinates ***/
const float latitude = 00.00;
const float longitude = 00.00;
const float altitude = 100.00;
#include <ESP8266WiFi.h>
#include <ArduinoJson.h>
#include <ESP8266HTTPClient.h>
#include <Adafruit_NeoPixel.h>
//Variables for times and duration
long riseTime = 0;
long currentTime = 0;
long duration = 0;
long timeUntilFlyover = 0; //difference
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(12, 2, 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/europe/london"); //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();
}
}
}
void setup() {
pixels.begin();
pixels.setBrightness(100);
pinMode (2, OUTPUT); //LED Pin (at ESP8266: D4)
Serial.begin(115200);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting...");
}
success();
delay(1000);
Serial.println("Hello, world!");
}
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();
}
}
Wie geht es weiter?
Wir haben für den NeoPixel LED Ring einen Farbverlauf programmiert, der sich an der Dauer des Überflugs der ISS orientiert und von Blau langsam zu Rot wechselt. Wecke den Lichttechniker in dir und lass dir gerne etwas spannenderes einfallen.
Damit du nicht von der ISS überrascht wirst, kannst du auch ein Display anschließen, das dir anzeigt, wann der nächste Überflug stattfindet. Ein Beispiel hierfür findest du in unserer ersten Version dieses Projekts hier auf pollux labs.
Letzte Aktualisierung am 9.01.2021 / Affiliate Links / Bilder von der Amazon Product Advertising API