Rest API: HTTP GET Request

Hello all,

I am using an ESP32 to call three webpages (rest API), but I am having a frustrating amount of trouble getting the HTTPClient library to cooperate. Specifically, I can't even get past the http.GET() instruction (code below).

#include <WiFi.h> // ESP32's WiFi library
#include <HTTPClient.h> // ESP32's HTTPClient library

HTTPClient webpageProgram; // object for interacting with the programming webpage
programAddress = "https://xxxxxxxxxxxxxx.php?unit=123&status=P"; // URL hidden for privacy

bool doSomething(void)
{
  bool somethingDone= false; // flag raised whenever something has been done
  String payloadProgram; // variable to hold response from webpage

  if(!webpageProgram.begin(programAddress.c_str())) // connect to the webpage
  {
    Serial.println("Failed to connect to the webpage. GOOD-BYE!");
    while(true);
  }
  delay(100);
  httpResponseCode = webpageProgram.GET(); // send the HTTP GET request to the webpage
  if (httpResponseCode > 0) // check for a successful HTTP GET request
  {
    if (httpResponseCode == HTTP_CODE_OK) // if a file has been found
    {
      payloadProgram = webpageProgram.getString(); // get the payload
    }
  }
  else
  {
    Serial.print("INVALID HTTP GET REQUEST (error code: "); Serial.print(httpResponseCode); Serial.println("). GOOD-BYE!");
    while(1);
  }
  webpageProgram.end(); // free webpage
  return somethingDone;
}

All I'm doing in setup() is calling this function "doSomething()," and it always fails with httpCode = -1. I've grown very frustrated trying to figure it out on my own, so I thought I would pass it on to the ESP32 gurus and see if y'all see my problem.

Thanks to all in advance.

the full code would help. Don't post snippets (Snippets R Us!)

The current program is massive, so I'll just post the relevant snippets.

// Libraries
  #include <WiFi.h> // ESP32's WiFi library
  #include <HTTPClient.h> // ESP32's HTTPClient library>
  #include <ArduinoJson.h> // Arduino's JSON library

// ESP32's Internet Information
  const char* SSID = "xxxx"; // WiFi SSID name
  const char* password = "xxxx"; // WiFi password
  IPAddress local_IP(10,187,20,100); // ESP32's IP Address
  IPAddress gateway(10,187,19,1); // gateway
  IPAddress subnet(255, 255, 0, 0); // set subnet

// Operational Variables
  uint32_t WiFiTimeoutCounter = 0; // Connect to WiFi timeout counter
  bool connectedWiFi = false; // flag raised whenever the ESP32 is connected to WiFi
  String esp32MAC; // MAC address of ESP32

// Objects
  HTTPClient webpageProgram; // object for interacting with the programming webpage
  HTTPClient webpageStatusSend; // object for interacting with the status webpage
  HTTPClient webpageStatusRequest; // object for polling the status webpage
  JsonDocument jsonDocRec; // object for interacting with the received JSON document data from the webpage
  char* jsonKeyVal = ""; // the value of a key from the JSON doc
  String webpageData = ""; // data from reading webpage

// System Variables
  String doorbellStatus = "X"; // status of doorbell
    // Status is limited to A, W, and X
      // A -> Active (green light to cross)
      // W -> Waiting for operator to acknolwedge ok to cross (no timeout)
      // X -> Red light (DO NOT CROSS)
  String unitIdentifier = ""; // identifier for this doorbell unit
  String programAddress = ""; // URL address for programming doorbell
  String statusSendAddress = ""; // URL address for setting the doorbell status
  String statusRequestAddress = ""; // URL address for polling the doorbell status

  // Diagnostics
    int httpResponseCode = 0; // code that indicates if the HTTP GET request was successful

// Flags
      bool deviceProgrammed = false; // flag raised whenever the doorbell unit has been successfully programmed on the webpage
      bool doorbellPressed = false; // flag raised whenever the doorbell is pressed
      bool programBtnPressed = false; // flag raised whenever the program button is pressed
      bool WAIT = false; // flag raised whenever a walk request has been sent but no message has been received yet (red LED blinks)
      bool WALK = false; // flag raised whenever a walk request has been granted (green LED ON and red LED OFF)

void WiFi_Connect(void)
{
  if (!WiFi.config(local_IP, gateway, subnet))
  {
    Serial.println("STA failed to configure");
  }
  //Serial.println("Setting WiFi to station mode...");
  //WiFi.mode(WIFI_STA); // set ESP32's WiFi module to station mode
  //Serial.println("Disconnecting from networks...");
  WiFi.disconnect(); // disconnect from any previous APs
  delay(100); // wait for WiFi module to initialize

  Serial.println("Connecting to WiFi..."); 
  WiFi.begin(SSID, password); // connect to WiFi

  WiFiTimeoutCounter = 0; // reset counter

  while((WiFiTimeoutCounter != 1) & (WiFiTimeoutCounter != 2)) // check WiFiTimeoutCounter's status
  {
    if (WiFi.status() != WL_CONNECTED) // if ESP32 has not connected to the WiFi
    {
      //Serial.print('.'); 
      WiFiTimeoutCounter = WiFiTimeoutCounter + 1000; // increment counter 1000 ms at a time
      delay(1000);
    }
    else
    {
      WiFiTimeoutCounter = 1; // board connected to WiFi
    }
    if (WiFiTimeoutCounter >= 15000) // if the timer has reached 15 seconds
    {
      WiFiTimeoutCounter = 2; // timeout
    }
  }
  if (WiFiTimeoutCounter == 1)
  {
    Serial.print("\nSuccessfully Connected to ");
    Serial.print(WiFi.SSID()); // print SSID of connected WiFi
    Serial.print(" with IP Address of ");
    Serial.println(WiFi.localIP()); // print WiFi information
    connectedWiFi = true; // raise flag for successfull WiFi connection
  }
  else if (WiFiTimeoutCounter == 2)
  {
    Serial.println("Connection request to WiFi timed out... Please reset and try again.");
    connectedWiFi = false; // lower flag for unsuccessfull WiFi connection
    delay(2000);
  }
  else
  {
    Serial.println("Error: Please reboot"); // error message
    while(1);
  }
  esp32MAC = WiFi.macAddress(); // get MAC address
}

void webpagesInit(void)
{
  unitIdentifier = esp32MAC; // set the ESP32's MAC address as its unit identifier
  programAddress = "https://xxx/api/Crosswalk_System/program.php?unit=123&status=P"; // URL address for programming doorbell
  statusSendAddress = "https://xxx/api/Crosswalk_System/update.php?unit=" + unitIdentifier + "\&status=" + doorbellStatus; // URL address for setting the doorbell status
  statusRequestAddress = "https://xxx/api/Crosswalk_System/status.php?unit=" + unitIdentifier; // URL address for polling the doorbell status
}

bool doorbellProgram(void)
{
  bool doorbellProgrammed = false; // flag raised whenever the device has been successfully programmed
  String payloadProgram; // variable to hold response from program command

  if(!webpageProgram.begin(programAddress.c_str())) // connect to the program webpage
  {
    Serial.println("Failed to connect to the webpage. GOOD-BYE!");
    while(true);
  }
  delay(100);
  httpResponseCode = webpageProgram.GET(); // send the HTTP GET request to the webpage
  if (httpResponseCode > 0) // check for a successful HTTP GET request
  {
    if (httpResponseCode == HTTP_CODE_OK) // if a file has been found
    {
      payloadProgram = webpageProgram.getString(); // get the payload
    }
  }
  else
  {
    Serial.print("INVALID HTTP GET REQUEST (error code: "); Serial.print(httpResponseCode); Serial.println("). GOOD-BYE!");
    while(1);
  }
  webpageProgram.end(); // free webpage

  DeserializationError error = deserializeJson(jsonDocRec, payloadProgram); // deserialize the JSON document
  if (error) // if there was an error in parsing the JSON document
  {
    Serial.println("Packet is invalid! Closing program...");
    while(1); // stop program
  }

  double programKeyVal = jsonDocRec["status"]; // save JSON value of "status
  Serial.print("jsonDocument[\"status\"]: "); Serial.println(programKeyVal);
  if (programKeyVal == 0x4F4B) // check if the status is "OK"
  {
    doorbellProgrammed = true; // doorbell device successfully programmed
  }
  else
  {
    doorbellProgrammed = false; // doorbell device NOT successfully programmed
  }
  return doorbellProgrammed; // return flag
}

void setup() 
{
  // Board Initialization
    delay(3000); // allow a few seconds for bootup
    Serial.begin(115200); // start serial monitor
  // System Initialization
    // Connect to WiFi
      WiFi_Connect(); // establish WiFi connection
      
    WAIT = false; // set system flag
    WALK = false; // set system flag

    webpagesInit(); // initialize webpage information

    while(!deviceProgrammed) // while the device is NOT programmed
    {
      deviceProgrammed = doorbellProgram(); // connect to webpage to program the device
    }
}

void loop()
{
  // nothing for now
}

is it HTTP or HTTPS that you are really using?

Sorry, it is HTTP. I had changed them to HTTPS just to make sure I wasn't going crazy.

it would not have worked with HTTPS without going for a secure connection

The webpage I'm trying to access has an HTTP address and doesn't require authentication. I've been working with the IT guys, and they said that everything seems fine on their end. Even trying this code with a test URL, the webpageProgram.GET() always returns -1.

keep things minimal at first for testing

would something like this work (typed here, mind typos)

#include <WiFi.h>
#include <HTTPClient.h>

const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
String serverName = "http://xxx/api/Crosswalk_System/program.php";

void setup() {
  Serial.begin(115200);

  WiFi.begin(ssid, password);
  Serial.println("Connecting");
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.write('.');
  }
  Serial.print(" => Connected to WiFi network with IP Address: ");
  Serial.println(WiFi.localIP());

  HTTPClient http;
  String serverPath = serverName + "?unit=123&status=P";
  http.begin(serverPath.c_str());
  int httpResponseCode = http.GET();

  if (httpResponseCode > 0) {
    Serial.print("HTTP Response code: ");
    Serial.println(httpResponseCode);
    String payload = http.getString();
    Serial.println(payload);
  }
  else {
    Serial.print("Error code: ");
    Serial.println(httpResponseCode);
  }
  http.end();
}

void loop() {}

I just tried this example code and still get code an error code of -1. Even though the IT guys say that everything seems alright on their end, do you think they need to fix things on their end?

what do you see if you do a

curl -X GET "http://xxx/api/Crosswalk_System/program.php?unit=123&status=P"

from a computer on the same network as your ESP32

"curl: (6) Could not resolve host: xxx.xxx.xxx.xxx"

This seems to be an issue that's not on my end, so I'll talk to the IT guys again and see what we can come up with.

ok - indeed seems routing does not work

Ok, I figured out the problem. Because of my lack of knowledge and experience with web applications, I was calling the wrong webpage address and thus wasn't receiving any information.

Instead of calling http://xxx/api/Crosswalk_System/program.php?unit=123&status=P, I should have just called http://xxx/api/Crosswalk_System/program.php?, and then read and interpret the unit=123&status=P as my returned data.

1 Like

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