Hello!
I'm trying to periodically POST data to a HTTP API from my Arduino MKR NB 1500 over the NB network. I'm having problems getting the device to send multiple HTTP requests though. Often the first request goes fine, but then usually already the next one fails and after that the device completely locks up and stops executing the code when attempting a new request. Rarely a few requests go fine before this happens and similarly sometimes a few requests fail before the device finally locks up. I feel I've gone through all the official examples and forums posts and such and I feel I should do everything correctly but the device still fails. Would someone here maybe have some tips on how to get this working? I'll paste an example code and logs from the code below:
#include <MKRNB.h>
#include <ArduinoHttpClient.h>
NB nbAccess = NB(true);
NBScanner nbNetworkScanner;
NBModem nbModem;
GPRS gprsClient;
NBClient nbClient;
void sendData(uint16_t data1, float data2, float data3){
union {
float from;
uint32_t to;
} converter = {.from = data2};
uint32_t data2Integer = converter.to;
converter.from = data3;
uint32_t data3Integer = converter.to;
uint8_t payload[10];
payload[0] = (data1 & 0x0000FF00) >> 8;
payload[1] = (data1 & 0x000000FF) >> 0;
payload[2] = (data2Integer & 0xFF000000) >> 24;
payload[3] = (data2Integer & 0x00FF0000) >> 16;
payload[4] = (data2Integer & 0x0000FF00) >> 8;
payload[5] = (data2Integer & 0x000000FF) >> 0;
payload[6] = (data3Integer & 0xFF000000) >> 24;
payload[7] = (data3Integer & 0x00FF0000) >> 16;
payload[8] = (data3Integer & 0x0000FF00) >> 8;
payload[9] = (data3Integer & 0x000000FF) >> 0;
HttpClient httpClient = HttpClient(nbClient, "api.oursite.com", 80);
Serial.println("Sending data over NB");
httpClient.beginRequest();
httpClient.post("/data"); // I believe the code finally locks up at this line
httpClient.sendHeader("Authorization", "Bearer abcdefg1234567");
httpClient.sendHeader("Content-Type", "application/octet-stream");
httpClient.sendHeader("Content-Length", "10");
httpClient.beginBody();
httpClient.write(payload, 10);
httpClient.endRequest();
int statusCode = httpClient.responseStatusCode();
if(statusCode == 200){
Serial.println("Data sent over NB");
}else{
Serial.print("Could not send data over NB, status ");
Serial.println(statusCode);
}
}
void setup() {
nbNetworkScanner.begin();
boolean connected = false;
while(!connected){
if(nbAccess.begin("1234") == NB_READY && gprsClient.attachGPRS() == GPRS_READY){
connected = true;
}else{
Serial.println("Error connecting to NB network, retrying in 1 second...");
delay(1000);
}
}
Serial.print("Connected to NB network with signal strength ");
Serial.print(nbNetworkScanner.getSignalStrength());
Serial.println("/31");
}
void loop() {
sendData(30, 25, 50);
delay(20000);
}
And here's some logs from running the code, with repeating or secret info removed.
15:11:14.505 -> AT
15:11:14.505 -> OK
15:11:14.634 -> AT
15:11:14.634 -> OK
15:11:14.731 -> AT+CMEE=0
15:11:14.731 -> OK
15:11:14.859 -> AT+CFUN=0
15:11:14.859 -> OK
15:11:15.052 -> AT+CPIN?
15:11:15.052 -> +CPIN: READY
15:11:15.052 ->
15:11:15.052 -> OK
15:11:15.246 -> AT+CMGF=1
15:11:15.246 -> OK
15:11:15.471 -> AT+UDCONF=1,1
15:11:15.471 -> OK
15:11:15.665 -> AT+CTZU=1
15:11:15.665 -> OK
15:11:15.858 -> AT+CGDCONT=1,"IP",""
15:11:15.858 -> OK
15:11:16.084 -> AT+UAUTHREQ=1,0
15:11:16.084 -> OK
15:11:16.277 -> AT+CFUN=1
15:11:16.277 -> OK
15:11:16.469 -> AT+CEREG?
15:11:16.469 -> +CEREG: 0,0
15:11:16.469 ->
15:11:16.469 -> OK
15:11:16.661 -> AT+CEREG?
15:11:16.661 -> +CEREG: 0,0
15:11:16.661 ->
15:11:16.661 -> OK
...
15:11:29.394 -> AT+CEREG?
15:11:29.394 -> +CEREG: 0,2
15:11:29.394 ->
15:11:29.394 -> OK
15:11:29.620 -> AT+CEREG?
15:11:29.620 -> +CEREG: 0,5
15:11:29.620 ->
15:11:29.620 -> OK
15:11:30.138 -> AT+CGATT=1
15:11:30.138 -> OK
15:11:31.144 -> AT+CGACT?
15:11:31.144 -> +CGACT: 1,1
15:11:31.144 ->
15:11:31.144 -> OK
15:11:31.144 -> Connected to NB network with signal strength AT+CSQ
15:11:31.144 -> +CSQ: 2,99
15:11:31.144 ->
15:11:31.144 -> OK
15:11:31.144 -> 2/31
15:11:31.144 -> Sending data over NB
15:11:31.273 -> AT+USOCR=6
15:11:31.273 -> +USOCR: 0
15:11:31.273 ->
15:11:31.273 -> OK
15:11:31.499 -> AT+USOCO=0,"api.oursite.com",80
15:11:49.990 -> OK
15:11:49.990 -> AT+USOWR=0,4,"504F5354"
15:11:49.990 -> +USOWR: 0,4
15:11:49.990 ->
15:11:49.990 -> OK
...
15:12:08.009 -> AT+USORD=0,512
15:12:08.009 -> +USORD: 0,""
15:12:08.009 ->
15:12:08.009 -> OK
15:12:09.014 ->
15:12:09.014 -> +UUSORD: 0,196
15:12:09.045 -> AT+USORD=0,512
15:12:09.045 ->
15:12:09.045 -> +USORD: 0,196,"..."
15:12:09.077 -> OK
15:12:09.077 -> Data sent over NB
15:12:29.066 -> Sending data over NB
15:12:29.066 ->
15:12:29.066 -> +UUSOCL: 0
15:12:29.066 -> AT+USOCL=0
15:12:29.066 -> ERROR
15:12:29.196 -> AT+USOCR=6
15:12:29.196 -> +USOCR: 0
15:12:29.196 ->
15:12:29.196 -> OK
15:12:29.390 -> AT+USOCO=0,"api.oursite.com",80
15:12:46.968 -> OK
...
15:12:47.870 -> +USOWR: 0,10
15:12:47.870 ->
15:12:47.870 -> OK
15:12:47.902 -> AT+USORD=0,512
15:12:47.902 -> +USORD: 0,""
15:12:47.902 ->
15:12:47.902 -> OK
...
15:13:17.062 -> AT+USORD=0,512
15:13:17.062 -> +USORD: 0,""
15:13:17.062 ->
15:13:17.062 -> OK
15:13:18.066 -> Could not send data over NB, status -3
15:13:38.025 -> Sending data over NB
15:13:38.025 ->
15:13:38.025 -> +UUSORD: 0,196
15:13:38.025 -> AT+USOCL=0
15:14:11.176 -> OK
I think the relevant part of the logs, maybe in addition to the NB library logs (maybe?), is the HTTP library returning a -3 meaning from what I gather a unknown state with the client object. The first request has returned code 200 so the request went fine and looking at the test server we use the data posted shows up there fine. The logs end where the Arduino locks up and won't continue unless reprogrammed or powered off and on again.
I hope somebody can see what I'm doing wrong or could be doing differently to get this working!