ESP8266无法连接HTTPS服务器,GPIO远程控制失效求助
问题概述
我有一块ESP8266模块,想要通过网页切换GPIO2的状态。因为使用的000webhost服务器是HTTPS协议,我写了对应的Arduino代码,但运行后没有任何有效响应,串口只显示模糊内容。需要解决这个问题,可提供PHP代码。
我的Arduino代码如下:
#include <ESP8266WiFi.h> #include <ESP8266HTTPClient.h> #include <WiFiClientSecureBearSSL.h> #include <Arduino_JSON.h> #include <WiFiClient.h> const char* ssid ="***"; const char* password ="*****"; const char* serverName = "https://ppcesp8266.000webhostapp.com/esp-outputs-action.php?action=outputs_state&board=1"; // Update interval time set to 5 seconds const long interval = 5000; unsigned long previousMillis = 0; String outputsState; void setup() { Serial.begin(115200); WiFi.begin(ssid, password); Serial.println("Connecting"); while(WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(""); Serial.print("Connected to WiFi network with IP Address: "); Serial.println(WiFi.localIP()); } void loop() { unsigned long currentMillis = millis(); if(currentMillis - previousMillis >= interval) { // Check WiFi connection status if(WiFi.status()== WL_CONNECTED ){ outputsState = httpGETRequest(serverName); Serial.println(outputsState); JSONVar myObject = JSON.parse(outputsState); // JSON.typeof(jsonVar) can be used to get the type of the var if (JSON.typeof(myObject) == "undefined") { Serial.println("Parsing input failed!"); return; } Serial.print("JSON object = "); Serial.println(myObject); // myObject.keys() can be used to get an array of all the keys in the object JSONVar keys = myObject.keys(); for (int i = 0; i < keys.length(); i++) { JSONVar value = myObject[keys[i]]; Serial.print("GPIO: "); Serial.print(keys[i]); Serial.print(" - SET to: "); Serial.println(value); pinMode(atoi(keys[i]), OUTPUT); digitalWrite(atoi(keys[i]), atoi(value)); } // save the last HTTP GET Request previousMillis = currentMillis; } else { Serial.println("WiFi Disconnected"); } } } // Function String httpGETRequest(const char* serverName) { std::unique_ptr<BearSSL::WiFiClientSecure>client(new BearSSL::WiFiClientSecure); // Ignore SSL certificate validation client->setInsecure(); HTTPClient https; // Your IP address with path or Domain name with URL path https.begin(*client, serverName); // Send HTTP POST request int httpResponseCode = https.GET(); String payload = "{}"; if (httpResponseCode>0) { Serial.println("HTTP Response code: "); Serial.println(httpResponseCode); payload = https.getString(); } else { Serial.println("Error code: "); Serial.println(httpResponseCode); } // Free resources https.end(); return payload; }
排查与解决步骤
1. 先修正串口乱码问题
串口显示模糊内容大概率是波特率不匹配,先确认串口监视器的波特率和代码中Serial.begin(115200)完全一致。如果波特率正确,把Serial.println(outputsState);替换为逐字节打印,确保能看到服务器返回的原始数据:
Serial.print("Raw Response: "); for (int i=0; i<outputsState.length(); i++) { Serial.print(outputsState[i]); } Serial.println();
2. 修复HTTPS连接兼容性
000webhost的服务器可能使用TLS 1.2/1.3协议,ESP8266的BearSSL默认可能不兼容,需要手动指定TLS版本:
// 在client->setInsecure();之前添加以下代码 client->setTLSVersion(TLSv1_2);
另外,部分000webhost站点带Cloudflare防护,可能返回JS验证页面而非预期JSON,需要先在浏览器访问目标URL,确认返回的是纯JSON内容。
3. 验证JSON格式有效性
手动在浏览器访问https://ppcesp8266.000webhostapp.com/esp-outputs-action.php?action=outputs_state&board=1,检查返回内容是否为标准JSON(比如{"2":"1"})。如果返回HTML错误页、验证页面,说明PHP脚本存在问题,需要排查服务器端代码。
4. 优化GPIO操作逻辑
代码中每次循环都执行pinMode(atoi(keys[i]), OUTPUT);属于冗余操作,会影响稳定性,建议在setup()中提前初始化引脚:
void setup() { // ... 其他初始化代码 pinMode(2, OUTPUT); // 提前将GPIO2设为输出模式 }
5. 排查PHP脚本问题(若提供代码)
如果服务器返回非预期内容,需确认PHP脚本:
- 无语法错误,能正确处理
action和board参数 - 输出仅包含JSON,无多余空格、HTML注释或其他内容
- 设置了正确的响应头:
header('Content-Type: application/json');
6. 增加详细错误日志
在httpGETRequest函数中补充完整的响应日志,便于定位问题:
if (httpResponseCode>0) { Serial.print("HTTP Code: "); Serial.println(httpResponseCode); Serial.print("Raw Payload: "); Serial.println(payload); } else { Serial.print("HTTP Error Code: "); Serial.println(httpResponseCode); }
内容的提问来源于stack exchange,提问作者Emma_h

