Hardware components | ||||||
![]() |
| × | 1 | |||
Software apps and online services | ||||||
![]() |
| |||||
HELIOS is a real-time space weather decision console powered by live data from the NOAA Space Weather Prediction Center.
Instead of showing raw numbers, HELIOS translates them into actionable intelligence across critical systems:
- GNSS / GPS - positioning accuracy and drift risk
- HF Radio - ionospheric propagation and blackout conditions
- Ionosphere State - overall atmospheric disturbance level
- Aurora Status - visible manifestation of geomagnetic activity
It’s not just data - it’s interpretation.What HELIOS Does
- Fetches live Kp index data every 5 minutes
- Converts it into geomagnetic storm levels (G0–G5)
Interprets impact across:
- GNSS positioning systems
- HF radio communications
- Ionospheric stability
- Aurora activity
- Provides a forecast outlook based on trend
- Shows data freshness + system status
- Runs on a clean, retro-inspired ops interface
HELIOS Space Weather Intel
C/C++1) Flash this code onto an M5StickC Plus / Plus 2 using Arduino IDE.
2) Enter your WiFi credentials below:
const char* ssid = "YOUR_WIFI_SSID";
const char* password = "YOUR_WIFI_PASSWORD";
3) Power on the device.
4) The system connects to WiFi and fetches NOAA Kp index data every 5 minutes.
This badge is designed for:
- Space weather awareness
- Aviation / RF / satellite enthusiasts
- Educational demos & live showcases
- Embedded systems experimentation
2) Enter your WiFi credentials below:
const char* ssid = "YOUR_WIFI_SSID";
const char* password = "YOUR_WIFI_PASSWORD";
3) Power on the device.
4) The system connects to WiFi and fetches NOAA Kp index data every 5 minutes.
This badge is designed for:
- Space weather awareness
- Aviation / RF / satellite enthusiasts
- Educational demos & live showcases
- Embedded systems experimentation
#include <M5Unified.h>
#include <WiFi.h>
#include <HTTPClient.h>
#include <WiFiClientSecure.h>
#include <ArduinoJson.h>
#include <time.h>
// ---------------- WIFI ----------------
const char* ssid = ""; //SSID
const char* password = ""; //Password
// ---------------- DATA ----------------
float kp = 0;
float kp_prev = 0;
float riskIndex = 0;
String gnssStatus, hfStatus, ionosphereState, auroraStatus;
String flareClass = "A";
String kpTimeFormatted = "--:--";
String kpDateFormatted = "--";
String sysTimeStr = "--:--";
unsigned long lastFetch = 0;
// ---------------- COLORS ----------------
#define CYAN 0x07FF
#define WHITE 0xFFFF
#define BLACK 0x0000
#define YELLOW 0xFFE0
#define ORANGE 0xFD20
// ---------------- BOOT ----------------
void heliosBoot() {
M5.Lcd.fillScreen(BLACK);
for (int i = 0; i <= 100; i += 5) {
M5.Lcd.setTextSize(2);
M5.Lcd.setTextColor(CYAN);
M5.Lcd.setCursor(30, 40);
M5.Lcd.println("HELIOS");
M5.Lcd.drawRect(20, 90, 200, 10, WHITE);
M5.Lcd.fillRect(20, 90, i * 2, 10, CYAN);
delay(25);
M5.Lcd.fillScreen(BLACK);
}
M5.Lcd.setTextSize(1);
M5.Lcd.setTextColor(WHITE);
M5.Lcd.setCursor(45, 60);
M5.Lcd.println("SYSTEM READY");
delay(800);
}
// ---------------- BATTERY ----------------
void drawBattery() {
int level = M5.Power.getBatteryLevel();
int x = 200, y = 5;
M5.Lcd.drawRect(x, y, 30, 10, WHITE);
int fill = (level * 28) / 100;
uint16_t c = CYAN;
if (level < 40) c = YELLOW;
if (level < 20) c = ORANGE;
M5.Lcd.fillRect(x + 1, y + 1, fill, 8, c);
}
// ---------------- TIME ----------------
void updateTime() {
struct tm t;
if (getLocalTime(&t)) {
char buf[20];
strftime(buf, sizeof(buf), "%d-%m %H:%M", &t);
sysTimeStr = String(buf);
}
}
// ---------------- KP FETCH ----------------
void fetchKp() {
WiFiClientSecure client;
client.setInsecure();
HTTPClient http;
http.begin(client,
"https://services.swpc.noaa.gov/json/planetary_k_index_1m.json");
if (http.GET() != 200) {
http.end();
return;
}
String payload = http.getString();
http.end();
DynamicJsonDocument doc(16384);
deserializeJson(doc, payload);
JsonObject last = doc[doc.size() - 1];
kp = last["kp_index"].as<float>();
String t = last["time_tag"].as<String>();
if (t.length() >= 16) {
kpDateFormatted = t.substring(8, 10) + "-" + t.substring(5, 7);
kpTimeFormatted = t.substring(11, 16);
}
lastFetch = millis();
}
// ---------------- FLARE ----------------
void fetchFlare() {
WiFiClientSecure client;
client.setInsecure();
HTTPClient http;
http.begin(client,
"https://services.swpc.noaa.gov/json/goes/primary/xrays-7-day.json");
if (http.GET() != 200) {
http.end();
return;
}
String payload = http.getString();
http.end();
DynamicJsonDocument doc(32768);
deserializeJson(doc, payload);
JsonObject last = doc[doc.size() - 1];
float flux = last["flux"].as<float>();
if (flux < 1e-6) flareClass = "A";
else if (flux < 1e-5) flareClass = "B";
else if (flux < 1e-4) flareClass = "C";
else if (flux < 1e-3) flareClass = "M";
else flareClass = "X";
}
// ---------------- RISK ----------------
void computeRisk() {
riskIndex = 0;
riskIndex += kp * 12;
if (flareClass == "B") riskIndex += 5;
else if (flareClass == "C") riskIndex += 10;
else if (flareClass == "M") riskIndex += 20;
else if (flareClass == "X") riskIndex += 35;
float delta = kp - kp_prev;
riskIndex += delta * 8;
if (riskIndex > 100) riskIndex = 100;
if (riskIndex < 0) riskIndex = 0;
kp_prev = kp;
if (riskIndex < 30) {
gnssStatus = "Nominal";
hfStatus = "Stable";
ionosphereState = "Quiet";
auroraStatus = "Low";
}
else if (riskIndex < 60) {
gnssStatus = "Degraded";
hfStatus = "Disturbed";
ionosphereState = "Active";
auroraStatus = "Moderate";
}
else {
gnssStatus = "Severe";
hfStatus = "Blackout";
ionosphereState = "Storm";
auroraStatus = "High";
}
}
// ---------------- RENDER ----------------
void render() {
M5.Lcd.fillScreen(BLACK);
M5.Lcd.setTextSize(1);
// HEADER
M5.Lcd.setTextColor(CYAN);
M5.Lcd.setCursor(5, 5);
M5.Lcd.println("HELIOS SPACE WEATHER INTEL");
drawBattery();
M5.Lcd.drawLine(0, 15, 240, 15, WHITE);
// RISK
M5.Lcd.setTextColor(WHITE);
M5.Lcd.setCursor(5, 25);
M5.Lcd.print("RISK: ");
M5.Lcd.print((int)riskIndex);
M5.Lcd.println(" / 100");
// TABLE ROW 1
M5.Lcd.setCursor(5, 45);
M5.Lcd.print("GNSS - ");
M5.Lcd.print(gnssStatus);
M5.Lcd.setCursor(120, 45);
M5.Lcd.print("HF - ");
M5.Lcd.println(hfStatus);
// TABLE ROW 2
M5.Lcd.setCursor(5, 60);
M5.Lcd.print("IONO - ");
M5.Lcd.print(ionosphereState);
M5.Lcd.setCursor(120, 60);
M5.Lcd.print("AURORA - ");
M5.Lcd.println(auroraStatus);
M5.Lcd.drawLine(0, 80, 240, 80, WHITE);
// TIME ROW
M5.Lcd.setTextColor(CYAN);
M5.Lcd.setCursor(5, 90);
M5.Lcd.print("KP: ");
M5.Lcd.print(kpDateFormatted);
M5.Lcd.print(" ");
M5.Lcd.println(kpTimeFormatted);
M5.Lcd.setCursor(5, 105);
M5.Lcd.print("TIME: ");
M5.Lcd.println(sysTimeStr);
M5.Lcd.setCursor(5, 120);
M5.Lcd.print("DATA: ");
M5.Lcd.println((millis() - lastFetch < 300000) ? "LIVE" : "STALE");
}
// ---------------- SETUP ----------------
void setup() {
auto cfg = M5.config();
M5.begin(cfg);
M5.Lcd.setRotation(1);
heliosBoot();
WiFi.begin(ssid, password);
delay(2000);
configTime(0, 0, "pool.ntp.org");
fetchKp();
fetchFlare();
updateTime();
computeRisk();
render();
}
// ---------------- LOOP ----------------
void loop() {
static unsigned long last = 0;
if (millis() - last > 300000) {
fetchKp();
fetchFlare();
updateTime();
computeRisk();
render();
last = millis();
}
delay(50);
}













Comments