v.0.2.1 ColorSerial

This commit is contained in:
tiijay
2025-11-08 17:09:23 +01:00
parent b3c5cfa1e0
commit 9d29dcd542
3 changed files with 534 additions and 16 deletions

View File

@@ -0,0 +1,398 @@
#include "ColorSerial.h"
// ANSI Escape Codes
const char *ColorSerial::RESET = "\033[0m";
const char *ColorSerial::BOLD = "\033[1m";
const char *ColorSerial::UNDERLINE = "\033[4m";
const char *ColorSerial::ITALIC = "\033[3m";
// Standard Colors
const char *ColorSerial::RED = "\033[38;2;255;0;0m";
const char *ColorSerial::GREEN = "\033[38;2;0;255;0m";
const char *ColorSerial::BLUE = "\033[38;2;0;120;255m";
const char *ColorSerial::YELLOW = "\033[38;2;255;255;0m";
const char *ColorSerial::CYAN = "\033[38;2;0;255;255m";
const char *ColorSerial::MAGENTA = "\033[38;2;255;0;255m";
const char *ColorSerial::ORANGE = "\033[38;2;255;165;0m";
const char *ColorSerial::WHITE = "\033[38;2;255;255;255m";
const char *ColorSerial::GRAY = "\033[38;2;128;128;128m";
// Icons
const char *ColorSerial::ICON_SUCCESS = "";
const char *ColorSerial::ICON_ERROR = "";
const char *ColorSerial::ICON_WARNING = "⚠️";
const char *ColorSerial::ICON_INFO = "";
const char *ColorSerial::ICON_DEBUG = "🐛";
const char *ColorSerial::ICON_WIFI = "📡";
const char *ColorSerial::ICON_WEATHER = "🌡️";
// Main Logging Methods
void ColorSerial::success(const char *message, const char *details)
{
Serial.print(GREEN);
Serial.print(ICON_SUCCESS);
Serial.print(" SUCCESS: ");
Serial.print(RESET);
Serial.print(BOLD);
Serial.print(message);
Serial.print(RESET);
if (strlen(details) > 0)
{
Serial.print(" ");
Serial.print(GRAY);
Serial.print("(");
Serial.print(details);
Serial.print(")");
Serial.print(RESET);
}
Serial.println();
}
void ColorSerial::error(const char *message, const char *details)
{
Serial.print(RED);
Serial.print(ICON_ERROR);
Serial.print(" ERROR: ");
Serial.print(RESET);
Serial.print(BOLD);
Serial.print(message);
Serial.print(RESET);
if (strlen(details) > 0)
{
Serial.print(" ");
Serial.print(RED);
Serial.print(details);
Serial.print(RESET);
}
Serial.println();
}
void ColorSerial::warning(const char *message, const char *details)
{
Serial.print(YELLOW);
Serial.print(ICON_WARNING);
Serial.print(" WARNING: ");
Serial.print(RESET);
Serial.print(BOLD);
Serial.print(message);
Serial.print(RESET);
if (strlen(details) > 0)
{
Serial.print(" ");
Serial.print(GRAY);
Serial.print("(");
Serial.print(details);
Serial.print(")");
Serial.print(RESET);
}
Serial.println();
}
void ColorSerial::info(const char *message, const char *details)
{
Serial.print(CYAN);
Serial.print(ICON_INFO);
Serial.print(" INFO: ");
Serial.print(RESET);
Serial.print(BOLD);
Serial.print(message);
Serial.print(RESET);
if (strlen(details) > 0)
{
Serial.print(" ");
Serial.print(GRAY);
Serial.print("(");
Serial.print(details);
Serial.print(")");
Serial.print(RESET);
}
Serial.println();
}
void ColorSerial::debug(const char *message, const char *details)
{
Serial.print(MAGENTA);
Serial.print(ICON_DEBUG);
Serial.print(" DEBUG: ");
Serial.print(RESET);
Serial.print(ITALIC);
Serial.print(message);
Serial.print(RESET);
if (strlen(details) > 0)
{
Serial.print(" ");
Serial.print(GRAY);
Serial.print("[");
Serial.print(details);
Serial.print("]");
Serial.print(RESET);
}
Serial.println();
}
// Data Display Methods
void ColorSerial::data(const char *label, const char *value, const char *unit)
{
Serial.print(BLUE);
Serial.print(label);
Serial.print(":");
Serial.print(RESET);
Serial.print(" ");
Serial.print(BOLD);
Serial.print(WHITE);
Serial.print(value);
Serial.print(RESET);
Serial.print(unit);
Serial.println();
}
void ColorSerial::data(const char *label, float value, const char *unit)
{
char buf[20];
snprintf(buf, sizeof(buf), "%.1f", value);
data(label, buf, unit);
}
void ColorSerial::data(const char *label, int value, const char *unit)
{
char buf[20];
snprintf(buf, sizeof(buf), "%d", value);
data(label, buf, unit);
}
void ColorSerial::temperature(float temp, const char *label)
{
const char *color;
if (temp < 0)
color = CYAN;
else if (temp < 10)
color = BLUE;
else if (temp < 20)
color = GREEN;
else if (temp < 30)
color = YELLOW;
else
color = RED;
Serial.print(BLUE);
Serial.print(label);
Serial.print(": ");
Serial.print(RESET);
Serial.print(color);
Serial.print(temp, 1);
Serial.print("°C");
Serial.print(RESET);
Serial.println();
}
void ColorSerial::wifiStatus()
{
if (WiFi.status() == WL_CONNECTED)
{
Serial.print(GREEN);
Serial.print(ICON_WIFI);
Serial.print(" WiFi: ");
Serial.print(RESET);
Serial.print(BOLD);
Serial.print("Connected");
Serial.print(GRAY);
Serial.print(" (IP: ");
Serial.print(WiFi.localIP().toString().c_str());
Serial.print(")");
Serial.print(RESET);
Serial.println();
}
else
{
Serial.print(RED);
Serial.print(ICON_WIFI);
Serial.print(" WiFi: ");
Serial.print(RESET);
Serial.print(BOLD);
Serial.print("Disconnected");
Serial.print(RESET);
Serial.println();
}
}
// Progress Bars
void ColorSerial::progressBar(int percent, const char *label, int width)
{
int pos = (percent * width) / 100;
const char *color = (percent < 30) ? RED : (percent < 70) ? YELLOW
: GREEN;
Serial.print(BLUE);
Serial.print(label);
Serial.print(" [");
Serial.print(RESET);
for (int i = 0; i < width; i++)
{
if (i < pos)
{
Serial.print(color);
Serial.print("");
}
else
{
Serial.print(GRAY);
Serial.print("");
}
}
Serial.print(RESET);
Serial.print(BLUE);
Serial.print("] ");
Serial.print(color);
Serial.print(percent);
Serial.print("%");
Serial.print(RESET);
Serial.println();
}
// Section Headers
void ColorSerial::header(const char *title, char decorator, int width)
{
int titleLen = strlen(title);
int padding = (width - titleLen - 2) / 2;
Serial.println();
// Top line
Serial.print(MAGENTA);
for (int i = 0; i < width; i++)
{
Serial.print(decorator);
}
Serial.print(RESET);
Serial.println();
// Title line
Serial.print(MAGENTA);
Serial.print("");
Serial.print(RESET);
for (int i = 0; i < padding; i++)
{
Serial.print(" ");
}
Serial.print(BOLD);
Serial.print(title);
Serial.print(RESET);
Serial.println();
// Bottom line
Serial.print(MAGENTA);
for (int i = 0; i < width; i++)
{
Serial.print(decorator);
}
Serial.print(RESET);
Serial.println();
}
void ColorSerial::subheader(const char *title)
{
Serial.print(CYAN);
Serial.print("");
Serial.print(RESET);
Serial.print(BOLD);
Serial.print(title);
Serial.print(RESET);
Serial.println();
}
// Weather Specific Private Methods
const char *ColorSerial::getWeatherCondition(int code)
{
switch (code)
{
case 0:
return "Clear sky";
case 1:
return "Mainly clear";
case 2:
return "Partly cloudy";
case 3:
return "Overcast";
case 45:
case 48:
return "Fog";
case 51:
case 53:
case 55:
return "Drizzle";
case 61:
case 63:
case 65:
return "Rain";
case 71:
case 73:
case 75:
return "Snow";
case 95:
case 96:
case 99:
return "Thunderstorm";
default:
return "Unknown weather";
}
}
const char *ColorSerial::getWeatherIcon(int code)
{
if (code == 0)
return "☀️";
if (code <= 2)
return "";
if (code == 3)
return "☁️";
if (code <= 55)
return "🌧️";
if (code <= 65)
return "🌧️";
if (code <= 79)
return "❄️";
return "🌩️";
}
const char *ColorSerial::getWeatherColor(int code)
{
if (code <= 2)
return YELLOW;
if (code == 3)
return GRAY;
if (code <= 55)
return CYAN;
if (code <= 65)
return BLUE;
if (code <= 79)
return WHITE;
return MAGENTA;
}
void ColorSerial::weatherCondition(int code, const char *customLabel)
{
const char *label = (customLabel == nullptr || strlen(customLabel) == 0) ? "Condition" : customLabel;
const char *condition = getWeatherCondition(code);
const char *icon = getWeatherIcon(code);
const char *color = getWeatherColor(code);
Serial.print(BLUE);
Serial.print(label);
Serial.print(": ");
Serial.print(RESET);
Serial.print(color);
Serial.print(icon);
Serial.print(" ");
Serial.print(condition);
Serial.print(RESET);
Serial.println();
}

View File

@@ -0,0 +1,66 @@
#ifndef COLORSERIAL_H
#define COLORSERIAL_H
#include <Arduino.h>
#include <WiFi.h>
class ColorSerial
{
private:
static const char *getWeatherCondition(int code);
static const char *getWeatherIcon(int code);
static const char *getWeatherColor(int code);
public:
// ANSI Escape Codes
static const char *RESET;
static const char *BOLD;
static const char *UNDERLINE;
static const char *ITALIC;
// Standard Colors
static const char *RED;
static const char *GREEN;
static const char *BLUE;
static const char *YELLOW;
static const char *CYAN;
static const char *MAGENTA;
static const char *ORANGE;
static const char *WHITE;
static const char *GRAY;
// Icons
static const char *ICON_SUCCESS;
static const char *ICON_ERROR;
static const char *ICON_WARNING;
static const char *ICON_INFO;
static const char *ICON_DEBUG;
static const char *ICON_WIFI;
static const char *ICON_WEATHER;
// Main Logging Methods
static void success(const char *message, const char *details = "");
static void error(const char *message, const char *details = "");
static void warning(const char *message, const char *details = "");
static void info(const char *message, const char *details = "");
static void debug(const char *message, const char *details = "");
// Data Display Methods
static void data(const char *label, const char *value, const char *unit = "");
static void data(const char *label, float value, const char *unit = "");
static void data(const char *label, int value, const char *unit = "");
static void temperature(float temp, const char *label = "Temperature");
static void wifiStatus();
// Progress Bars
static void progressBar(int percent, const char *label = "", int width = 20);
// Section Headers
static void header(const char *title, char decorator = '', int width = 40);
static void subheader(const char *title);
// Weather Specific
static void weatherCondition(int code, const char *customLabel = "");
};
#endif

View File

@@ -1,6 +1,8 @@
#include <WiFi.h> #include <WiFi.h>
#include <HTTPClient.h>
#include <ArduinoJson.h> #include <ArduinoJson.h>
#include <LedMatrix.h> #include <LedMatrix.h>
#include <ColorSerial.h>
#include <FastLED.h> #include <FastLED.h>
#include <MyClass.h> #include <MyClass.h>
#include <BlinkInternLed.h> #include <BlinkInternLed.h>
@@ -93,9 +95,26 @@ void setupMatrix()
matrix.show(); matrix.show();
} }
void get_json_data() void connect_wifi()
{ {
Serial.println("get_json_data()"); // For Wokwi simulation - use simulated WiFi
Serial.println("Connecting to WiFi...");
// In Wokwi, WiFi connects automatically in simulation
WiFi.begin("Wokwi-GUEST", ""); // Wokwi's simulated WiFi
while (WiFi.status() != WL_CONNECTED)
{
delay(250);
Serial.print(".");
}
Serial.println("\nConnected to WiFi!");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
}
void json_with_WiFiClient()
{
Serial.println("json_with_WiFiClient()");
WiFiClient client; WiFiClient client;
const int timeout = 5000; // 5 second timeout const int timeout = 5000; // 5 second timeout
@@ -176,21 +195,54 @@ void get_json_data()
} }
} }
void connect_wifi() void json_with_HTTPClient()
{ {
// For Wokwi simulation - use simulated WiFi Serial.println("json_with_HTTPClient()");
Serial.println("Connecting to WiFi...");
// In Wokwi, WiFi connects automatically in simulation HTTPClient http;
WiFi.begin("Wokwi-GUEST", ""); // Wokwi's simulated WiFi
while (WiFi.status() != WL_CONNECTED) http.begin("http://api.open-meteo.com/v1/forecast?latitude=52.52&longitude=13.41&current_weather=true");
// http.setTimeout(5000);
int httpCode = http.GET();
if (httpCode != HTTP_CODE_OK)
{ {
delay(250); Serial.printf("HTTP error: %d\n", httpCode);
Serial.print("."); http.end();
return;
}
Serial.println("connected to api.open-meteo.com :-)");
Serial.println("=== Full Response Complete ===");
String payload = http.getString();
http.end();
Serial.println(payload);
// JSON parsen
JsonDocument doc;
DeserializationError error = deserializeJson(doc, payload);
if (!error)
{
JsonObject current = doc["current_weather"];
JsonObject units = doc["current_weather_units"];
float temperature = current["temperature"];
String temp_unit = units["temperature"];
Serial.printf("Temperature: %.1f %s", temperature, temp_unit.c_str());
Serial.println();
}
else
{
Serial.println("JSON parse failed");
Serial.println(error.c_str());
return;
} }
Serial.println("\nConnected to WiFi!");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
} }
void setup() void setup()
@@ -200,14 +252,16 @@ void setup()
// Wait for Serial to be ready (important for some boards) // Wait for Serial to be ready (important for some boards)
while (!Serial) while (!Serial)
{
delay(10); delay(10);
}
ColorSerial::header("PICO W WEATHER STATION");
ColorSerial::info("System starting up", "v1.0");
connect_wifi(); connect_wifi();
if (WiFi.status() == WL_CONNECTED) if (WiFi.status() == WL_CONNECTED)
{ {
get_json_data(); json_with_WiFiClient();
json_with_HTTPClient();
} }
else else
{ {