The purpose of this project is to make a simple smart device that can really improve your mornings and relieve your stress. I developed this solution for my girlfriend who uses the public transportation daily and struggles with keeping timetables in memory, route planning and being in time.This simple device would help anyone who uses public transportation by checking the ETAs of their most used bus lines and keep the user updated.To reduce the maintenance as little as possible, the device is powered by a Li-ion battery and wakes up every 10 minutes to update its table, which is displayed on a e-paper display, reducing the power consumption next to nothing.
By using the TTGO T5 esp32 epaper module, there is no much to wire since it is all built-in. Make it sure to buy the Li-ion battery with the right connector so it will be just plug-and-play.There is a little trick you should do to reduce the power consumption of the board. When you plug the power in and turn on the power switch, you'll see there is a green led near the antenna showing up; this led is directly connected to 3.3v rail so it will be always on and will always consume some energy. To resolve this issue, simply take a soldering iron and remove it.
The software side of the project is where the real stuff happens.The flow of the program is to wake up, connect to an hardcoded Wi-Fi network, connect to a Public Transportation API, print results on the display and go to sleep.
For convenience I built a structbusTable to hold line number, ETA and a realtime variable that indicates if the prediction is correct.
Data is pulled from the API by the requestTo method. By giving the stop number, the API is returning a JSON array filled with the timetable informations. This array is being parsed and data fills the busTable object.
void requestTo(String stopN, busTable *table){
client.begin("https://gpa.madbob.org/query.php?stop="+stopN);
if(client.GET()>0){
String payload = client.getString();
DynamicJsonDocument doc(1500);
deserializeJson(doc, payload);
uint8_t arraySize = doc.size();
for(uint8_t i = 0; i<arraySize; i++){
String line = doc[i]["line"];
String hour = doc[i]["hour"];
bool realtime = doc[i]["realtime"]=="true"?1:0;
table[i].line = line;
table[i].hour = hour;
table[i].realtime = realtime;
}
}
client.end();
}
In the method printBusLine(), the busTable array is searched for a specific line number. Buses which matched are then printed on the display: bold if the prediction is correct, plain otherwise. If no data has been found NO SERVICE is printed.
void printBusLine(String line, String endstop, int pos, busTable* table){
display.setFont(&BOLD_FONT);
display.setCursor(2,pos);
display.print(endstop);
display.setCursor(150,pos);
int bus_n = 0;
for(int i = 0; i < 9; i++){
if(table[i].line == line){
bus_n ++;
if(table[i].realtime){
display.setFont(&BOLD_FONT);
}else{
display.setFont(&DEFAULT_FONT);
}
if(bus_n < 4) display.print(table[i].hour+" ");
}
}
if(bus_n ==0){
display.setFont(&DEFAULT_FONT);
display.print("NO SERVICE");
}
}
To use it in your city you have to find a free API of your Public Transportation and pull data from it.
To run low power, all of the code is run in the setup() and closed by the PowerOff() method. This method powers off the display controller, enables the timer wakeup to 10 minutes and then puts the MCU to deep sleep.
void PowerOff(){
display.update();
display.powerDown();
esp_sleep_enable_timer_wakeup(6e8);
delay(10);
esp_deep_sleep_start();
}
AssemblingTo make it look a little less hacky, I have designed a simple 3D printable case that you can modify to your own needs.
If you like the project and you want to build it yourself, you can find my code repo below and all of my 3D files for the case. I would like to check how much the battery will last; I will update you with my further testings.
Good luck and Happy Hacking!
Comments