#include #include #include #include #include #include #include #include #define STATION_UID "93" // location id #define HOST "bici.lbsfilm.at" #define REFRESH 1000 #define CHANGE_MODE 10000 #define OFFSET 1 #define SEGLEN 5 // SegmentLength #define SEPLEN 2 // SeperatorLength #define NUM_LEDS 142 //SEGLEN * 4 * 7 + 2 #define DATA_PIN D5 // Data pin for led comunication Adafruit_NeoPixel clock = Adafruit_NeoPixel(NUM_LEDS, DATA_PIN, NEO_GRB + NEO_KHZ800); byte digits[12][7] = { { 0, 1, 1, 1, 1, 1, 1 }, // Digit 0 { 0, 1, 0, 0, 0, 0, 1 }, // Digit 1 { 1, 1, 1, 0, 1, 1, 0 }, // Digit 2 { 1, 1, 1, 0, 0, 1, 1 }, // Digit 3 { 1, 1, 0, 1, 0, 0, 1 }, // Digit 4 { 1, 0, 1, 1, 0, 1, 1 }, // Digit 5 { 1, 0, 1, 1, 1, 1, 1 }, // Digit 6 { 0, 1, 1, 0, 0, 0, 1 }, // Digit 7 { 1, 1, 1, 1, 1, 1, 1 }, // Digit 8 { 1, 1, 1, 1, 0, 1, 1 }, // Digit 9 { 1, 1, 1, 1, 0, 0, 0 }, // Digit *0 { 0, 0, 1, 1, 1, 1, 0 } // Digit C }; long oldTime = 0; // for refresh long oldModeTime = 0; // for mode String bicislots = ""; String bicis = ""; String hours = ""; String minutes = ""; char stationId[6] = "93"; bool displayOn = false; #define TIME 0 #define BICIS 1 unsigned int displayMode = TIME; //flag for saving data bool shouldSaveConfig = false; //callback notifying us of the need to save config /* void saveConfigCallback () { Serial.println("Should save config"); shouldSaveConfig = true; } */ void setup() { Serial.begin(115200); //EEPROM.begin(512); //stationId = EEPROM.read(25); WiFiManagerParameter custom_station_id("server", "station id", stationId, 6); WiFiManager wifiManager; //wifiManager.setSaveConfigCallback(saveConfigCallback); wifiManager.autoConnect("ConfigureClock"); wifiManager.addParameter(&custom_station_id); Serial.println(custom_station_id.getValue()); if (shouldSaveConfig) { Serial.println("saving config"); //EEPROM.write(25); } clock.begin(); clock.show(); // Initialize all pixels to 'off' colon(clock.Color(255, 255, 255)); delay(1000); colorWipe( clock.Color(0, 100, 150), 10); colorWipe( clock.Color(0, 0, 0), 5); //displayNumber("99:99", clock.Color(150, 150, 150)); //countUp( clock.Color(0, 100, 150), 100); } void loop() // Main loop { // Check motion sensor // get data and time displayOn = digitalRead(D7); //displayOn = true; if (millis() - oldModeTime > CHANGE_MODE) { if (displayMode == TIME) displayMode = BICIS; else displayMode = TIME; oldModeTime = millis(); } if (millis() - oldTime > REFRESH) { getData(); switch (displayMode) { case TIME: { uint32_t c = clock.Color(100, 100, 130); if (displayOn) displayNumber(hours + ":" + minutes, c); else colorWipe( clock.Color(0, 0, 0), 1); break; } case BICIS: { uint32_t cSlots = clock.Color(100, 0, 0); uint32_t cBicis = clock.Color(0, 100, 0); if (displayOn) display2Numbers(bicislots, bicis, cSlots, cBicis ); else colorWipe( clock.Color(0, 0, 0), 1); break; } } Serial.println(hours + ":" + minutes); } } void getData() { HTTPClient https; String URL = "https://" + String(HOST) + "/stations?stationId=" + String(STATION_UID); Serial.println(URL); https.begin( URL, "20:0F:86:A4:96:D4:40:EF:28:03:C4:36:B7:B5:F2:C3:55:42:E7:51"); //HTTPS int httpCode = https.GET(); if (httpCode > 0) { // HTTP header has been send and Server response header has been handled Serial.printf("[HTTP] GET... code: %d\n", httpCode); // file found at server if (httpCode == HTTP_CODE_OK) { String payload = https.getString(); Serial.println(payload); // Compute optimal size of the JSON buffer according to what we need to parse. // See https://bblanchon.github.io/ArduinoJson/assistant/ // Allocate a temporary memory pool DynamicJsonBuffer jsonBuffer(650); JsonObject& root = jsonBuffer.parseObject(payload); if (!root.success()) { Serial.println("JSON parsing failed!"); return; } Serial.println("JSON parsing SUCCEDED!"); const char* bicislotsChar = root["empty_slots"]; bicislots = String(bicislotsChar); const char* bicisChar = root["free_bikes"]; bicis = String(bicisChar); const char* hoursChar = root["time"]["hours"]; hours = String(hoursChar); const char* minutesChar = root["time"]["minutes"]; minutes = String(minutesChar); int offsetting = hours.toInt(); offsetting = offsetting + OFFSET; if (offsetting == 24) offsetting = 0; if (offsetting < 10) hours = "0" + String(offsetting, DEC); else hours = String(offsetting, DEC); } } else { Serial.printf("[HTTP] GET... failed, error: %s\n", https.errorToString(httpCode).c_str()); } https.end(); oldTime = millis(); } /* LED FX */ // Fill the dots one after the other with a color void colorWipe(uint32_t c, uint8_t wait) { for (uint16_t i = 0; i < clock.numPixels(); i++) { clock.setPixelColor(i, c); clock.show(); delay(wait); } } void rainbow(uint8_t wait) { uint16_t i, j; for (j = 0; j < 256; j++) { for (i = 0; i < clock.numPixels(); i++) { clock.setPixelColor(i, Wheel((i + j) & 255)); } clock.show(); delay(wait); } } // Slightly different, this makes the rainbow equally distributed throughout void rainbowCycle(uint8_t wait) { uint16_t i, j; for (j = 0; j < 256 * 5; j++) { // 5 cycles of all colors on wheel for (i = 0; i < clock.numPixels(); i++) { clock.setPixelColor(i, Wheel(((i * 256 / clock.numPixels()) + j) & 255)); } clock.show(); delay(wait); } } //Theatre-style crawling lights. void theaterChase(uint32_t c, uint8_t wait) { for (int j = 0; j < 10; j++) { //do 10 cycles of chasing for (int q = 0; q < 3; q++) { for (uint16_t i = 0; i < clock.numPixels(); i = i + 3) { clock.setPixelColor(i + q, c); //turn every third pixel on } clock.show(); delay(wait); for (uint16_t i = 0; i < clock.numPixels(); i = i + 3) { clock.setPixelColor(i + q, 0); //turn every third pixel off } } } } //Theatre-style crawling lights with rainbow effect void theaterChaseRainbow(uint8_t wait) { for (int j = 0; j < 256; j++) { // cycle all 256 colors in the wheel for (int q = 0; q < 3; q++) { for (uint16_t i = 0; i < clock.numPixels(); i = i + 3) { clock.setPixelColor(i + q, Wheel( (i + j) % 255)); //turn every third pixel on } clock.show(); delay(wait); for (uint16_t i = 0; i < clock.numPixels(); i = i + 3) { clock.setPixelColor(i + q, 0); //turn every third pixel off } } } } // Input a value 0 to 255 to get a color value. // The colours are a transition r - g - b - back to r. uint32_t Wheel(byte WheelPos) { WheelPos = 255 - WheelPos; if (WheelPos < 85) { return clock.Color(255 - WheelPos * 3, 0, WheelPos * 3); } if (WheelPos < 170) { WheelPos -= 85; return clock.Color(0, WheelPos * 3, 255 - WheelPos * 3); } WheelPos -= 170; return clock.Color(WheelPos * 3, 255 - WheelPos * 3, 0); } // ############### The LED Strip handling ################### void displayNumber(String string, uint32_t color) { for (int i = 0; i < 4; i++) { if (i < 2) fillNumber(i, string[i] - 48, color); else fillNumber(i, string[i + 1] - 48, color); } if (string[2] == ':') colon(color); else nocolon(); } void display2Numbers(String string, String string2, uint32_t color, uint32_t color2 ) { for (int i = 0; i < 2; i++) { fillNumber(i, string[i] - 48, color); } for (int i = 0; i < 2; i++) { fillNumber(i + 2, string2[i] - 48, color2); } nocolon(); } void noclock() { for (int led = 0; led < clock.numPixels(); led++) { clock.setPixelColor(led, 0); } clock.show(); } void colon(uint32_t color) { for (int led = 0; led < SEPLEN; led++) { int currentLed = SEGLEN * 14 + led; clock.setPixelColor(currentLed, color); } clock.show(); } void nocolon() { for (int led = 0; led < SEPLEN; led++) { int currentLed = SEGLEN * 14 + led; clock.setPixelColor(currentLed, 0); } clock.show(); } void fillNumber(int position, int digit, uint32_t color) { int offset = 0; if (position > 3)return; if (position < 0)return; if (position > 1) offset = SEPLEN; for (int seg = 0; seg < 7; seg++) { for (int led = 0; led < SEGLEN; led++) { int currentLed = position * 5 * 7 + seg * 5 + led + offset; if (digits[digit][seg] == 1) { clock.setPixelColor(currentLed, color); } else { clock.setPixelColor(currentLed, clock.Color(0, 0, 0)); } } } } void countUp(uint32_t color, int wait) { fillNumber(0, 8, clock.Color(0, 0, 0)); for (int num3 = 0; num3 < 10; num3++) { fillNumber(1, num3, color); for (int num2 = 0; num2 < 10; num2++) { fillNumber(2, num2, color); for (int num1 = 0; num1 < 10; num1++) { fillNumber(3, num1, color); clock.show(); delay(wait); } } } }