The inspiration for this project was traintrackr, at first I thought about using IS31FL3731 LED driver IC to control up to 144 LEDs with the built-in cross-plexing feature. The pros about using this IC is the small footprint, relatively easy to control, low current consumption and PWM, on the negative side I would have only one color. I designed a PCB for it, but I didn't like it.

Finally I decided to use WS2812B addressable LEDs, its RGB, easy to program, control brightness, easy to design the PCB and I also like the size of it. The only problem with those LEDs is the high current draw, each RGB LED draws approximately 50mA when it is set to full brightness and powered at 5V. This means that, for 96 train stations we turn on, our LED array could be drawing as much as 4.5A. Since this project is not powering up all LEDs at the same time, I designed the PCB with LM7805 (1.5A), which we could power 30 LEDs with maximum brightness. I did also some tests powering all LEDs, but using 40% of the brightness, it works very well and I had no problem at all.

To control everything the microcontroller selected was the ESP32 WROVER, WIFI was mandatory to fetch online data, it also works with ESP8266, but with ESP32 the code was running much faster to parse online data, and I could make use of tasks.

In Munich, all transport stations have this QR code, where you can scan and open an webpage with information about line, direction and arrival time, for example Petuelring stations:

Checking the source code of the webpage, its easy to find the information about the station, and also easy to parse using ESP32, specially because it was HTTP:

Well, that was the first plan, and it did work but was not the best approach, to get information from other stations I would have to write the hole name:

After some research I found the new webpage from MVG, where we have a similar feature to search the station information:

Using the JQuery AJAX Capture Chrome extension I saw this https url query.

Its the ID of the station plus services selected:

And there was the information, all available in JSON, much better to parse:

There is even an python library from MVG (amazing!) but I didn't use it. "A library for fetching departures, routes and service interruptions from Munich Transport Authority MVG, using the newer JSON-api on"

Nice, so now I can get information using JSON, but where to find all stations IDs? Well after some more searche, I found this webpage from MVV for developers:

There can download the list of all stations with name, global ID and other nice information.

The HTTPS GET now can be easily build:

const String urlHost = "";
const String urlquery = "?apiKey=aklKa290LsadOLW&sbahn=false&tram=false&bus=false";

String strHstGlobaleID = urlHost + String(hstGlobaleID[j]) + urlquery;

To parse JSON data using ESP32, I made use of the amazing ArduinoJson assistant, I simplified the JSON to get only the first 4 departure times of each station:

It also generates for you the parsing program:

const size_t capacity = JSON_ARRAY_SIZE(4) + 5*JSON_OBJECT_SIZE(1) + 80;
DynamicJsonDocument doc(capacity);

const char* json = "{\"departures\":[{\"departureTime\":1603563780000},{\"departureTime\":1603563960000},{\"departureTime\":1603564380000},{\"departureTime\":1603564560000}]}";

deserializeJson(doc, json);

JsonArray departures = doc["departures"];

long long departures_0_departureTime = departures[0]["departureTime"]; // 1603563780000

long long departures_1_departureTime = departures[1]["departureTime"]; // 1603563960000

long long departures_2_departureTime = departures[2]["departureTime"]; // 1603564380000

long long departures_3_departureTime = departures[3]["departureTime"]; // 1603564560000

Those are the key points of the program, more information you can find in the full application software.

The PCB schematics was developed using EasyEDA from JLCPCB, you can find all files attached.