WKHarmon / led-sectional

MIT License
35 stars 20 forks source link

cannot get over 54 airports to load. #29

Closed jbilleaudeaux closed 6 months ago

jbilleaudeaux commented 6 months ago

Map is up and running fine with 54 airports and less. When I add more than 55 airports I get an exception code 28 in the stack and it keeps on scrolling over and over infinitely. LEDS switch amber to magenta and back. Hoping to locate the issue as I'd like to build a US map. Thanks so much for the help in advance

Versions are 2.74 esp8266 Board is a ESP8266 ESP-12E CP2102 NodeMCU Lua fast LED 3.3 Wifi Manager 2.016-rc2 tzapu.

Here is the code some airports randomly added at the end, just to see. Airport names are incorrect.

ERROR CODE COPIED AT THE BOTTOM

include

include // IMPORTANT USE FASTLED V3.4 ONLY

include

include // https://github.com/tzapu/WiFiManager

using namespace std;

define FASTLED_ESP8266_RAW_PIN_ORDER

define NUM_AIRPORTS 57 // This is really the number of LEDs

define WIND_THRESHOLD 25 // 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 180000 // How often we update. In practice LOOP_INTERVAL is added. In ms (5 min is 300000)

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

// WIFI Management for ESP8266 WiFiManager wm;

define WIFI_TIMEOUT 120 // in seconds

// Parameters for ESP8266 access point

define ESP_WIFI_SSID "METAR Map"

define ESP_WIFI_PASSWORD "123456789"

// 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 WS2812B

define COLOR_ORDER GRB

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({ "KNRS", // 1 IMPERIAL BEACH "KSDM", // 2 BROWN "KNZY", // 3 EL CENTRO "KSAN", // 4 IMPERIAL "KMYF", // 5 BORREGO "KSEE", // 6 RAMONA "KRNM", // 7 GILLESPIE "KNKX", // 8 NORTH ISLAND "KCRQ", // 9 SAN DIEGO "KOKB", // 10 MONTGOMERY "KNFG", // 11 MIRAMAR "KL18", // 12 PALOMAR "KF70", // 13 OCEANSIDE "KL08", // 14 FALLBROOK "KNJK", // 15 FRENCH VALLEY "KIPL", // 16 HEMET "KTRM", // 17 PALM SPRINGS "KPSP", // 18 THERMAL "KHMT", // 19 BIG BEAR "KRIV", // 20 MARCH "KRAL", // 21 SAN BERNARDINO "KAJO", // 22 RIVERSIDE "KCNO", // 23 JOHN WAYNE "KSBD", // 24 CATALINA "KONT", // 25 TORRANCE "KCCB", // 26 LONG BEACH "KPOC", // 27 LOS ALAMITOS NWS "KEMT", // 28 FULLERTON "KSNA", // 29 CORONA "KAVX", // 30 CHINO "KTOA", // 31 ONTARIO "KLGB", // 32 CABLE "KSLI", // 33 BRACKETT "KFUL", // 34 EL MONTE "KHHR", // 35 HAWTHORNE "KLAX", // 36 LOS ANGELES "KSMO", // 37 BURBANK "KBUR", // 38 WHITEMAN "KWHP", // 39 VAN NUYS "KVNY", // 40 SANTA MONICA "KNTD", // 41 CAMARILLO "KCMA", // 42 OXNARD "KOXR", // 43 SANTA BARBARA "KSBA", // 44 SANDBERG "KTSP", // 45 TEHACHAPI "KWJF", // 46 FOX FIELD "KPMD", // 47 MOJAVE "KMHV", // 48 PALMDALE "KEDW", // 49 EDWARDS "K9L2", // 50 GRAY BUTTE "KVCV", // 51 VICTORVILLE "KL35", // 52 DAGGETT "KDAG", "KTNP", "KNFG", "KSBD", "KRDG"

});

define DEBUG false

define READ_TIMEOUT 15 // Cancel query if no data received (seconds)

define RETRY_TIMEOUT 15000 // in ms

define SERVER "aviationweather.gov"

define BASE_URI "/cgi-bin/data/dataserver.php?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() {

Serial.begin(9600);

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); wm.setConfigPortalTimeout(WIFI_TIMEOUT); } if(wm.autoConnect(ESP_WIFI_SSID,ESP_WIFI_PASSWORD)){ Serial.println("Connected to local network"); if (ledStatus) fill_solid(leds, NUM_AIRPORTS, CRGB::Purple); // indicate status with LEDs FastLED.show(); ledStatus = false; } else { Serial.println("Failed to connect to local network or hit timeout"); fill_solid(leds, NUM_AIRPORTS, CRGB::Orange); FastLED.show(); ledStatus = true; return; }

// 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(); }

Serial.println("Getting METARs ...");
if (getMetars()) {
  Serial.println("Refreshing LEDs.");
  FastLED.show();
  if ((DO_LIGHTNING && lightningLeds.size() > 0) || USE_LIGHT_SENSOR) {
    Serial.println("There is lightning or we're using a light sensor, so no long sleep.");
    digitalWrite(LED_BUILTIN, HIGH);
    delay(LOOP_INTERVAL); // pause during the interval
  } else {
    Serial.print("No lightning; Going into sleep for: ");
    Serial.println(REQUEST_INTERVAL);
    digitalWrite(LED_BUILTIN, HIGH);
    delay(REQUEST_INTERVAL);
  }
} else {
  digitalWrite(LED_BUILTIN, HIGH);
  delay(RETRY_TIMEOUT); // try again if unsuccessful
}

} 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]; } }

BearSSL::WiFiClientSecure client; client.setInsecure(); Serial.println("\nStarting connection to server..."); // if you get a connection, report back via serial: if (!client.connect(SERVER, 443)) { 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();

Serial.print("Getting data");

while (!client.connected()) {
  if ((millis() - t) >= (READ_TIMEOUT * 1000)) {
    Serial.println("---Timeout---");
    client.stop();
    return false;
  }
  Serial.print(".");
  delay(1000);
}

Serial.println();

while (client.connected()) {
  if ((c = client.read()) >= 0) {
    yield(); // Otherwise the WiFi stack can crash
    currentLine += c;
    if (c == '\n') currentLine = "";
    if (currentLine.endsWith("<station_id>")) { // start paying attention
      if (!led.empty()) { // we assume we are recording results at each change in airport
        for (vector<unsigned short int>::iterator it = led.begin(); it != led.end(); ++it) {
          doColor(currentAirport, *it, currentWind.toInt(), currentGusts.toInt(), currentCondition, currentWxstring);
        }
        led.clear();
      }
      currentAirport = ""; // Reset everything when the airport changes
      readingAirport = true;
      currentCondition = "";
      currentWind = "";
      currentGusts = "";
      currentWxstring = "";
    } else if (readingAirport) {
      if (!currentLine.endsWith("<")) {
        currentAirport += c;
      } else {
        readingAirport = false;
        for (unsigned short int i = 0; i < NUM_AIRPORTS; i++) {
          if (airports[i] == currentAirport) {
            led.push_back(i);
          }
        }
      }
    } else if (currentLine.endsWith("<wind_speed_kt>")) {
      readingWind = true;
    } else if (readingWind) {
      if (!currentLine.endsWith("<")) {
        currentWind += c;
      } else {
        readingWind = false;
      }
    } else if (currentLine.endsWith("<wind_gust_kt>")) {
      readingGusts = true;
    } else if (readingGusts) {
      if (!currentLine.endsWith("<")) {
        currentGusts += c;
      } else {
        readingGusts = false;
      }
    } else if (currentLine.endsWith("<flight_category>")) {
      readingCondition = true;
    } else if (readingCondition) {
      if (!currentLine.endsWith("<")) {
        currentCondition += c;
      } else {
        readingCondition = false;
      }
    } else if (currentLine.endsWith("<wx_string>")) {
      readingWxstring = true;
    } else if (readingWxstring) {
      if (!currentLine.endsWith("<")) {
        currentWxstring += c;
      } else {
        readingWxstring = false;
      }
    }
    t = millis(); // Reset timeout clock
  } else if ((millis() - t) >= (READ_TIMEOUT * 1000)) {
    Serial.println("---Timeout---");
    fill_solid(leds, NUM_AIRPORTS, CRGB::Cyan); // indicate status with LEDs
    FastLED.show();
    ledStatus = true;
    client.stop();
    return false;
  }
}

} // 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; }


ERROR CODE

09:07:49.630 -> wm:9 networks found 09:08:07.331 -> wm:Connecting to NEW AP: Geaux Tigers 09:08:07.449 -> wm:connectTimeout not set, ESP waitForConnectResult... 09:08:14.360 -> wm:Connect to new AP [SUCCESS] 09:08:14.421 -> wm:Got IP Address: 09:08:14.423 -> wm:192.168.86.31 09:08:15.371 -> *wm:config portal exiting 09:08:15.403 -> Connected to local network 09:08:15.435 -> Getting METARs ... 09:08:15.468 -> 09:08:15.468 -> --------------- CUT HERE FOR EXCEPTION DECODER --------------- 09:08:15.531 -> 09:08:15.531 -> Exception (28): 09:08:15.531 -> epc1=0x4000bdc8 epc2=0x00000000 epc3=0x00000000 excvaddr=0x00000000 depc=0x00000000 09:08:15.627 -> 09:08:15.627 -> >>>stack>>> 09:08:15.659 -> 09:08:15.659 -> ctx: cont 09:08:15.659 -> sp: 3ffffc30 end: 3fffffc0 offset: 0190 09:08:15.692 -> 3ffffdc0: 3fff2544 3ffffde0 000002c4 402107c8
09:08:15.755 -> 3ffffdd0: 3ffffed0 3ffeeec8 000002d0 40201ae7
09:08:15.820 -> 3ffffde0: 3fff2500 011f011f 80002c4d 40212a19
09:08:15.851 -> 3ffffdf0: 3ffe8b4f 00000000 3a6d772a 40212a19
09:08:15.916 -> 3ffffe00: 3ffef19c 00000003 3ffffe40 40267e30
09:08:15.947 -> 3ffffe10: 4020f704 3ffef2ac 3ffe8b4d 4020f710
09:08:16.011 -> 3ffffe20: 4020f704 3ffef2ac 3ffe8b4d 4020faf9
09:08:16.075 -> 3ffffe30: 00000002 3ffe8a51 3ffef00c 4020fbf4
09:08:16.107 -> 3ffffe40: 00000002 3ffe8a51 3ffef00c 402079f3
09:08:16.171 -> 3ffffe50: 1f56a8c0 00ffffff 40215438 3ffef0b4
09:08:16.236 -> 3ffffe60: 00000003 3ffef10c 3ffef00c 4020e6e8
09:08:16.268 -> 3ffffe70: 3ffef10c 1f56a8c0 80000001 3fff1c00
09:08:16.331 -> 3ffffe80: ac2ed120 80fef10c 3ffef00c 3ffe892c
09:08:16.395 -> 3ffffe90: 00000000 00000001 3ffef00c 00000063
09:08:16.427 -> 3ffffea0: 00000014 00000002 3ffffee0 40201824
09:08:16.491 -> 3ffffeb0: 3ffef00c 00000064 00000000 00000000
09:08:16.523 -> 3ffffec0: 0d140000 80fe0312 00000000 000b000f
09:08:16.587 -> 3ffffed0: 3fff20f4 011f011f 09fe004d 40201900
09:08:16.651 -> 3ffffee0: 3ffeeee0 80000064 00000000 00000000
09:08:16.684 -> 3ffffef0: 80fe8b4f 00000000 000a0d78 80212a19
09:08:16.748 -> 3fffff00: 3ffe8b00 00000000 802e2e20 40212a00
09:08:16.811 -> 3fffff10: 3ffe89a8 80000000 80000000 3ffe84d0
09:08:16.844 -> 3fffff20: 8020f704 00000000 00000000 00000000
09:08:16.907 -> 3fffff30: 4020f704 3ffef2ac 3ffe8b4d 4020faf9
09:08:16.939 -> 3fffff40: 00000000 00000012 3ffef2ac 4020fbf4
09:08:17.003 -> 3fffff50: 3ffef270 3ffeeed4 3ffef2ac 3ffe84d0
09:08:17.068 -> 3fffff60: 3ffef270 3ffeeed4 3ffef2ac 402022f8
09:08:17.100 -> 3fffff70: 00800080 feefeffe 3ffeee9c 40206309
09:08:17.163 -> 3fffff80: 00002580 00000000 00000002 3ffef3ec
09:08:17.227 -> 3fffff90: 3ffeeec0 00000000 3ffeee9c 3ffef3ec
09:08:17.259 -> 3fffffa0: 3fffdad0 00000000 3ffef3ac 40211c1c
09:08:17.324 -> 3fffffb0: feefeffe feefeffe 3ffe84ec 40100f2d 09:08:17.355 -> <<<stack<<< 09:08:17.387 -> 09:08:17.387 -> --------------- CUT HERE FOR EXCEPTION DECODER ---------------

jbilleaudeaux commented 6 months ago

ended up re-installing ESP8266 libraries and put in 2.74 with 58 LEDS and its working properly now. Also put 1st light as "NULL" . Seems to have fixed it.