如何使用Arduino Ethernet库通过POST对接Ruby on Rails API
问题排查与修复方案
我帮你梳理了几个关键问题,这些都是导致Arduino无法成功连接Rails服务器的核心原因:
1. 普通EthernetClient不支持HTTPS连接
你用的Ethernet.h里的EthernetClient是纯TCP客户端,不支持SSL/TLS加密,但你的服务器是https://spark-backend.herokuapp.com(HTTPS协议),直接连80端口(HTTP默认端口)肯定会失败。HTTPS需要用443端口,且必须使用支持SSL的客户端库。
修复方法:
替换为EthernetSSLClient库(需通过Arduino IDE库管理器安装),它是支持SSL加密的以太网客户端,能和HTTPS服务器建立连接。
2. 服务器地址与连接参数错误
你的server变量包含了https://前缀,这会让client.connect()解析失败——连接只需要纯域名,不需要协议头。同时HTTPS的默认端口是443,不是你用的80。
修复方法:
把服务器地址改成纯域名:
char server[] = "spark-backend.herokuapp.com";
连接时指定443端口:
if (client.connect(server, 443)) { ... }
3. 请求头与数据格式不匹配
你手动拼接的是JSON格式数据,但设置的Content-Type是application/x-www-form-urlencoded,这会让Rails后端无法正确解析请求体。而且你拼接的JSON还有语法错误(单引号混用、格式混乱),JSON要求键和字符串值必须用双引号。
修复方法:
- 将
Content-Type改为application/json - 用规范方式拼接JSON:
String data = "{\"parkspot_id\":\"SP001\",\"sensor_in\":\"" + String(sensorvalue) + "\",\"user_id\":\"U001\"}";
4. 缺少必要的请求头
HTTPS请求建议添加Connection: close头,告诉服务器请求结束后关闭连接,避免连接挂起导致后续请求失败。
完整修正后的代码
//------------------------------------------ // Park Sensor Prototype // Only insert if there is car parked //------------------------------------------ #include <Ethernet.h> #include <EthernetSSLClient.h> // 引入SSL客户端库 // 纯域名,去掉https://前缀 char server[] = "spark-backend.herokuapp.com"; byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; EthernetSSLClient client; // 用SSL客户端替代普通EthernetClient String data; bool flagstatus = false; void setup() { Serial.begin(9600); // 连接以太网,等待DHCP分配IP if (Ethernet.begin(mac) == 0) { Serial.println("Failed to configure Ethernet via DHCP"); // DHCP失败时可手动设置IP,示例: // Ethernet.begin(mac, IPAddress(192,168,1,177)); } // 等待以太网连接稳定 delay(1000); Serial.print("Local IP: "); Serial.println(Ethernet.localIP()); } void loop() { int sensorvalue = analogRead(A0); // 读取传感器值 // 正确拼接JSON格式数据 data = "{\"parkspot_id\":\"SP001\",\"sensor_in\":\"" + String(sensorvalue) + "\",\"user_id\":\"U001\"}"; // 检测到车辆停放 if(sensorvalue >= 1000){ if(!flagstatus){ Serial.println("Insert to DB: car just parked"); Serial.println("Data to send: " + data); // 连接HTTPS服务器(端口443) if (client.connect(server, 443)){ Serial.println("Connected to server"); // 发送POST请求头 client.println("POST /api/v1/parks HTTP/1.1"); client.print("Host: "); client.println(server); client.println("Content-Type: application/json"); client.print("Content-Length: "); client.println(data.length()); client.println("Connection: close"); // 告知服务器关闭连接 client.println(); // 空行分隔请求头与请求体 client.print(data); // 发送请求体 // 读取服务器响应(调试用) while(client.connected()){ if(client.available()){ char c = client.read(); Serial.print(c); } } client.stop(); Serial.println("\nRequest sent successfully"); } else { Serial.println("Failed to connect to server"); } flagstatus = true; } else { Serial.println("Car still parked"); } } else { Serial.println("No car parked"); flagstatus = false; } delay(10000); // 延迟10秒 }
额外调试建议
- 确保你的以太网模块支持SSL(比如W5500模块,旧款W5100可能不支持)
- 调试时保留服务器响应打印,能帮你快速排查后端是否正确接收请求
- 可添加重连逻辑,避免单次连接失败就直接放弃
内容的提问来源于stack exchange,提问作者Briant Stevanus
相关产品推荐
相关产品推荐

