#include #include #include #include #include #define BTN_PIN 0 int station_id = 126; void print_busses(); void print_select_station(); String stringify_field(JSONVar); int intify_field(JSONVar); void norm_text(char* text); Encoder enc(3, 4); long enc_position = 0; int last_button_state = 0; int station_selected = 0; // set LCD address, number of columns and rows // if you don't know your display address, run an I2C scanner sketch LCDI2C_Latin_Symbols lcd(0x27, 20, 4); char baseEndpoint[] = "https://bgpp.misa.st/api/stations/bg/search?id="; JSONVar busses; JSONVar response; int bus_index = 0; int busses_updated = 0; int scroll_updated = 0; int station_updated = 0; void setup() { pinMode(BTN_PIN, INPUT_PULLUP); // initialize LCD lcd.init(); lcd.setAutoNewLine(false); // turn on LCD backlight lcd.backlight(); Serial.begin(115200); delay(100); WiFi.begin("Decentrala", ""); lcd.setCursor(0, 1); lcd.print("Povezujem se"); Serial.print("\nConnection"); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); lcd.print("."); } Serial.print("\nConnection OK, IP: "); Serial.print(WiFi.localIP()); Serial.print(" Gateway: "); Serial.println(WiFi.gatewayIP()); Serial.println("You can try to ping me ;-)"); print_select_station(); } void loop() { int encoder_change = 0; int button_pressed = 0; int btnState = !digitalRead(BTN_PIN); if (btnState != last_button_state) { last_button_state = btnState; if(btnState){ button_pressed = 1; } } Serial.println(button_pressed); if (!station_selected) { if(button_pressed){ station_selected = 1; fetch_busses(); } }else { if(button_pressed){ station_selected = 0; print_select_station(); } } long newPosition = enc.read(); if (newPosition != enc_position) { encoder_change += (newPosition - enc_position) / 4; enc_position = newPosition; } if (encoder_change && !station_selected) { station_id -= encoder_change; station_updated = 1; } if (encoder_change && station_selected) { bus_index -= encoder_change; scroll_updated = 1; if (bus_index < 0) { bus_index = 0; } if (bus_index > busses.length() - 4) { bus_index = max(busses.length() - 3, 0); } } if(station_updated){ print_select_station(); station_updated = 0; } if (busses_updated) { print_busses(); busses_updated = 0; bus_index = 0; } if (scroll_updated) { print_busses(); scroll_updated = 0; } delay(200); } void fetch_busses() { lcd.clear(); lcd.setCursor(2, 1); lcd.println("Ucitavam..."); char url[256] = { 0 }; char id[5] = { 0 }; strcpy(url, baseEndpoint); strcat(url, itoa(station_id, id, 10)); HTTPClient http; http.begin(url); int responseCode = http.GET(); if (responseCode > 0) { lcd.clear(); lcd.setCursor(0, 1); lcd.print("HTTP response code: "); lcd.print(responseCode); String payload = http.getString(); Serial.println(payload); response = JSON.parse(payload); if (JSON.typeof_(response) == "undefined") { lcd.clear(); lcd.print("undefined"); } else { // for(response["vehicles"]) Serial.println(response["vehicles"][0]["lineNumber"]); busses = response["vehicles"]; Serial.println(response["vehicles"]); } busses_updated = 1; } else { lcd.clear(); lcd.setCursor(0, 1); lcd.print("error"); } http.end(); } void print_busses() { lcd.clear(); lcd.setCursor(0, 0); String name = stringify_field(response["name"]); char namec[20] = { 0 }; name.toCharArray(namec, 20); lcd.print(stringify_field(response["id"])); lcd.print(":"); norm_text(namec); lcd.print(namec); // for (int i = 0; i < 16; i++) { // lcd.scrollDisplayLeft(); // delay(250); // } // for (int i = 0; i < 16; i++) { // lcd.scrollDisplayRight(); // delay(250); // } lcd.setCursor(0, 1); if (JSON.typeof_(busses) == "undefined" || JSON.typeof_(busses) == "null") { delay(1000); Serial.print("no busses"); lcd.print("nema buseva"); return; } for (int i = 0; i < min(busses.length(), 3); i++) { int busi = busses.length() - 1 - i - bus_index; JSONVar bus = busses[busi]; String line_number = stringify_field(bus["lineNumber"]); int minutes = intify_field(bus["secondsLeft"]) / 60; lcd.setCursor(0, i + 1); lcd.print(line_number); lcd.print(": "); lcd.print(stringify_field(bus["stationsBetween"])); lcd.print("st "); lcd.print(minutes); lcd.print("'"); } if (bus_index > 0) { lcd.setCursor(19, 1); lcd.print("^"); } if (bus_index < busses.length() - 3) { lcd.setCursor(19, 3); lcd.print(">"); } } void print_select_station() { lcd.clear(); lcd.setCursor(0, 0); lcd.print("Izaberite broj stanice:"); lcd.setCursor(1, 1); lcd.print(station_id); } int intify_field(JSONVar jfield) { if (JSON.typeof_(jfield) != "number") { return -1; } return (int)jfield; } String stringify_field(JSONVar jfield) { if (JSON.typeof_(jfield) == "number") { return (String)(int)jfield; } String field = JSON.stringify(jfield); return field.substring(1, field.length() - 1); } void norm_text(char* text) { int flag = 0; char* t = text; while (*t != 0) { switch (*t) { case 197: case 196: flag = 1; break; case 0x86: case 0x8c: *t = 'C'; case 0x87: case 0x8d: *t = 'c'; break; case 0xbd: *t = 'Z'; break; case 0xbe: *t = 'z'; break; case 0xa0: *t = 'S'; break; case 0xa1: *t = 's'; break; } if (flag) { flag = 0; char* c = t; while (*c != 0) { *c = c[1]; c += 1; } t -= 1; } t += 1; } }