Why does my Arduino occasionally fail to POST (HTTP)?

I've been trying to fix this for hours and hours now, googling constantly and trying out different methods, and it seems like I can't find a fix with existing forums, so I decided to post my own question.

I'm using an MKR WiFi 1010 with the ArduinoHttpClient and WiFiNINA libraries to POST some sensor data to my web server, which is being hosted on a Raspberry Pi 4 Model B.

As it is currently, the POST is successful at seemingly random times, often working multiple times in succession before failing and never working again (but either way, unsuccessful the majority of the time). I have to believe my web server code is the issue, because my Arduino sketch looks like it follows the ArduinoHttpClient "SimplePost.ino" sketch pretty exactly, besides my postData being longer.

My serial monitor shows that I do have a WiFi connection at the moment each POST is attempted and can connect to my web server from another computer, yet I'm getting a mixture of error status codes - mostly "-2" or "-3".

Arduino sketch: (abridged for relevant code, let me know if you need more)

#include <WiFiNINA.h>
#include <ArduinoHttpClient.h>  // talk to web server
#include <OneWire.h>
#include <DallasTemperature.h>
#include <DHT.h>

#include "arduino_secrets.h"    // hiding SSID and password in a header

char ssid[] = SECRET_SSID;
char pass[] = SECRET_PASS;
int status = WL_IDLE_STATUS;

char serverAddress[] = "192.168.5.231"; // RPi addr
int port = 3030;

WiFiClient wifi;
HttpClient client = HttpClient(wifi, serverAddress, port);

---cut code---

void setup(void) {
    Serial.begin(9600);
    while(!Serial);

    while(status != WL_CONNECTED) {
        Serial.print("Attempting to connect to network: ");
        Serial.println(ssid);

        status = WiFi.begin(ssid, pass);
    }

    ---cut code---

}

---cute code---

void uploadData() {
    // Arduino HTTP Client

    Serial.println();
    Serial.print("Signal Strength (RSSI): ");
    Serial.println(WiFi.RSSI());
    
    String postURL = String("POST readings to " + String(serverAddress) + ':' + String(port));
    Serial.println(postURL);
    String contentType = "application/x-www-form-urlencoded";   // POST method to send data to server
    String postData = String(
        "temp1="    + String(temp1) + 
        "&temp2="   + String(temp2) +
        "&temp3="   + String(temp3) +
        "&temp4="   + String(temp4) +
        "&temp5="   + String(temp5) +
        "&dhtHum="  + String(dhtHum) +
        "&dhtTemp=" + String(dhtTemp) +
        "&leftDoorState=" + String(leftDoorState) +
        "&rightDoorState=" + String(rightDoorState) );
    Serial.print("Readings: ");
    Serial.println(postData);

    client.post("/temperatures", contentType, postData);

    int statusCode = client.responseStatusCode();
    String response = client.responseBody();

    Serial.print("Status code: ");
    Serial.println(statusCode);
    Serial.print("Response: ");
    Serial.println(response);

    delay(1000);
}

---cut code---

Example of serial monitor output, success (200) followed by failure (-3) a second later. I've tried setting the delay to longer between POST attempts, that didn't seem to affect anything.

index.js - web server code, run on my Raspberry Pi via SSH using "node index.js". Using Node.js 18.10.0, Express.js 4.18.1, CORS 2.8.5, IP 1.1.8, and body-parser 1.20.1.

const express = require('express');
const cors = require('cors');
const bodyParser = require('body-parser');

const app = express();
const ip = require('ip');
const PORT = 3030;
const serverIP = `${ip.address()}:${PORT}`

app.use(cors());
app.use(bodyParser.urlencoded({ extended: true }));

app.get('/', (req, res, next) => {
    res.json({
        message: 'test'
    });
    next();
    return;
});

app.post('/temperatures', (req, res, next) => {
    console.log('Got body:', req.body);

    let body = JSON.parse(JSON.stringify(req.body));
    let reading = {
        date: new Date(),
        temp1: body.temp1,
        temp2: body.temp2,
        temp3: body.temp3,
        temp4: body.temp4,
        temp5: body.temp5,
        dhtHum: body.dhtHum,
        dhtTemp: body.dhtTemp,
        leftDoorState: body.leftDoorState,
        rightDoorState: body.rightDoorState
    }

    res.sendStatus(200); // send "OK"
    next();
    return;
});

app.listen(PORT, () => {
    console.log(`listening on ${serverIP}`);
});

VSCode terminal output when running the server, showing only two successful POSTs after running the Arduino sketch for around 20 minutes. Apologies for the lack of timestamps, not sure how to get them on VSCode.
terminal

Hopefully it's alright to post/ask for help with something usually non-Arduino like a JavaScript web server, not sure how that works here. I would greatly appreciate any help, thank you!

Just to make sure if the issue is on the arduino or server side, write a simple PHP/Python script accepting the post request. If the issue disappears, you can likely focus on your server side. If it fails you’ll have to investigate the http server, the network and the arduino code
Try to go to unit tests as much as you can

1 Like

It's fine to post questions like this where there are Arduino parts and non-Arduino parts, even when you don't know which part contains the problem. There are members here who will have experience in PHP, Python etc.

Some forum members will even try out your code to help with debugging it. But they can't do that unless you post complete code. That doesn't have to be your entire code, it could be a cut-down version containing just enough code to demonstrate the problem and can be compiled.

Please do not post screen images of serial monitor, Linux terminal etc containing only text. Instead, copy the text & paste it into your post between code tags.

1 Like

This is great to know for the future, I appreciate it!

I really appreciate the help! I have amazing news! Although it was before I was able to try out the PHP/Python script, I realized that my Raspberry Pi booting into console, and not desktop, was preventing it somehow from connecting to the WiFi (wlan0 - it wasn't getting an IP), and so it was defaulting to eth.
I had a static IP address set for eth, so I figured that wouldn't be an issue - but through some inner-workings of networking that I am clueless about, that was a problem. I solved this by allowing the RPi to auto-login to desktop on boot, and changed the static IP settings to wlan0 instead of eth.

great to hear !!

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.