Live arrivals
Reads the next three estimates from LTA DataMall Bus Arrival v3.
A CoreS3 arrival display that watches one Singapore bus service and sounds a timely reminder.

MOD.01 / ENTRY 03
A dedicated glanceable display for the bus that matters now—not every route in the city.
The CoreS3 joins Wi-Fi, requests the next three arrivals for one stop and service, and sounds once when the next bus enters the chosen alert window. The public sketch contains placeholders only; no Wi-Fi password or LTA key is stored on this website.
[ 01 / SYSTEM SHAPE ]
03 FUNCTIONS
Reads the next three estimates from LTA DataMall Bus Arrival v3.
Sounds once inside the alert window, then rearms for the following bus.
Shows service, stop, arrival times, and available load information.
[ 02 / ARDUINO ]
The excerpt shows the essential request. The complete downloadable sketch adds Singapore time parsing, the CoreS3 display, reconnect handling, and the speaker pattern.
const char* WIFI_NAME = "YOUR_WIFI_NAME";
const char* WIFI_PASSWORD = "YOUR_WIFI_PASSWORD";
const char* LTA_ACCOUNT_KEY = "YOUR_LTA_ACCOUNT_KEY";
const char* BUS_STOP_CODE = "83139";
const char* BUS_SERVICE = "15";
const int ALERT_MINUTES = 3;
const unsigned long UPDATE_INTERVAL_MS = 20000;
void updateBusArrival() {
String url =
"https://datamall2.mytransport.sg/"
"ltaodataservice/v3/BusArrival"
"?BusStopCode=" + String(BUS_STOP_CODE) +
"&ServiceNo=" + String(BUS_SERVICE);
WiFiClientSecure secureClient;
secureClient.setInsecure(); // Prototype only; install a CA for production.
HTTPClient http;
if (!http.begin(secureClient, url)) return;
http.addHeader("AccountKey", LTA_ACCOUNT_KEY);
http.addHeader("accept", "application/json");
if (http.GET() != HTTP_CODE_OK) {
http.end();
return;
}
DynamicJsonDocument document(8192);
if (deserializeJson(document, http.getStream())) {
http.end();
return;
}
JsonArray services = document["Services"].as<JsonArray>();
if (!services.isNull() && services.size() > 0) {
const char* arrival = services[0]["NextBus"]["EstimatedArrival"] | "";
const int minutes = minutesUntil(arrival);
drawArrival(minutes);
if (minutes >= 0 && minutes <= ALERT_MINUTES && !alarmGiven) {
soundReminder();
alarmGiven = true;
}
}
http.end();
}NO LIVE CREDENTIALS FOUND · NOT HARDWARE-BUILD-VERIFIED HERE