I had an issue yesterday where my board couldn't connect to ngrok free app running on my local machine using the url but could with the IP address.
I also tried using the root_ca but that didn't work. Couldn't figure out what was going on. Once it resolved the IP and I included the Host: in the request everything worked fine and it was stable all night.
Below is just a test program. I pulled out the wifi/client code and just trying to test it.
Any idea?
#include <ESP8266WiFi.h>
// WiFi credentials
const char* ssid = "";
const char* password = "";
// Web server settings
const char* host = "8a15b2f181c5.ngrok-free.app"; // Your server hostname
const int httpsPort = 443;
const char* endpoint = "/weather"; // Your API
// Basic Auth credentials
const char* api_username = "";
const char* api_password = "";
void setup() {
Serial.begin(115200);
Serial.println("Weather Station Starting...");
delay(5000);
}
void loop() {
sendDataToServer(0, 0, 0);
delay(20000);
}
bool connectToWiFi() {
if (WiFi.status() == WL_CONNECTED) return true;
Serial.print("Connecting to WiFi");
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
int attempts = 0;
while (WiFi.status() != WL_CONNECTED && attempts < 20) {
delay(500);
Serial.print(".");
attempts++;
}
if (WiFi.status() == WL_CONNECTED) {
Serial.println(" Connected!");
Serial.printf("IP: %s\n", WiFi.localIP().toString().c_str());
return true;
} else {
Serial.println(" Failed to connect");
return false;
}
}
void sendDataToServer(float temperature, float humidity, int rainTips) {
if (WiFi.status() != WL_CONNECTED) {
if (!connectToWiFi()) {
Serial.println("Failed to connect to WiFi for data transmission");
return;
}
}
Serial.println("Sending data to server...");
// Create JSON payload
String payload = "{";
payload += "\"temperature\":"; payload += String(temperature, 1);
payload += ",\"humidity\":"; payload += String(humidity, 1);
payload += ",\"rain_bucket_tips\":"; payload += String(rainTips);
payload += ",\"timestamp\":"; payload += String(time(nullptr));
payload += "}";
Serial.println("Payload: " + payload);
// Test DNS resolution first
Serial.println("Testing DNS resolution...");
IPAddress serverIP;
if (WiFi.hostByName(host, serverIP)) {
Serial.printf("DNS resolved to: %s\n", serverIP.toString().c_str());
} else {
Serial.println("DNS resolution failed!");
disconnectWiFi();
return;
}
// Use WiFiClientSecure for HTTPS
WiFiClientSecure client;
client.setInsecure(); // Skip certificate validation (use for testing)
// For production, use: client.setTrustAnchors(&cert); with proper certificate
// BearSSL::X509List cert(root_ca);
// client.setTrustAnchors(&cert);
Serial.println("Attempting to connect to server...");
unsigned long connectStart = millis();
if (!client.connect(host, httpsPort)) {
Serial.println("Connection to server failed!");
Serial.printf("Connection attempt took: %lu ms\n", millis() - connectStart);
// Try to get more detailed error info
Serial.println("Trying to connect to IP directly...");
if (!client.connect(serverIP, httpsPort)) {
Serial.println("Direct IP connection also failed");
disconnectWiFi();
return;
} else {
Serial.println("Connection by IP worked.");
}
}
// Create Basic Auth header
String auth = String(api_username) + ":" + String(api_password);
String encodedAuth = base64Encode(auth);
// Create HTTP POST request
String request = "POST ";
request += endpoint;
request += " HTTP/1.1\r\n";
request += "Host: ";
request += host;
request += "\r\n";
request += "ngrok-skip-browser-warning: true\r\n"; // Skip ngrok warning page
request += "User-Agent: ESP8266-WeatherStation/1.0\r\n"; // Some servers require User-Agent
request += "Authorization: Basic ";
request += encodedAuth;
request += "\r\n";
request += "Content-Type: application/json\r\n";
request += "Content-Length: ";
request += payload.length();
request += "\r\n";
request += "Connection: close\r\n\r\n";
request += payload;
request += "\r\n";
// Send request
client.print(request);
Serial.println("Request sent");
// Read response
unsigned long timeout = millis();
while (client.available() == 0) {
if (millis() - timeout > 5000) {
Serial.println("Server timeout");
client.stop();
disconnectWiFi();
return;
}
}
// Print response
String response = "";
while (client.available()) {
response += char(client.read());
}
Serial.println("Server response:");
Serial.println(response);
// Check if response indicates success
if (response.indexOf("200 OK") > 0 || response.indexOf("201") > 0) {
Serial.println("Data sent successfully!");
} else {
Serial.println("Server returned error");
}
client.stop();
disconnectWiFi();
}
// Base64 encoding for Basic Auth
String base64Encode(String str) {
String encoded = "";
const char* chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
int i = 0;
unsigned char char_array_3[3];
unsigned char char_array_4[4];
while (i < str.length()) {
char_array_3[0] = str[i++];
char_array_3[1] = (i < str.length()) ? str[i++] : 0;
char_array_3[2] = (i < str.length()) ? str[i++] : 0;
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
char_array_4[3] = char_array_3[2] & 0x3f;
for (int j = 0; j < 4; j++) {
if (j < 4 - (3 - (str.length() - i + 3) % 3) % 3) {
encoded += chars[char_array_4[j]];
} else {
encoded += '=';
}
}
}
return encoded;
}
// Disconnect WiFi to save power
void disconnectWiFi() {
WiFi.disconnect();
WiFi.mode(WIFI_OFF);
Serial.println("WiFi disconnected for power saving");
}