Arduino HTTP Error Code -1 When Using Static IP

I am doing a project with Arduino. The project consists of using several sensors with an ESP8266 NodeMcu board. I use WifiManager for wifi configuration. Once the configuration is done, I open a portal with a static IP:

IPAddress ip(192, 168, 1, 200);
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 255, 0);

Then I activate the sensors and send the data to the server via http.

The problem is that I get an http -1 error code when i use the static IP. But if i don't use it I get HTTP code 200 (OK).

My code is:

#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h>
#include <WiFiClient.h>
#include <DNSServer.h>
#include <ESP8266WebServer.h>
#include <WiFiManager.h>
#include <DHT.h>
#include <Wire.h>
#include <ESP8266httpUpdate.h>
#include <ESP8266HTTPClient.h>
#include "MHZ19.h"                                        
#include <SoftwareSerial.h>                                // Remove if using HardwareSerial

#define RX_PIN D1                                          // Rx pin which the MHZ19 Tx pin is attached to
#define TX_PIN D2                                          // Tx pin which the MHZ19 Rx pin is attached to
#define BAUDRATE 9600 
MHZ19 myMHZ19;                                             // Constructor for library
SoftwareSerial mySerial(RX_PIN, TX_PIN);                   // (Uno example) create device to MH-Z19 serial
int contador_primera_medicion = 0;
int CO2;
int tVOC;


unsigned long getDataTimer = 0;
//TIME
unsigned long starttime;
unsigned long sampletime_ms = 600000;
unsigned long add_base_time_portal = 300000;
//TIME

//SERVER
IPAddress ip(192, 168, 1, 200);
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 255, 0);
//SERVER

//UPDATER
String last_error;
String update_status;
void update_started() {
  Serial.println("CALLBACK:  HTTP update process started");
}
void update_finished() {
  Serial.println("CALLBACK:  HTTP update process finished");
}
void update_progress(int cur, int total) {
  Serial.printf("CALLBACK:  HTTP update process at %d of %d bytes...\n", cur, total);
}
void update_error(int err) {
  Serial.printf("CALLBACK:  HTTP update fatal error code %d\n", err);
}
//UPDATER

//SEND_DATA
const char* serverName = "http://domain.com/post-esp-data.php";
String serial_numb = WiFi.macAddress();
String tipo_tabla;
//SEND_DATA

//DHT22
#define PIN_CONEXION D3// A cuál pin está conectado el lector
#define TIPO_SENSOR DHT22 // Puede ser DHT11 también
DHT dht(PIN_CONEXION, TIPO_SENSOR);
float DHThumid, DHTtempC = 0; 
//DHT22

//LED WIFI
#include <Ticker.h>
Ticker ticker;
#ifndef LED_BUILTIN
#define LED_BUILTIN 13 // ESP32 DOES NOT DEFINE LED_BUILTIN
#endif

int LED = LED_BUILTIN;

void tick()
{
  //toggle state
  digitalWrite(LED, !digitalRead(LED));     // set pin to the opposite state
}
//LED WIFI

// TCP server at port 80 will respond to HTTP requests
WiFiServer server(80);

void setup(void) {
  Serial.begin(115200);
  //setup updater
  //
  WiFi.config(ip, gateway, subnet);
  WiFi.mode(WIFI_STA);
    pinMode(LED, OUTPUT);
  // start ticker with 0.5 because we start in AP mode and try to connect
    ticker.attach(0.6, tick);
    //WiFiManager
    //Local intialization. Once its business is done, there is no need to keep it around
    WiFiManager wifiManager;
    //reset saved settings
    //wifiManager.resetSettings();
    
    //set custom ip for portal
    //wifiManager.setAPStaticIPConfig(IPAddress(10,0,1,1), IPAddress(10,0,1,1), IPAddress(255,255,255,0));

    //fetches ssid and pass from eeprom and tries to connect
    //if it does not connect it starts an access point with the specified name
    //here  "AutoConnectAP"
    //and goes into a blocking loop awaiting configuration
    wifiManager.autoConnect("O₂BASE");
    //or use this for auto generated name ESP + ChipID
    //wifiManager.autoConnect();
    //if you get here you have connected to the WiFi
    Serial.println("connected...yeey :)");
    ticker.detach();
  //keep LED on
    //Open add o2base web server
    if (!MDNS.begin("o2base")) {
      Serial.println("Error setting up MDNS responder!");
      while (1) {
        delay(1000);
      }
   }
    Serial.println("mDNS responder started");

  // Start TCP (HTTP) server
    server.begin();
    Serial.println("TCP server started");

  // Add service to MDNS-SD
   MDNS.addService("http", "tcp", 80);
   
  setup_mh_z19(); //SETUP SENSOR
  delay(4000);
  }
  
void loop(void) {
  tipo_tabla = "";
  if ((millis() - starttime) > 5000 || contador_primera_medicion == 0) {
    if ((millis() - starttime) > sampletime_ms || contador_primera_medicion == 0) {
      tipo_tabla = "historico";
    }
    run_mh_z19();
    send_data();
    contador_primera_medicion++;
  }

  if (millis()<add_o2base_time_portal){
    MDNS.update();

  // Check if a client has connected
    WiFiClient client = server.available();
    if (!client) {
      return;
    }
    Serial.println("");
    Serial.println("New client");

  // Wait for data from client to become available
    while (client.connected() && !client.available()) {
      delay(1);
    }

  // Read the first line of HTTP request
    String req = client.readStringUntil('\r');

  // First line of HTTP request looks like "GET /path HTTP/1.1"
  // Retrieve the "/path" part by finding the spaces
    int addr_start = req.indexOf(' ');
    int addr_end = req.indexOf(' ', addr_start + 1);
    if (addr_start == -1 || addr_end == -1) {
     Serial.print("Invalid request: ");
      Serial.println(req);
      return;
   }
   req = req.substring(addr_start + 1, addr_end);
   Serial.print("Request: ");
   Serial.println(req);
   client.flush();

    
   String s;
    if (req == "/") {
       s  = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\n<html class='no-js' lang='es'>";
       s += "<head>";

    //<!--- basic page needs
    //================================================== -->
    s += "<meta charset='utf-8'>";
    s += "<title>BASE</title>";    
    s += "</head></html>\r\n\r\n";
       Serial.println("Sending 200");
     } else {
       s = "HTTP/1.1 404 Not Found\r\n\r\n";
       Serial.println("Sending 404");
  }
  client.print(s);

   Serial.println("Done with client");
  if (millis()>add_o2base_time_portal - 2000){
    MDNS.end();
  }
  }
}

void setup_mh_z19()
{
  mySerial.begin(BAUDRATE);                               // (Uno example) device to MH-Z19 serial start   
  myMHZ19.begin(mySerial);                                // *Serial(Stream) refence must be passed to library begin(). 

  myMHZ19.autoCalibration();
  //Calling .begin() causes the settings to be loaded
  delay(10); //Make sure sensor had enough time to turn on. BME280 requires 2ms to start up.
  dht.begin();
}

void run_mh_z19()
{
  starttime = millis();
  if (millis() - getDataTimer >= 2000)
    {
        /* note: getCO2() default is command "CO2 Unlimited". This returns the correct CO2 reading even 
        if below background CO2 levels or above range (useful to validate sensor). You can use the 
        usual documented command with getCO2(false) */

        CO2 = myMHZ19.getCO2();                             // Request CO2 (as ppm)
        if (CO2 > 500){
          CO2 -=50;
        }
        Serial.print("CO2 (ppm): ");                      
        Serial.println(CO2);
        tVOC = 0;
        Serial.print("tVOC (ppb): ");                      
        Serial.println(tVOC);  
        
        int8_t Temp;
        Temp = myMHZ19.getTemperature();                     // Request Temperature (as Celsius)
        Serial.print("Temperature (C): ");                  
        Serial.println(Temp);                               
        DHTtempC = dht.readTemperature();
        DHThumid = dht.readHumidity();
        getDataTimer = millis();
    }

}

void send_data(){
//Check WiFi connection status
  if(WiFi.status()== WL_CONNECTED){
    WiFiClient client;
    HTTPClient http;
    
    // Your Domain name with URL path or IP address with path
    http.begin(client, serverName);
    
    // Specify content-type header
    http.addHeader("Content-Type", "application/x-www-form-urlencoded");
    
    // Prepare your HTTP POST request data
    String httpRequestData = "serial_numb=" + serial_numb + "&DHTtempC=" + String(DHTtempC)
                          + "&DHThumid=" + String(DHThumid) + "&CCS811_CO2=" + String(CO2) + "&CCS811_tVOC=" + String(tVOC) + "&update_status=" + update_status + "&tipo_tabla=" + String(tipo_tabla) +  "";
    Serial.print("httpRequestData: ");
    Serial.println(httpRequestData);
    
    // You can comment the httpRequestData variable above
    // then, use the httpRequestData variable below (for testing purposes without the BME280 sensor)
    //String httpRequestData = "api_key=tPmAT5Ab3j7F9&sensor=BME280&location=Office&value1=24.75&value2=49.54&value3=1005.14";

    // Send HTTP POST request
    int httpResponseCode = http.POST(httpRequestData);
     
    // If you need an HTTP request with a content type: text/plain
    //http.addHeader("Content-Type", "text/plain");
    //int httpResponseCode = http.POST("Hello, World!");
    
    // If you need an HTTP request with a content type: application/json, use the following:
    //http.addHeader("Content-Type", "application/json");
    //int httpResponseCode = http.POST("{\"value1\":\"19\",\"value2\":\"67\",\"value3\":\"78\"}");
        
    if (httpResponseCode>0) {
      Serial.print("HTTP Response code: ");
      Serial.println(httpResponseCode);
    }
    else {
      Serial.print("Error code: ");
      Serial.println(httpResponseCode);
    }
    // Free resources
    http.end();
  }
  else {
    Serial.println("WiFi Disconnected");
  }
}

void updater (){
      // wait for WiFi connection
  if ((WiFi.status() == WL_CONNECTED)) {

    WiFiClient client;

    // The line below is optional. It can be used to blink the LED on the board during flashing
    // The LED will be on during download of one buffer of data from the network. The LED will
    // be off during writing that buffer to flash
    // On a good connection the LED should flash regularly. On a bad connection the LED will be
    // on much longer than it will be off. Other pins than LED_BUILTIN may be used. The second
    // value is used to put the LED on. If the LED is on with HIGH, that value should be passed
    ESPhttpUpdate.setLedPin(LED_BUILTIN, LOW);

    // Add optional callback notifiers
    ESPhttpUpdate.onStart(update_started);
    ESPhttpUpdate.onEnd(update_finished);
    ESPhttpUpdate.onProgress(update_progress);
    ESPhttpUpdate.onError(update_error);

    t_httpUpdate_return ret = ESPhttpUpdate.update(client, "http://domain.com/arduino_check_updates.php");
    // Or:
    //t_httpUpdate_return ret = ESPhttpUpdate.update(client, "server", 80, "file.bin");

    switch (ret) {
      case HTTP_UPDATE_FAILED:
        Serial.printf("HTTP_UPDATE_FAILD Error (%d): %s\n", ESPhttpUpdate.getLastError(), ESPhttpUpdate.getLastErrorString().c_str());
        last_error = ESPhttpUpdate.getLastError();
        update_status = "HTTP_UPDATE_FAILD Error " + last_error + " " + ESPhttpUpdate.getLastErrorString().c_str();
        break;

      case HTTP_UPDATE_NO_UPDATES:
        Serial.println("HTTP_UPDATE_NO_UPDATES");
        update_status = "HTTP_UPDATE_NO_UPDATES";
        break;

      case HTTP_UPDATE_OK:
        Serial.println("HTTP_UPDATE_OK");
        update_status = "HTTP_UPDATE_OK";
        break;
    }
  }
}```

I don't know where to start to solve the problem. Anyone have an idea?

It would be a lot easier to help you if you told us where within the 337 lines of source code the error is being reported. There is no HTTP Error -1 so that -1 is probably defined somewhere.

Hi.

Have you ever figured out this problem? I am new to Arduino and am encountering the same -1 error code associated with the http.POST. This can't be this complicated.

Thank you.

I would tend to agree with you. It shouldn't be THAT complicated. However, as previously stated, no one here will be able to answer any question unless the code is uploaded so we can examine it. Often, the wiring schematic may also be needed. We are willing to help, but need you to help us help you by providing details. Unfortunately, my crystal ball stopped working a long time ago. I think I may need to charge its battery. :slight_smile:

If you can just copy and paste the full error message, it would be so much easier to troubleshoot.

When the code is too long and complex, what I would do is separating it to sections and trying to find the bug. This is how to assign a static IP to your ESP8266. Use this code, forget all the sensor data and try sending a simple POST request. If it works, then add another piece of that long code and try it. You'll eventually catch the error. Also recheck the wiring and connections. Most of the time, bad connections cause these kind of errors.

Good Luck!