Compare commits
4 Commits
86d5bcc729
...
master
Author | SHA1 | Date | |
---|---|---|---|
24794eb5b3 | |||
ccd03735ea | |||
52726c263c | |||
215d412778 |
@@ -11,6 +11,7 @@
|
||||
[env:d1_mini_lite]
|
||||
platform = espressif8266
|
||||
board = d1_mini_lite
|
||||
; board_build.f_cpu = 160000000L
|
||||
framework = arduino
|
||||
lib_deps =
|
||||
bblanchon/ArduinoJson@^7.2.0
|
||||
|
234
src/main.cpp
234
src/main.cpp
@@ -7,6 +7,7 @@
|
||||
#include <WiFiUdp.h>
|
||||
#include <Adafruit_GFX.h>
|
||||
#include <Adafruit_SSD1306.h>
|
||||
#include <EEPROM.h>
|
||||
#include "bitmaps.h"
|
||||
#include "netman.h"
|
||||
|
||||
@@ -22,12 +23,7 @@ NTPClient timeClient(ntpUDP, "pool.ntp.org", 3600, 43200000);
|
||||
// Define these in config.h
|
||||
const String Location = LOCATION;
|
||||
const String API_Key = API_KEY;
|
||||
|
||||
void capitalizeFirstLetter(char* str) {
|
||||
if (str != nullptr && *str != '\0') {
|
||||
str[0] = toupper(str[0]);
|
||||
}
|
||||
}
|
||||
int displayBrightness = 205;
|
||||
|
||||
void beep(int buzz) {
|
||||
tone(PIN_BUZZER, buzz, 100);
|
||||
@@ -42,9 +38,11 @@ void initSystems() {
|
||||
pinMode(PIN_BUZZER, OUTPUT);
|
||||
pinMode(LED_BUILTIN, OUTPUT);
|
||||
digitalWrite(LED_BUILTIN, HIGH);
|
||||
EEPROM.begin(512);
|
||||
Wire.begin(); // Initialize I2C
|
||||
Wire.setClock(400000); // Set I2C to Fast Mode (400 kHz)
|
||||
|
||||
Wire.setClock(400000L); // Set I2C to Fast Mode (400 kHz)
|
||||
display.ssd1306_command(SSD1306_SETCONTRAST);
|
||||
display.ssd1306_command(displayBrightness); // Value between 0 and 255
|
||||
// Initialize the SSD1306 display
|
||||
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Adjust I2C address if needed
|
||||
for(;;); // Don't proceed, loop forever
|
||||
@@ -64,8 +62,8 @@ void initSystems() {
|
||||
// Timers for dynamic updates
|
||||
unsigned long lastWeatherUpdate = 0;
|
||||
unsigned long lastDisplayOverride = 0;
|
||||
const unsigned long weatherUpdateInterval = 1800000; // 30 minutes in milliseconds
|
||||
const unsigned long displayOverrideTimeout = 60000; // 1 minute in milliseconds
|
||||
const unsigned long weatherUpdateInterval = 2700000; // 45 minutes in milliseconds
|
||||
const unsigned long displayOverrideTimeout = 120000; // 2 minutes in milliseconds
|
||||
bool is_display_off = false;
|
||||
bool display_override = false;
|
||||
|
||||
@@ -89,6 +87,13 @@ void commonButtonHandler() {
|
||||
if (!leftBeeped) {
|
||||
beep(1000); // Play beep sound
|
||||
leftBeeped = true; // Set beeped state
|
||||
displayBrightness -= 50;
|
||||
if (displayBrightness < 10 ) {
|
||||
displayBrightness = 255;
|
||||
}
|
||||
// Send the command to set the contrast
|
||||
display.ssd1306_command(SSD1306_SETCONTRAST);
|
||||
display.ssd1306_command(displayBrightness); // Value between 0 and 255
|
||||
// Handle left short press action here
|
||||
}
|
||||
}
|
||||
@@ -102,6 +107,7 @@ void commonButtonHandler() {
|
||||
if (!middleBeeped) {
|
||||
beep(1000); // Play beep sound
|
||||
middleBeeped = true; // Set beeped state
|
||||
lastWeatherUpdate = millis() + weatherUpdateInterval + 1;
|
||||
// Handle middle short press action here
|
||||
}
|
||||
}
|
||||
@@ -170,6 +176,32 @@ void powerSaveCheck() {
|
||||
}
|
||||
}
|
||||
|
||||
float prevTemperature = 0.0;
|
||||
int prevHumidity = 0;
|
||||
float prevPressure = 0.0;
|
||||
float prevWindSpeed = 0.0;
|
||||
|
||||
void saveWeatherData() {
|
||||
|
||||
// Store float values as bytes (4 bytes for each float)
|
||||
EEPROM.put(0, prevTemperature);
|
||||
EEPROM.put(4, prevHumidity);
|
||||
EEPROM.put(8, prevPressure);
|
||||
EEPROM.put(12, prevWindSpeed);
|
||||
|
||||
// Commit changes to EEPROM
|
||||
EEPROM.commit(); // Write changes to flash
|
||||
}
|
||||
|
||||
void loadWeatherData() {
|
||||
// Read the data from EEPROM (addresses correspond to where they were saved)
|
||||
|
||||
EEPROM.get(0, prevTemperature);
|
||||
EEPROM.get(4, prevHumidity);
|
||||
EEPROM.get(8, prevPressure);
|
||||
EEPROM.get(12, prevWindSpeed);
|
||||
}
|
||||
|
||||
int icon = 0;
|
||||
String weatherState;
|
||||
float temperature;
|
||||
@@ -179,6 +211,21 @@ float wind_speed;
|
||||
int forecastIcons[3];
|
||||
int currentYear, currentMonth, currentDay;
|
||||
|
||||
// Function to get a random message from an array
|
||||
String getRandomMessage(const String messages[], int size) {
|
||||
return messages[random(size)];
|
||||
}
|
||||
|
||||
String generateTrendMessage(float current, float previous, const String& parameter) {
|
||||
if (current > previous) {
|
||||
return parameter + " rising ";
|
||||
} else if (current < previous) {
|
||||
return parameter + " falling ";
|
||||
} else {
|
||||
return parameter + " stable ";
|
||||
}
|
||||
}
|
||||
|
||||
bool fetchWeatherData() {
|
||||
// Get current time
|
||||
time_t epochTime = timeClient.getEpochTime();
|
||||
@@ -198,13 +245,151 @@ bool fetchWeatherData() {
|
||||
|
||||
if (!deserializeJson(doc, payload)) {
|
||||
String mainWeather = doc["weather"][0]["main"].as<String>();
|
||||
String description = doc["weather"][0]["description"].as<String>();
|
||||
capitalizeFirstLetter(const_cast<char*>(description.c_str()));
|
||||
weatherState = mainWeather + " " + description;
|
||||
temperature = doc["main"]["temp"].as<float>() - 273.15;
|
||||
humidity = doc["main"]["humidity"];
|
||||
pressure = doc["main"]["pressure"].as<float>() / 1000;
|
||||
wind_speed = doc["wind"]["speed"].as<float>();
|
||||
if (mainWeather == "Clear") {
|
||||
String clearMessages[] = {
|
||||
"All systems nominal. Atmospheric clearance detected.",
|
||||
"Clear skies confirmed. Solar energy levels stable for ship systems.",
|
||||
"Sky conditions optimal for external scan. Proceed with visual sweep.",
|
||||
"Visibility restored. All monitoring systems active and secure.",
|
||||
"Open space ahead. Prepare for normal operations.",
|
||||
"Solar reflection steady. Systems running at full capacity.",
|
||||
"Clear. No interference detected. Navigation optimal.",
|
||||
"Visible space clear. Proceed with standard operations.",
|
||||
"Skies unclouded. No anomalies detected.",
|
||||
"No obstructions in sight. Navigation systems operating normally.",
|
||||
"Bright and clear skies. Optimal conditions for long-range communication.",
|
||||
"Perfect visibility. All systems functioning within expected parameters.",
|
||||
"Clear and stable. No impact on external activities.",
|
||||
"The sky is free of disturbances. Proceed with confidence.",
|
||||
"Atmospheric conditions steady. All sensors reporting normal."
|
||||
};
|
||||
weatherState = generateTrendMessage(temperature, prevTemperature, "Temperature") + generateTrendMessage(pressure, prevPressure, "Atmospheric pressure") + generateTrendMessage(humidity, prevHumidity, "Humidity") + generateTrendMessage(wind_speed, prevWindSpeed, "Wind speed") + getRandomMessage(clearMessages, 15);
|
||||
} else if (mainWeather == "Clouds") {
|
||||
String cloudMessages[] = {
|
||||
"Cloud cover detected. Light interference on visual systems.",
|
||||
"Overcast conditions observed.",
|
||||
"Shadows overhead. Adjusting sensitivity on light filters.",
|
||||
"Moderate cloud formation detected. System performance normal.",
|
||||
"Atmospheric interference present. Monitoring light levels.",
|
||||
"Cloud coverage rising. Operational impact minimal.",
|
||||
"Low-visibility overhead. Preparing for reduced solar input.",
|
||||
"Sensors report cloud patterns. Adjusting visibility protocols.",
|
||||
"Clouds forming in surrounding space. Adjusting navigational parameters.",
|
||||
"Light cloud cover detected. No operational impact expected.",
|
||||
"Cloud formation increasing. Visual scan in progress.",
|
||||
"Partly cloudy. Visibility reduced, but no immediate danger.",
|
||||
"Overcast sky. Sensors adjusting for changing light levels.",
|
||||
"Increasing cloud density. Proceeding with caution on exterior tasks.",
|
||||
"Cumulus clouds observed. No operational impact anticipated."
|
||||
};
|
||||
weatherState = generateTrendMessage(temperature, prevTemperature, "Temperature") + generateTrendMessage(pressure, prevPressure, "Atmospheric pressure") + generateTrendMessage(humidity, prevHumidity, "Humidity") + generateTrendMessage(wind_speed, prevWindSpeed, "Wind speed") + getRandomMessage(cloudMessages, 15);
|
||||
} else if (mainWeather == "Rain") {
|
||||
String rainMessages[] = {
|
||||
"Precipitation incoming. Shielding activated.",
|
||||
"Rain detected. External moisture levels rising, activating water barriers.",
|
||||
"Surface moisture increasing. Prepare for external wet conditions.",
|
||||
"Rainstorm detected. External protection systems online.",
|
||||
"Raindrops detected. Surface conditions becoming slick.",
|
||||
"Incoming water influx. Prepare external surfaces for wet conditions.",
|
||||
"Rain detected. Traction systems engaged for slippery terrain.",
|
||||
"Wet conditions approaching. Hydration protocols for external units activated.",
|
||||
"Raindrops increasing. Proceed with caution on exterior surfaces.",
|
||||
"Heavy rain in the vicinity. External equipment may require adjustment.",
|
||||
"Intense rain incoming. All systems on standby for moisture management.",
|
||||
"Heavy precipitation. Surface traction adjustments being made.",
|
||||
"Rainfall intensifying. Navigation systems recalibrating.",
|
||||
"Storm-like rain detected. Prepare for potential delays in operations.",
|
||||
"Rain approaching. All moisture-sensitive systems under review."
|
||||
};
|
||||
weatherState = generateTrendMessage(temperature, prevTemperature, "Temperature") + generateTrendMessage(pressure, prevPressure, "Atmospheric pressure") + generateTrendMessage(humidity, prevHumidity, "Humidity") + generateTrendMessage(wind_speed, prevWindSpeed, "Wind speed") + getRandomMessage(rainMessages, 15);
|
||||
} else if (mainWeather == "Drizzle") {
|
||||
String drizzleMessages[] = {
|
||||
"Light drizzle detected. Surface moisture rising, minimal impact.",
|
||||
"Low-intensity rain detected. External systems functioning normally.",
|
||||
"Fine mist detected. Prepare for minor surface wetting.",
|
||||
"Gentle drizzle. Light hydration of external units detected.",
|
||||
"Atmospheric moisture levels rising slowly. Proceed with minor caution.",
|
||||
"Minor drizzle detected. No immediate impact on operations.",
|
||||
"Drizzle detected. Adjusting exterior temperature controls.",
|
||||
"Light rain confirmed. Surface conditions remain stable.",
|
||||
"Drizzle present. External activity unaffected.",
|
||||
"Micro-droplets detected. Surface wetting minimal.",
|
||||
"Drizzle increasing. Minimal disruption to operational efficiency.",
|
||||
"Light mist falling. Preparing exterior equipment for light moisture.",
|
||||
"Slight drizzle detected. Monitoring for potential buildup.",
|
||||
"Traces of rain observed. Surface conditioning proceeding normally.",
|
||||
"Faint drizzle. No significant effect on operational systems."
|
||||
};
|
||||
weatherState = generateTrendMessage(temperature, prevTemperature, "Temperature") + generateTrendMessage(pressure, prevPressure, "Atmospheric pressure") + generateTrendMessage(humidity, prevHumidity, "Humidity") + generateTrendMessage(wind_speed, prevWindSpeed, "Wind speed") + getRandomMessage(drizzleMessages, 15);
|
||||
} else if (mainWeather == "Thunderstorm") {
|
||||
String thunderstormMessages[] = {
|
||||
"Warning: Severe storm approaching. High-voltage hazard detected.",
|
||||
"Electrical storm detected in proximity. Shielding and surge protection engaged.",
|
||||
"Thunderstorm alert: Prepare for sudden power fluctuations.",
|
||||
"Storm in progress. Lightning detected. Surge protection active.",
|
||||
"Electrical interference detected. Recalibrating external sensors.",
|
||||
"Thunderstorm imminent. High-energy levels detected. Activating surge protocols.",
|
||||
"Power surge imminent. Warning: high-voltage storm detected.",
|
||||
"Electrical storm approaching. Brace for system disturbances.",
|
||||
"Warning: Lightning detected. Secure sensitive systems immediately.",
|
||||
"Severe atmospheric storm approaching. Power systems primed for protection.",
|
||||
"Lightning detected. Power surge prevention systems activated.",
|
||||
"Thunderstorm conditions intensifying. All external systems under review.",
|
||||
"Severe electrical interference. Adjusting system tolerance for spikes.",
|
||||
"Warning: Storm detected. Power fluctuations expected.",
|
||||
"Thunderstorm alert. Lightning strike imminent. Systems on full defense."
|
||||
};
|
||||
weatherState = generateTrendMessage(temperature, prevTemperature, "Temperature") + generateTrendMessage(pressure, prevPressure, "Atmospheric pressure") + generateTrendMessage(humidity, prevHumidity, "Humidity") + generateTrendMessage(wind_speed, prevWindSpeed, "Wind speed") + getRandomMessage(thunderstormMessages, 15);
|
||||
} else if (mainWeather == "Snow") {
|
||||
String snowMessages[] = {
|
||||
"Cryogenic conditions detected. Snowfall in progress.",
|
||||
"Snow accumulation imminent. External traction systems engaged.",
|
||||
"Freezing precipitation confirmed. Temperature control systems adjusting.",
|
||||
"Snow falling. Low-traction surfaces detected. Proceed with caution.",
|
||||
"Heavy snowfall recorded. Thermal systems operating at full capacity.",
|
||||
"Snowstorm imminent. Prepare for reduced external mobility.",
|
||||
"Temperature drop confirmed. Snow accumulation expected.",
|
||||
"Snow detected. De-icing systems online.",
|
||||
"Cryogenic particles in atmosphere. Surface stability compromised.",
|
||||
"Snowfall detected. All external movement restricted.",
|
||||
"Snow level increasing. Traction systems are in full effect.",
|
||||
"Blizzard conditions approaching. Prepare for limited visibility.",
|
||||
"Heavy snow confirmed. Adjusting exterior systems for extreme conditions.",
|
||||
"Low-temperature alert. Ice accumulation expected.",
|
||||
"Snowstorm detected. Proceed with extreme caution on external surfaces."
|
||||
};
|
||||
weatherState = generateTrendMessage(temperature, prevTemperature, "Temperature") + generateTrendMessage(pressure, prevPressure, "Atmospheric pressure") + generateTrendMessage(humidity, prevHumidity, "Humidity") + generateTrendMessage(wind_speed, prevWindSpeed, "Wind speed") + getRandomMessage(snowMessages, 15);
|
||||
} else if (mainWeather == "Mist" || mainWeather == "Fog") {
|
||||
String mistMessages[] = {
|
||||
"Low-visibility conditions. Activate infrared scanning systems.",
|
||||
"Fog detected. Navigation systems recalibrating for low-visibility operation.",
|
||||
"Atmospheric opacity confirmed. Proceed with caution at reduced speed.",
|
||||
"Dense mist detected. Visibility dropped to critical levels.",
|
||||
"Fog levels increasing. Adjusting pathfinding parameters for accuracy.",
|
||||
"Dense fog detected. Slowing navigation to safe speeds.",
|
||||
"Increased fog density. Visual systems recalibrated.",
|
||||
"Low visibility confirmed. Proceed with extreme caution.",
|
||||
"Mist detected in sector. Visual enhancement systems engaged.",
|
||||
"Fog detected. Reduced visibility affecting sensor accuracy.",
|
||||
"Thick fog detected. External systems recalibrating for safety.",
|
||||
"Reduced visibility confirmed. Navigating with extreme care.",
|
||||
"Mist conditions detected. Heightened caution in exterior operations.",
|
||||
"Fog rising in vicinity. Adjusting navigational parameters for safe course.",
|
||||
"Low-visibility conditions. Monitoring environment closely."
|
||||
};
|
||||
weatherState = generateTrendMessage(temperature, prevTemperature, "Temperature") + generateTrendMessage(pressure, prevPressure, "Atmospheric pressure") + generateTrendMessage(humidity, prevHumidity, "Humidity") + generateTrendMessage(wind_speed, prevWindSpeed, "Wind speed") + getRandomMessage(mistMessages, 15);
|
||||
} else {
|
||||
weatherState = generateTrendMessage(temperature, prevTemperature, "Temperature") + generateTrendMessage(pressure, prevPressure, "Atmospheric pressure") + generateTrendMessage(humidity, prevHumidity, "Humidity") + generateTrendMessage(wind_speed, prevWindSpeed, "Wind speed") + "Unspecified weather anomaly detected. Monitoring closely.";
|
||||
}
|
||||
prevTemperature = temperature;
|
||||
prevHumidity = humidity;
|
||||
prevPressure = pressure;
|
||||
prevWindSpeed = wind_speed;
|
||||
saveWeatherData();
|
||||
http.end();
|
||||
break;
|
||||
}
|
||||
@@ -245,7 +430,7 @@ bool fetchWeatherData() {
|
||||
|
||||
int scrollPos = SCREEN_WIDTH; // Global variable to keep track of the scroll position
|
||||
unsigned long lastScrollTime = 0; // To control the scroll speed
|
||||
const int scrollDelay = 30; // Delay in milliseconds between scroll updates
|
||||
const int scrollDelay = 80; // Delay in milliseconds between scroll updates
|
||||
|
||||
void displayWeatherData() {
|
||||
display.clearDisplay();
|
||||
@@ -264,7 +449,7 @@ void displayWeatherData() {
|
||||
if (!is_display_off) {
|
||||
if (millis() - lastScrollTime > scrollDelay) {
|
||||
// Update scroll position
|
||||
scrollPos -= 1; // Move left by 1 pixel each time
|
||||
scrollPos -= 5; // Move left by 1 pixel each time
|
||||
|
||||
lastScrollTime = millis();
|
||||
|
||||
@@ -280,20 +465,21 @@ void displayWeatherData() {
|
||||
display.print(weatherState);
|
||||
// Clear the area for "Time left" display before printing
|
||||
display.fillRect(0, 37, SCREEN_WIDTH, 27, BLACK); // Clear area for "Time left"
|
||||
display.setCursor(0, 40);
|
||||
display.setCursor(0, 44);
|
||||
display.setTextSize(1);
|
||||
display.printf(" %5.2f C %d%%\r\n", temperature, humidity);
|
||||
display.drawRect(43, 40, 3, 3, WHITE); // Degree symbol
|
||||
display.drawRect(43, 44, 3, 3, WHITE); // Degree symbol
|
||||
|
||||
display.setCursor(0, 52);
|
||||
display.setCursor(0, 55);
|
||||
display.printf(" %.3fbar %.1fm/s \r\n", pressure, wind_speed);
|
||||
display.drawLine(0, 18, 127, 18, 1);
|
||||
display.drawLine(65, 18, 65, 0, 1);
|
||||
|
||||
display.drawBitmap(0, 38, temperature_icon, 10, 10, WHITE);
|
||||
display.drawBitmap(74, 38, humidity_icon, 10, 10, WHITE);
|
||||
display.drawBitmap(0, 51, pressure_icon, 10, 10, WHITE);
|
||||
display.drawBitmap(74, 51, wind_icon, 10, 10, WHITE);
|
||||
display.drawLine(0, 40, 127, 40, 1);
|
||||
|
||||
display.drawBitmap(0, 42, temperature_icon, 10, 10, WHITE);
|
||||
display.drawBitmap(74, 42, humidity_icon, 10, 10, WHITE);
|
||||
display.drawBitmap(0, 54, pressure_icon, 10, 10, WHITE);
|
||||
display.drawBitmap(74, 54, wind_icon, 10, 10, WHITE);
|
||||
|
||||
int pos = 69;
|
||||
for (int i = 0; i < 3; i++) {
|
||||
@@ -309,6 +495,7 @@ void setup(void) {
|
||||
netman.start();
|
||||
timeClient.begin();
|
||||
timeClient.update();
|
||||
loadWeatherData();
|
||||
fetchWeatherData();
|
||||
}
|
||||
|
||||
@@ -323,6 +510,7 @@ void loop() {
|
||||
if (!is_display_off && (millis() - lastWeatherUpdate > weatherUpdateInterval)) {
|
||||
fetchWeatherData();
|
||||
lastWeatherUpdate = millis();
|
||||
scrollPos = SCREEN_WIDTH;
|
||||
}
|
||||
powerSaveCheck();
|
||||
}
|
||||
|
Reference in New Issue
Block a user