Open Tapity04 opened 2 years ago
Are you running with the serial monitor?
You should be seeing the stations update with the parsed data-
WiFi connecting.......OK! Getting METARs ...
Starting connection to server... Connected ... GET /adds/dataserver_current/httpparam?dataSource=metars&requestType=retrieve&format=xml&hoursBeforeNow=3&mostRecentForEachStation=true&stationString=KIKV,KARB,KTNU,KDTW HTTP/1.1 Host: www.aviationweather.gov User-Agent: LED Map Client Connection: close
Getting data KTNU: MVFR 16G21kts LED 14 WX: KIKV: IFR 8G17kts LED 12 WX: -SN KARB: LIFR 6G0kts LED 13 WX: BR KDTW: IFR 11G17kts LED 50 WX:
knowing if you are getting that data output in the serial monitor would help you understand if you have a problem parsing the response from the server or something with the calls to update the LED states.
Hi, WKHarmon, really liked your code, but im struggling to update it to be ESP32 "friendly"
At the moment my changes were:
Right now my worst nightmare is the GET from aviationweather.gov, the query is being sent but the data received is not being decoded. Only the "default" leds are lightning up (VFR, IFR, etc.)
Here's the editted code if there's something weird looking `#include
include
include
using namespace std;
define FASTLED_ESP8266_RAW_PIN_ORDER
define NUM_AIRPORTS 5 // This is really the number of LEDs
define WIND_THRESHOLD 30 // Maximum windspeed for green, otherwise the LED turns yellow
define LOOP_INTERVAL 5000 // ms - interval between brightness updates and lightning strikes
define DO_LIGHTNING true // Lightning uses more power, but is cool.
define DO_WINDS true // color LEDs for high winds
define REQUEST_INTERVAL 900000 // How often we update. In practice LOOP_INTERVAL is added. In ms (15 min is 900000)
define USE_LIGHT_SENSOR false // Set USE_LIGHT_SENSOR to true if you're using any light sensor.
// Set LIGHT_SENSOR_TSL2561 to true if you're using a TSL2561 digital light sensor. // Kits shipped after March 1, 2019 have a digital light sensor. Setting this to false assumes an analog light sensor.
define LIGHT_SENSOR_TSL2561 false
const char ssid[] = "MySsid"; // your network SSID (name) const char pass[] = "MyVerySecurePassword"; // your network password (use for WPA, or use as key for WEP)
// Define the array of leds CRGB leds[NUM_AIRPORTS];
define DATA_PIN 5 // Kits shipped after March 1, 2019 should use 14. Earlier kits us 5.
define LED_TYPE WS2811
define COLOR_ORDER RGB
define BRIGHTNESS 20 // 20-30 recommended. If using a light sensor, this is the initial brightness on boot.
/ This section only applies if you have an ambient light sensor connected /
if USE_LIGHT_SENSOR
/ The sketch will automatically scale the light between MIN_BRIGHTNESS and MAX_BRIGHTNESS on the ambient light values between MIN_LIGHT and MAX_LIGHT Set MIN_BRIGHTNESS and MAX_BRIGHTNESS to the same value to achieve a simple on/off effect. /
define MIN_BRIGHTNESS 20 // Recommend values above 4 as colors don't show well below that
define MAX_BRIGHTNESS 20 // Recommend values between 20 and 30
// Light values are a raw reading for analog and lux for digital
define MIN_LIGHT 16 // Recommended default is 16 for analog and 2 for lux
define MAX_LIGHT 30 // Recommended default is 30 to 40 for analog and 20 for lux
if LIGHT_SENSOR_TSL2561
include
include
include
Adafruit_TSL2561_Unified tsl = Adafruit_TSL2561_Unified(TSL2561_ADDR_FLOAT, 12345);
else
define LIGHTSENSORPIN A0 // A0 is the only valid pin for an analog light sensor
endif
endif
/ ----------------------------------------------------------------------- /
std::vector lightningLeds;
std::vector airports({
"LIFR", // 1 order of LEDs, starting with 1 should be KKIC; use VFR, WVFR, MVFR, IFR, LIFR for key; NULL for no airport
"IFR", // 2
"MVFR", // 3
"WVFR", // 4
"VFR", // 5
"SAEZ", // 6
"SADF", // 7
"SAAR", // 8
"SAZM", // 9
"KCVH", // 10
"KWVI", // 11
"KE16", // 12
"SABE" // 80 I limited the number of airports trying to find if the big quantity of airports affected the GET
});
define DEBUG true
define READ_TIMEOUT 15 // Cancel query if no data received (seconds)
define WIFI_TIMEOUT 60 // in seconds
define RETRY_TIMEOUT 15000 // in ms
define SERVER "www.aviationweather.gov"
define BASE_URI "/adds/dataserver_current/httpparam?dataSource=metars&requestType=retrieve&format=xml&hoursBeforeNow=3&mostRecentForEachStation=true&stationString="
boolean ledStatus = true; // used so leds only indicate connection status on first boot, or after failure int loops = -1;
int status = WL_IDLE_STATUS;
void setup() { //Initialize serial and wait for port to open: Serial.begin(74880); //pinMode(D1, OUTPUT); //Declare Pin mode //while (!Serial) { // ; // wait for serial port to connect. Needed for native USB //}
pinMode(LED_BUILTIN, OUTPUT); // give us control of the onboard LED digitalWrite(LED_BUILTIN, LOW);
if USE_LIGHT_SENSOR
if LIGHT_SENSOR_TSL2561
Wire.begin(D2, D1); if(!tsl.begin()) { / There was a problem detecting the TSL2561 ... check your connections / Serial.println("Ooops, no TSL2561 detected ... Check your wiring or I2C ADDR!"); } else { tsl.enableAutoRange(true); tsl.setIntegrationTime(TSL2561_INTEGRATIONTIME_13MS); }
else
pinMode(LIGHTSENSORPIN, INPUT);
endif
endif
// Initialize LEDs FastLED.addLeds<LED_TYPE, DATA_PIN, COLOR_ORDER>(leds, NUM_AIRPORTS).setCorrection(TypicalLEDStrip); FastLED.setBrightness(BRIGHTNESS); }
if USE_LIGHT_SENSOR
void adjustBrightness() { unsigned char brightness; float reading;
if LIGHT_SENSOR_TSL2561
sensors_event_t event; tsl.getEvent(&event); reading = event.light;
else
reading = analogRead(LIGHTSENSORPIN);
endif
Serial.print("Light reading: "); Serial.print(reading); Serial.print(" raw, ");
if (reading <= MIN_LIGHT) brightness = 0; else if (reading >= MAX_LIGHT) brightness = MAX_BRIGHTNESS; else { // Percentage in lux range brightness range + min brightness float brightness_percent = (reading - MIN_LIGHT) / (MAX_LIGHT - MIN_LIGHT); brightness = brightness_percent (MAX_BRIGHTNESS - MIN_BRIGHTNESS) + MIN_BRIGHTNESS; }
Serial.print(brightness); Serial.println(" brightness"); FastLED.setBrightness(brightness); FastLED.show(); }
endif
void loop() { digitalWrite(LED_BUILTIN, LOW); // on if we're awake
if USE_LIGHT_SENSOR
adjustBrightness();
endif
int c; loops++; Serial.print("Loop: "); Serial.println(loops); unsigned int loopThreshold = 1; if (DO_LIGHTNING || USE_LIGHT_SENSOR) loopThreshold = REQUEST_INTERVAL / LOOP_INTERVAL;
// Connect to WiFi. We always want a wifi connection for the ESP8266 if (WiFi.status() != WL_CONNECTED) { if (ledStatus) fill_solid(leds, NUM_AIRPORTS, CRGB::Orange); // indicate status with LEDs, but only on first run or error FastLED.show(); WiFi.mode(WIFI_STA); WiFi.hostname("LED Sectional " + WiFi.macAddress()); //wifi_set_sleep_type(LIGHT_SLEEP_T); // use light sleep mode for all delays Serial.print("WiFi connecting.."); WiFi.begin(ssid, pass); // Wait up to 1 minute for connection... for (c = 0; (c < WIFI_TIMEOUT) && (WiFi.status() != WL_CONNECTED); c++) { Serial.write('.'); delay(1000); } if (c >= WIFI_TIMEOUT) { // If it didn't connect within WIFI_TIMEOUT Serial.println("Failed. Will retry..."); fill_solid(leds, NUM_AIRPORTS, CRGB::Orange); FastLED.show(); ledStatus = true; return; } Serial.println("OK!"); if (ledStatus) fill_solid(leds, NUM_AIRPORTS, CRGB::Purple); // indicate status with LEDs FastLED.show(); ledStatus = false; }
// Do some lightning if (DO_LIGHTNING && lightningLeds.size() > 0) { std::vector lightning(lightningLeds.size());
for (unsigned short int i = 0; i < lightningLeds.size(); ++i) {
unsigned short int currentLed = lightningLeds[i];
lightning[i] = leds[currentLed]; // temporarily store original color
leds[currentLed] = CRGB::White; // set to white briefly
Serial.print("Lightning on LED: ");
Serial.println(currentLed);
}
delay(25); // extra delay seems necessary with light sensor
FastLED.show();
delay(25);
for (unsigned short int i = 0; i < lightningLeds.size(); ++i) {
unsigned short int currentLed = lightningLeds[i];
leds[currentLed] = lightning[i]; // restore original color
}
FastLED.show();
}
if (loops >= loopThreshold || loops == 0) { loops = 0; if (DEBUG) { fill_gradient_RGB(leds, NUM_AIRPORTS, CRGB::Red, CRGB::Blue); // Just let us know we're running FastLED.show(); }
} else { digitalWrite(LED_BUILTIN, HIGH); delay(LOOP_INTERVAL); // pause during the interval } }
bool getMetars(){ lightningLeds.clear(); // clear out existing lightning LEDs since they're global fill_solid(leds, NUM_AIRPORTS, CRGB::Black); // Set everything to black just in case there is no report uint32_t t; char c; boolean readingAirport = false; boolean readingCondition = false; boolean readingWind = false; boolean readingGusts = false; boolean readingWxstring = false;
std::vector led;
String currentAirport = "";
String currentCondition = "";
String currentLine = "";
String currentWind = "";
String currentGusts = "";
String currentWxstring = "";
String airportString = "";
bool firstAirport = true;
for (int i = 0; i < NUM_AIRPORTS; i++) {
if (airports[i] != "NULL" && airports[i] != "VFR" && airports[i] != "MVFR" && airports[i] != "WVFR" && airports[i] != "IFR" && airports[i] != "LIFR") {
if (firstAirport) {
firstAirport = false;
airportString = airports[i];
} else airportString = airportString + "," + airports[i];
}
}
WiFiClient client; Serial.println("\nStarting connection to server..."); // if you get a connection, report back via serial: if (!client.connect(SERVER, 80)) { Serial.println("Connection failed!"); client.stop(); return false; } else { Serial.println("Connected ..."); Serial.print("GET "); Serial.print(BASE_URI); Serial.print(airportString); Serial.println(" HTTP/1.1"); Serial.print("Host: "); Serial.println(SERVER); Serial.println("User-Agent: LED Map Client"); Serial.println("Connection: close"); Serial.println(); // Make a HTTP request, and print it to console: client.print("GET "); client.print(BASE_URI); client.print("airportString"); client.println(" HTTP/1.1"); client.print("Host: "); client.println(SERVER); client.println("User-Agent: LED Sectional Client"); client.println("Connection: close"); client.println(); client.flush(); t = millis(); // start time FastLED.clear();
} // need to doColor this for the last airport for (vector::iterator it = led.begin(); it != led.end(); ++it) {
doColor(currentAirport, *it, currentWind.toInt(), currentGusts.toInt(), currentCondition, currentWxstring);
}
led.clear();
// Do the key LEDs now if they exist for (int i = 0; i < (NUM_AIRPORTS); i++) { // Use this opportunity to set colors for LEDs in our key then build the request string if (airports[i] == "VFR") leds[i] = CRGB::Green; else if (airports[i] == "WVFR") leds[i] = CRGB::Yellow; else if (airports[i] == "MVFR") leds[i] = CRGB::Blue; else if (airports[i] == "IFR") leds[i] = CRGB::Red; else if (airports[i] == "LIFR") leds[i] = CRGB::Magenta; }
client.stop(); return true; }
void doColor(String identifier, unsigned short int led, int wind, int gusts, String condition, String wxstring) { CRGB color; Serial.print(identifier); Serial.print(": "); Serial.print(condition); Serial.print(" "); Serial.print(wind); Serial.print("G"); Serial.print(gusts); Serial.print("kts LED "); Serial.print(led); Serial.print(" WX: "); Serial.println(wxstring); if (wxstring.indexOf("TS") != -1) { Serial.println("... found lightning!"); lightningLeds.push_back(led); } if (condition == "LIFR" || identifier == "LIFR") color = CRGB::Magenta; else if (condition == "IFR") color = CRGB::Red; else if (condition == "MVFR") color = CRGB::Blue; else if (condition == "VFR") { if ((wind > WIND_THRESHOLD || gusts > WIND_THRESHOLD) && DO_WINDS) { color = CRGB::Yellow; } else { color = CRGB::Green; } } else color = CRGB::Black;
leds[led] = color; }`
Thanks a lot and sorry for the inconvenience