ESP32+SIM7600E模块向Firebase实时数据库发送HTTPS POST请求失败,报+HTTP_PEER_CLOSED错误求助
看起来你已经卡在这个问题一周了,先给你梳理下从你提供的代码和输出里发现的几个关键问题,一步步来解决:
首先看你的输出,转成HTTPS后得到了+HTTPACTION: 1,400,77,这个400错误是Bad Request,说明你的请求格式或者参数有问题,而不是单纯的SSL连接问题。结合你的代码,我们来逐个排查:
1. 你的command函数有致命缺陷,导致看不到完整的模块响应
你当前的command函数只读取一次模块的响应就break了,但SIM7600很多命令的响应是分多行返回的(比如AT+HTTPACTION=1会先返回OK,之后才返回+HTTPACTION: 1,xxx,xxx),这会导致你漏掉关键的错误信息,调试起来非常麻烦。先把这个函数改了:
void command(String command, unsigned long timeout = 1000) { sim.println(command); unsigned long startTime = millis(); String response = ""; // 在超时内持续读取所有可用的响应数据 while (millis() - startTime < timeout) { while (sim.available()) { response += sim.readString(); } } if (response.length() > 0) { Serial.println(response); } }
这个修改后的函数会把模块所有的响应都读出来打印,方便你看到完整的命令执行结果,不会再漏掉关键信息。
2. SSL配置命令执行失败,导致HTTPS连接存在隐患
看你的输出里AT+CSSLCFG="seclevel",0,2返回了ERROR,但你的代码里写的是AT+CSSLCFG="seclevel",0,0——这里可能是复制粘贴的问题?不管怎样,SIM7600的seclevel参数取值是0、1、2:0表示不验证服务器证书,1验证服务器证书,2是双向验证。你需要确保这条命令执行成功,比如改成:
command("AT+CSSLCFG=\"seclevel\",0,1", 2000); // 用1更安全,若暂时不想验证证书可换0,但必须确保返回OK
另外,你设置的AT+CSSLCFG="sslversion",0,3是指定TLSv1.2,这个是对的,因为Firebase只支持TLSv1.2及以上版本,没问题。
3. HTTP请求的字节数不匹配,这是400错误的核心原因
你用了AT+HTTPDATA=35,10000,但你实际发送的JSON是{"message":"test from SIM7600"},这个字符串的实际字节数是31(数一下:{"message":"test from SIM7600"}一共31个字符,包括大括号、引号)。SIM7600的AT+HTTPDATA命令第一个参数必须和你要发送的字节数完全一致,否则服务器会认为你的请求不完整,直接返回400错误。
把这条命令改成:
sim.println("AT+HTTPDATA=31,10000");
之后如果修改JSON内容,一定要重新计算字节数,确保和参数一致。
4. 检查Firebase的URL和Auth参数的有效性
- 确认你的Firebase数据库URL格式正确:必须以
.json结尾,比如https://your-project-id.firebasedatabase.app/test.json - 确认
auth参数正确:如果用的是数据库的「秘密」(从Firebase控制台→项目设置→服务账户→数据库秘密),或者是有效的用户ID Token,要确保这个密钥没有过期,并且有写入/test路径的权限。
5. 调整HTTP请求的流程,确保步骤正确
修改后的upload函数大概是这样的,你可以参考:
void upload() { // 配置SSL参数 command("AT+CSSLCFG=\"sslversion\",0,3", 2000); // 指定TLSv1.2 command("AT+CSSLCFG=\"ignorelocaltime\",0,1", 2000); // 模块无RTC时必须开启,忽略本地时间 command("AT+CSSLCFG=\"seclevel\",0,1", 2000); // 安全级别1,确保返回OK // 初始化HTTP服务 command("AT+HTTPINIT", 5000); // 设置请求URL command("AT+HTTPPARA=\"URL\",\"https://DB-URL-STUFF.firebasedatabase.app/test.json?auth=AUTH-KEY\"", 2000); // 设置Content-Type为JSON command("AT+HTTPPARA=\"CONTENT\",\"application/json\"", 2000); // 发送HTTPDATA命令,等待模块返回DOWNLOAD提示 sim.println("AT+HTTPDATA=31,10000"); delay(2000); String response = ""; unsigned long startTime = millis(); // 等待模块返回DOWNLOAD,超时10秒 while (millis() - startTime < 10000) { while (sim.available()) { response += sim.readString(); if (response.indexOf("DOWNLOAD") != -1) { Serial.println("收到DOWNLOAD提示,开始发送JSON..."); // 发送JSON数据 sim.println("{\"message\":\"test from SIM7600\"}"); delay(1000); // 发送Ctrl+Z(ASCII 26)表示数据发送完成 sim.write(0x1A); delay(3000); // 读取发送后的响应 while (sim.available()) { Serial.println(sim.readString()); } break; } } } // 执行POST请求(1代表POST方法) command("AT+HTTPACTION=1", 10000); // 读取服务器响应内容 command("AT+HTTPREAD", 5000); // 关闭HTTP服务 command("AT+HTTPTERM", 2000); }
最后再试一次的步骤:
- 把上面的修改都应用到代码里
- 重新上传到ESP32
- 打开串口监视器,看每一条AT命令的响应,确保所有SSL配置命令都返回
OK,没有ERROR - 执行到
AT+HTTPACTION=1后,如果返回+HTTPACTION: 1,200,xx,说明请求成功了,Firebase那边就能收到数据了
如果还是有问题,把完整的串口输出发出来,我们再进一步排查。
内容来源于stack exchange

