Finished code

Make station id independent parameter

Implement scrolling with rot encoder

Normalize latin text

add button
This commit is contained in:
txrpe 2025-04-23 11:44:15 +02:00
parent dac7cc0818
commit 8886544c74

292
bus_lcd.ino Normal file
View File

@ -0,0 +1,292 @@
#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;
}
}