Arduino中client.available()返回0的原因排查求助
排查Arduino RFID访问日志系统无法读取服务器响应的问题
我之前也碰到过类似的ENC28J60和MFRC522配合时的服务器响应问题,结合你的配置,咱们一步步排查:
1. 先确认服务器端是否正常响应
这是最基础的一步,先排除服务器的问题:
- 打开浏览器,直接访问你的PHP脚本,比如
http://你的服务器IP:100/你的脚本名.php?rfid=测试卡号 - 如果浏览器没有返回任何内容,或者显示错误,那问题出在服务器端:
- 检查PHP脚本是否有语法错误,确保有明确的输出(比如
echo "OK";) - 确认MySQL连接正常,脚本没有因为数据库操作报错而终止输出
- 检查服务器防火墙是否允许100端口的HTTP请求
- 检查PHP脚本是否有语法错误,确保有明确的输出(比如
2. 检查HTTP请求格式是否符合规范
ENC28J60对HTTP请求的格式要求很严格,格式错误会导致服务器忽略请求,自然没有响应:
- 必须包含
Host头,这是HTTP/1.1的强制要求 - 请求末尾必须有两个连续的换行符(
\r\n\r\n),用来标记请求结束 - 如果是POST请求,还要正确设置
Content-Length头
举个正确的GET请求示例:
if (client.connect(serverIP, 100)) { // 构造请求 client.print("GET /log-rfid.php?uid="); client.print(你的RFID卡号字符串); client.println(" HTTP/1.1"); client.println("Host: 192.168.1.100"); // 替换成你的服务器IP client.println("Connection: close"); // 告诉服务器请求结束后关闭连接 client.println(); // 空行,必须要有! client.flush(); // 确保所有数据都发送到网络 }
3. 优化响应读取的时机和逻辑
服务器处理请求需要时间,不要发送完请求立刻调用client.available():
- 增加超时等待,避免因为服务器响应慢导致误判
- 检查
client.connected()状态,确保连接没有提前断开
示例读取逻辑:
// 发送请求后等待响应 unsigned long timeout = millis(); while (client.available() == 0 && millis() - timeout < 5000) { delay(100); Serial.print("."); // 显示等待状态 } if (client.available() > 0) { Serial.println("\n收到服务器响应:"); while (client.available()) { char c = client.read(); Serial.print(c); } } else { Serial.println("\n未收到服务器响应"); } client.stop(); // 关闭连接
4. 彻底解决SPI总线冲突问题
虽然你修改了MFRC522的SS和RST引脚,但要确保同一时间只有一个SPI设备被选中:
- 在初始化以太网模块之前,把MFRC522的SS引脚设置为输出并拉高(
digitalWrite(MFRC522_SS_PIN, HIGH);) - 读取RFID的时候,再拉低MFRC522的SS引脚,读取完成后立刻拉高,避免干扰ENC28J60的通信
5. 检查以太网模块的初始化和连接参数
- 确认ENC28J60的CS引脚配置正确(Mega上常用Pin 53,但如果你改了要对应)
- 确保Arduino的IP、网关、子网掩码和服务器在同一网段
- 调用
Ethernet.begin()时,MAC地址不要和网络上其他设备冲突
按照这个顺序排查,基本能解决client.available()返回0的问题。
内容的提问来源于stack exchange,提问作者Nedo




