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.
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
}
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.
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?
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.