I keep getting dropped API, where only the first API call is successful, follow by 0 or a few calls. Rest are unable to get the API. Any advice? Thanks in Advance, Damien Lee
#include <WiFiS3.h>
#include <ArduinoHttpClient.h>
#include <Arduino_JSON.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ILI9341.h>
// WiFi credentials
const char* ssid = "TMOCETALxxxxxx";
const char* password = "TMOCxxxxxxx";
// LTA DataMall API details
const char* host = "datamall2.mytransport.sg";
const int httpsPort = 443;
const char* apiPath = "/ltaodataservice/v3/BusArrival?BusStopCode=10411&ServiceNo=63";
const char* accountKey = "xxxxxxx";
// TFT LCD pins (Adafruit 2.8" shield default)
#define TFT_CS 10
#define TFT_DC 9
#define TFT_RST 8
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST);
// WiFi and HTTP objects
WiFiSSLClient wifiClient;
HttpClient client = HttpClient(wifiClient, host, httpsPort);
int countUp = 0; // variable integer
unsigned long lastUpdate = 0;
const unsigned long updateInterval = 20000; // 20 seconds
void setup() {
Serial.begin(115200);
tft.begin();
tft.setRotation(1);
tft.fillScreen(ILI9341_BLACK);
tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK);
tft.setTextSize(2);
tft.setCursor(10, 10);
tft.println("Connecting WiFi...");
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
tft.print(".");
}
}
void loop() {
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
tft.print(".");
}
if (millis() - lastUpdate > updateInterval || lastUpdate == 0) {
lastUpdate = millis();
displayBusArrival();
}
}
void displayBusArrival() {
tft.fillScreen(ILI9341_BLACK);
tft.setCursor(10, 10);
tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK);
tft.setTextSize(3);
tft.println("SINGAPORE BUS");
tft.println(" ARRIVAL");
tft.setTextColor(ILI9341_RED, ILI9341_BLACK);
tft.setTextSize(2);
tft.println(" DEVELOPED BY DAMIEN LEE");
tft.println("");
tft.setTextColor(ILI9341_YELLOW, ILI9341_BLACK);
tft.setTextSize(2);
tft.println("Service : 63");
tft.setTextColor(ILI9341_YELLOW, ILI9341_BLACK);
tft.setTextSize(2);
tft.println("Bus Stop: 10411");
tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK);
tft.setTextSize(2);
client.beginRequest();
client.get(apiPath);
client.sendHeader("AccountKey", accountKey);
client.sendHeader("Accept", "application/json");
client.endRequest();
countUp++; // add 1 to the count
tft.println("");
tft.println(countUp); // prints out the count
int statusCode = client.responseStatusCode();
String response = client.responseBody();
if (statusCode != 200) {
tft.setTextColor(ILI9341_RED, ILI9341_BLACK);
tft.println("API Error!");
tft.print("Status: ");
tft.println("*");
tft.println(statusCode);
return;
}
JSONVar data = JSON.parse(response);
if (JSON.typeof(data) == "undefined") {
tft.setTextColor(ILI9341_RED, ILI9341_BLACK);
tft.println(".");
JSONVar data = null;
return;
}
JSONVar services = data["Services"];
if (services.length() > 0) {
JSONVar svc = services[0];
JSONVar nextBus = svc["NextBus"];
JSONVar nextBus2 = svc["NextBus2"];
JSONVar nextBus3 = svc["NextBus3"];
tft.setTextColor(ILI9341_CYAN, ILI9341_BLACK);
tft.println("Next 3 Arrivals:");
tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK);
tft.print("1: ");
tft.println(formatTime(nextBus["EstimatedArrival"]));
tft.print("2: ");
tft.println(formatTime(nextBus2["EstimatedArrival"]));
tft.print("3: ");
tft.println(formatTime(nextBus3["EstimatedArrival"]));
} else {
tft.setTextColor(ILI9341_RED, ILI9341_BLACK);
tft.println("No service info.");
}
wifiClient.stop(); // Close connection after successful request
}
// Helper to format ISO time to HH:MM or "--"
String formatTime(JSONVar isoTime) {
String t = (const char*)isoTime;
if (t.length() < 16) return "--";
// Format: "YYYY-MM-DDTHH:MM:SS+08:00"
return t.substring(11, 16);
J-M-L
November 21, 2025, 9:31am
2
you should not restart the wifi connection in the loop. Check if it is active but don't force restart it all the time !
try something like
void loop() {
if (WiFi.status() != WL_CONNECTED) {
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) { delay(500); }
}
if (millis() - lastUpdate > updateInterval || lastUpdate == 0) {
lastUpdate = millis();
displayBusArrival();
}
}
@J-M-L can you PM me? I pass you the api key.
It is better now, but beyond the 7th read, the data is empty . It seems that unplugging the usb and resetting the R4 will obtain stable results for 5 reads, then subsequent reads are empty. until the 14th, data is back. 15th empty and so on.
J-M-L
November 24, 2025, 8:15am
5
I don’t have an R4
Can you post full code and details about your wiring and power ?
#include <WiFiS3.h>
#include <ArduinoHttpClient.h>
#include <Arduino_JSON.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ILI9341.h>
// WiFi credentials
const char* ssid = "xxx_5G";
const char* password = "xxxx";
// LTA DataMall API details
const char* host = "datamall2.mytransport.sg";
const int httpsPort = 443;
const char* apiPath = "/ltaodataservice/v3/BusArrival?BusStopCode=10411&ServiceNo=63";
const char* accountKey = "xxxx==";
// TFT LCD pins (Adafruit 2.8" shield default)
#define TFT_CS 10
#define TFT_DC 9
#define TFT_RST 8
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST);
// WiFi and HTTP objects
WiFiSSLClient wifiClient;
HttpClient client = HttpClient(wifiClient, host, httpsPort);
int countUp = 0; // variable integer
unsigned long lastUpdate = 0;
const unsigned long updateInterval = 20000; // 20 seconds
void setup() {
Serial.begin(115200);
tft.begin();
tft.setRotation(1);
tft.fillScreen(ILI9341_BLACK);
tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK);
tft.setTextSize(2);
tft.setCursor(10, 10);
tft.println("Connecting WiFi...");
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
tft.print(".");
}
}
void loop() {
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
tft.print(".");
}
if (millis() - lastUpdate > updateInterval || lastUpdate == 0) {
lastUpdate = millis();
displayBusArrival();
}
}
void displayBusArrival() {
tft.fillScreen(ILI9341_BLACK);
tft.setCursor(10, 10);
tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK);
tft.setTextSize(3);
tft.println("SINGAPORE BUS");
tft.println(" ARRIVAL");
tft.setTextColor(ILI9341_RED, ILI9341_BLACK);
tft.setTextSize(2);
tft.println(" DEVELOPED BY DAMIEN LEE");
tft.println("");
tft.setTextColor(ILI9341_YELLOW, ILI9341_BLACK);
tft.setTextSize(2);
tft.println("Service : 63");
tft.setTextColor(ILI9341_YELLOW, ILI9341_BLACK);
tft.setTextSize(2);
tft.println("Bus Stop: 10411");
tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK);
tft.setTextSize(2);
client.beginRequest();
client.get(apiPath);
client.sendHeader("AccountKey", accountKey);
client.sendHeader("Accept", "application/json");
client.endRequest();
countUp++; // add 1 to the count
tft.println("");
tft.println(countUp); // prints out the count
int statusCode = client.responseStatusCode();
String response = client.responseBody();
if (statusCode != 200) {
tft.setTextColor(ILI9341_RED, ILI9341_BLACK);
tft.println("API Error!");
tft.print("Status: ");
tft.println("*");
tft.println(statusCode);
return;
}
JSONVar data = JSON.parse(response);
if (JSON.typeof(data) == "undefined") {
tft.setTextColor(ILI9341_RED, ILI9341_BLACK);
tft.println(".");
JSONVar data = null;
return;
}
JSONVar services = data["Services"];
if (services.length() > 0) {
JSONVar svc = services[0];
JSONVar nextBus = svc["NextBus"];
JSONVar nextBus2 = svc["NextBus2"];
JSONVar nextBus3 = svc["NextBus3"];
tft.setTextColor(ILI9341_CYAN, ILI9341_BLACK);
tft.println("Next 3 Arrivals:");
tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK);
tft.print("1: ");
tft.println(formatTime(nextBus["EstimatedArrival"]));
tft.print("2: ");
tft.println(formatTime(nextBus2["EstimatedArrival"]));
tft.print("3: ");
tft.println(formatTime(nextBus3["EstimatedArrival"]));
} else {
tft.setTextColor(ILI9341_RED, ILI9341_BLACK);
tft.println("No service info.");
}
// wifiClient.stop(); // Close connection after successful request
}
// Helper to format ISO time to HH:MM or "--"
String formatTime(JSONVar isoTime) {
String t = (const char*)isoTime;
if (t.length() < 16) return "--";
// Format: "YYYY-MM-DDTHH:MM:SS+08:00"
return t.substring(11, 16);
}
J-M-L
November 25, 2025, 8:01am
8
What did i say about that ?
You might also need to properly end the client session with wifiClient.stop();
appreciate if you can paste the whole code here? my limitied knowledge is an impairment. lolx
I have tried your suggestions but still there are significant drops with the data.
J-M-L
November 25, 2025, 9:52am
11
try this - edited here, fully untested
#include <WiFiS3.h>
#include <ArduinoHttpClient.h>
#include <Arduino_JSON.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ILI9341.h>
// ************************************************************************
// ******** PUT YOUR REAL VALUES HERE (DON'T SHARE WITH THE FORUM) ********
// ************************************************************************
const char* ssid = "xxx_5G";
const char* password = "xxxx";
const char* accountKey = "xxx==";
// ************************************************************************
// ************************************************************************
const char* host = "datamall2.mytransport.sg";
const int httpsPort = 443;
#define SERVICE_NO "63"
#define BUS_STOP_CODE "10411"
const char* apiPath = "/ltaodataservice/v3/BusArrival?BusStopCode=" BUS_STOP_CODE "&ServiceNo=" SERVICE_NO;
#define TFT_CS 10
#define TFT_DC 9
#define TFT_RST 8
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST);
WiFiSSLClient wifiClient;
int countUp = 0;
const unsigned long updateInterval = 20000;
unsigned long lastUpdate = -updateInterval;
const unsigned long wifiTimeout = 15000;
void displayBusArrival() {
if (WiFi.status() != WL_CONNECTED) {
tft.fillScreen(ILI9341_BLACK);
tft.setCursor(10, 10);
tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK);
tft.setTextSize(2);
tft.println("WiFi disconnected!");
tft.println("Reconnecting...");
WiFi.disconnect();
WiFi.begin(ssid, password);
unsigned long start = millis();
while (WiFi.status() != WL_CONNECTED) {
if (millis() - start > wifiTimeout) {
tft.setTextColor(ILI9341_RED, ILI9341_BLACK);
tft.println("WiFi reconnect failed!");
return;
}
delay(500);
}
tft.setTextColor(ILI9341_GREEN, ILI9341_BLACK);
tft.println("WiFi reconnected");
delay(1000);
}
tft.fillScreen(ILI9341_BLACK);
tft.setCursor(10, 10);
tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK);
tft.setTextSize(3);
tft.println("SINGAPORE BUS");
tft.println(" ARRIVAL");
tft.setTextColor(ILI9341_RED, ILI9341_BLACK);
tft.setTextSize(2);
tft.println("BY J-M-L FOR D. LEE");
tft.println();
tft.setTextColor(ILI9341_YELLOW, ILI9341_BLACK);
tft.setTextSize(2);
tft.print("Service : ");
tft.println(SERVICE_NO);
tft.print("Bus Stop: ");
tft.println(BUS_STOP_CODE);
tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK);
tft.setTextSize(2);
HttpClient client = HttpClient(wifiClient, host, httpsPort);
client.beginRequest();
client.get(apiPath);
client.sendHeader("AccountKey", accountKey);
client.sendHeader("Accept", "application/json");
client.endRequest();
countUp++;
tft.println();
tft.println(countUp);
int statusCode = client.responseStatusCode();
String response = client.responseBody();
client.stopConnection();
if (statusCode != 200) {
tft.setTextColor(ILI9341_RED, ILI9341_BLACK);
tft.println("API Error!");
tft.print("Status: ");
tft.println(statusCode);
return;
}
JSONVar data = JSON.parse(response);
if (JSON.typeof(data) == "undefined") {
tft.setTextColor(ILI9341_RED, ILI9341_BLACK);
tft.println("JSON parse error");
return;
}
JSONVar services = data["Services"];
if (services.length() > 0) {
JSONVar svc = services[0];
tft.setTextColor(ILI9341_CYAN, ILI9341_BLACK);
tft.println("Next 3 Arrivals:");
tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK);
printBusArrival(svc, "NextBus", 1);
printBusArrival(svc, "NextBus2", 2);
printBusArrival(svc, "NextBus3", 3);
} else {
tft.setTextColor(ILI9341_RED, ILI9341_BLACK);
tft.println("No service info.");
}
}
void printBusArrival(JSONVar svc, const char* key, int index) {
if (!svc.hasOwnProperty(key)) return;
JSONVar bus = svc[key];
if (!bus.hasOwnProperty("EstimatedArrival")) return;
tft.print(index);
tft.print(": ");
tft.println(formatTime(bus["EstimatedArrival"]));
}
String formatTime(JSONVar isoTime) {
String t = (const char*)isoTime;
if (t.length() < 16) return "--";
return t.substring(11, 16);
}
// --------------- MAIN CODE --------------
void setup() {
Serial.begin(115200);
tft.begin();
tft.setRotation(1);
tft.fillScreen(ILI9341_BLACK);
tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK);
tft.setTextSize(2);
tft.setCursor(10, 10);
tft.println("Connecting WiFi...");
WiFi.begin(ssid, password);
unsigned long start = millis();
while (WiFi.status() != WL_CONNECTED) {
if (millis() - start > wifiTimeout) {
tft.println();
tft.println("WiFi Failed");
return;
}
tft.print(".");
delay(500);
}
tft.println();
tft.println("WiFi Connected");
}
void loop() {
if (millis() - lastUpdate >= updateInterval) {
lastUpdate = millis();
displayBusArrival();
}
}
you'll have to set your correct info into
// ************************************************************************
// ******** PUT YOUR REAL VALUES HERE (DON'T SHARE WITH THE FORUM) ********
// ************************************************************************
const char* ssid = "xxx_5G";
const char* password = "xxxx";
const char* accountKey = "xxx==";
// ************************************************************************
// ************************************************************************
J-M-L:
#include <WiFiS3.h>
#include <ArduinoHttpClient.h>
#include <Arduino_JSON.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ILI9341.h>
// ************************************************************************
// ******** PUT YOUR REAL VALUES HERE (DON'T SHARE WITH THE FORUM) ********
// ************************************************************************
const char* ssid = "xxx_5G";
const char* password = "xxxx";
const char* accountKey = "xxx==";
// ************************************************************************
// ************************************************************************
const char* host = "datamall2.mytransport.sg";
const int httpsPort = 443;
#define SERVICE_NO "63"
#define BUS_STOP_CODE "10411"
const char* apiPath = "/ltaodataservice/v3/BusArrival?BusStopCode=" BUS_STOP_CODE "&ServiceNo=" SERVICE_NO;
#define TFT_CS 10
#define TFT_DC 9
#define TFT_RST 8
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST);
WiFiSSLClient wifiClient;
int countUp = 0;
const unsigned long updateInterval = 20000;
unsigned long lastUpdate = -updateInterval;
const unsigned long wifiTimeout = 15000;
void displayBusArrival() {
if (WiFi.status() != WL_CONNECTED) {
tft.fillScreen(ILI9341_BLACK);
tft.setCursor(10, 10);
tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK);
tft.setTextSize(2);
tft.println("WiFi disconnected!");
tft.println("Reconnecting...");
WiFi.disconnect();
WiFi.begin(ssid, password);
unsigned long start = millis();
while (WiFi.status() != WL_CONNECTED) {
if (millis() - start > wifiTimeout) {
tft.setTextColor(ILI9341_RED, ILI9341_BLACK);
tft.println("WiFi reconnect failed!");
return;
}
delay(500);
}
tft.setTextColor(ILI9341_GREEN, ILI9341_BLACK);
tft.println("WiFi reconnected");
delay(1000);
}
tft.fillScreen(ILI9341_BLACK);
tft.setCursor(10, 10);
tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK);
tft.setTextSize(3);
tft.println("SINGAPORE BUS");
tft.println(" ARRIVAL");
tft.setTextColor(ILI9341_RED, ILI9341_BLACK);
tft.setTextSize(2);
tft.println("BY J-M-L FOR D. LEE");
tft.println();
tft.setTextColor(ILI9341_YELLOW, ILI9341_BLACK);
tft.setTextSize(2);
tft.print("Service : ");
tft.println(SERVICE_NO);
tft.print("Bus Stop: ");
tft.println(BUS_STOP_CODE);
tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK);
tft.setTextSize(2);
HttpClient client = HttpClient(wifiClient, host, httpsPort);
client.beginRequest();
client.get(apiPath);
client.sendHeader("AccountKey", accountKey);
client.sendHeader("Accept", "application/json");
client.endRequest();
countUp++;
tft.println();
tft.println(countUp);
int statusCode = client.responseStatusCode();
String response = client.responseBody();
client.stopConnection();
if (statusCode != 200) {
tft.setTextColor(ILI9341_RED, ILI9341_BLACK);
tft.println("API Error!");
tft.print("Status: ");
tft.println(statusCode);
return;
}
JSONVar data = JSON.parse(response);
if (JSON.typeof(data) == "undefined") {
tft.setTextColor(ILI9341_RED, ILI9341_BLACK);
tft.println("JSON parse error");
return;
}
JSONVar services = data["Services"];
if (services.length() > 0) {
JSONVar svc = services[0];
tft.setTextColor(ILI9341_CYAN, ILI9341_BLACK);
tft.println("Next 3 Arrivals:");
tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK);
printBusArrival(svc, "NextBus", 1);
printBusArrival(svc, "NextBus2", 2);
printBusArrival(svc, "NextBus3", 3);
} else {
tft.setTextColor(ILI9341_RED, ILI9341_BLACK);
tft.println("No service info.");
}
}
void printBusArrival(JSONVar svc, const char* key, int index) {
if (!svc.hasOwnProperty(key)) return;
JSONVar bus = svc[key];
if (!bus.hasOwnProperty("EstimatedArrival")) return;
tft.print(index);
tft.print(": ");
tft.println(formatTime(bus["EstimatedArrival"]));
}
String formatTime(JSONVar isoTime) {
String t = (const char*)isoTime;
if (t.length() < 16) return "--";
return t.substring(11, 16);
}
// --------------- MAIN CODE --------------
void setup() {
Serial.begin(115200);
tft.begin();
tft.setRotation(1);
tft.fillScreen(ILI9341_BLACK);
tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK);
tft.setTextSize(2);
tft.setCursor(10, 10);
tft.println("Connecting WiFi...");
WiFi.begin(ssid, password);
unsigned long start = millis();
while (WiFi.status() != WL_CONNECTED) {
if (millis() - start > wifiTimeout) {
tft.println();
tft.println("WiFi Failed");
return;
}
tft.print(".");
delay(500);
}
tft.println();
tft.println("WiFi Connected");
}
void loop() {
if (millis() - lastUpdate >= updateInterval) {
lastUpdate = millis();
displayBusArrival();
}
}
thanks bro. Do you want a full set of R4 Uno and 2.8TFT above? I can send you one set free of charge. You can keep it after testing.
I got this error:
C:\Users\damien.lee.AAS\OneDrive - Automobile Association Of Singapore\Documents\Arduino\SG_BUS_Final_V3_JML\SG_BUS_Final_V3_JML.ino: In function 'void displayBusArrival()':
C:\Users\damien.lee.AAS\OneDrive - Automobile Association Of Singapore\Documents\Arduino\SG_BUS_Final_V3_JML\SG_BUS_Final_V3_JML.ino:97:10: error: 'class HttpClient' has no member named 'stopConnection'
client.stopConnection();
^~~~~~~~~~~~~~
exit status 1
Compilation error: 'class HttpClient' has no member named 'stopConnection'
J-M-L
November 26, 2025, 6:39am
14
Can you try stop() instead of stopConnection(). - it’s likely what’s it’s called in ArduinoHttpClient actually.
No need for shipping something around - thx for the offer though.
Thank you! Its fully working now.
Glad to have your guidance bro.