Make station id independent parameter Implement scrolling with rot encoder Normalize latin text add button
292 lines
5.9 KiB
C++
292 lines
5.9 KiB
C++
|
|
#include <LCDI2C_Multilingual.h>
|
|
#include <WiFi.h>
|
|
#include <HTTPClient.h>
|
|
#include <Arduino_JSON.h>
|
|
#include <Encoder.h>
|
|
|
|
#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;
|
|
}
|
|
} |