biciClock/biciClock.ino

364 lines
9.1 KiB
C++

#include <Adafruit_NeoPixel.h>
#include <ArduinoJson.h>
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <DNSServer.h>
#include <ESP8266WebServer.h>
#include <WiFiManager.h>
#include <EEPROM.h>
#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);
}
}
}
}