diff --git a/bus_lcd.ino b/bus_lcd.ino new file mode 100644 index 0000000..fa44a3c --- /dev/null +++ b/bus_lcd.ino @@ -0,0 +1,292 @@ + +#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; + } +} \ No newline at end of file