You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

树莓派3B+通过GPIO串口与Arduino Nano通信控制继电器逻辑异常

故障可能原因汇总

1. Arduino业务代码逻辑顺序错误

你当前使用的Arduino代码中,turnOn()、turnOff()函数的执行顺序有误:先调用print()打印当前引脚状态,再执行电平切换判断。你观测到的引脚状态日志是切换前的旧状态,并非执行指令后的新状态,会误导问题判断。
同时和你之前USB通信正常的版本对比,新增的状态判断逻辑虽然本身没有语法错误,但结合串口复位问题会出现动作不符合预期的情况。

2. Python侧重复打开串口触发Arduino复位

你的Python代码serialComs函数每次接收网页请求时,都会重新打开/dev/ttyAMA0串口设备。树莓派硬件串口和Arduino Nano连接时,打开串口的动作会默认拉低Arduino的复位引脚,导致Arduino每次处理指令前都会自动重启,继电器引脚电平恢复到初始默认值(LOW),直接打乱你的控制逻辑。
这也是为什么你USB通信时没有问题:USB转串口的默认配置一般不会触发Arduino自动复位,且你当时的代码没有多余的状态判断,每次收到指令直接写电平,不受复位影响。

3. 硬件电平匹配/共地问题

GPIO串口通信对电平一致性要求很高:

  • 请确认树莓派和Arduino已经可靠共地,仅连接TX、RX两根线无法保证电平识别准确
  • 请确认你的继电器模块触发逻辑:如果是低电平触发的继电器,代码中HIGH对应关、LOW对应开,和你的预期逻辑完全相反,就会出现点击关按钮反而开继电器的异常

快速修复方案

  • 调整Arduino代码执行顺序:先执行电平切换,再打印切换后的状态;建议直接删掉冗余的状态判断逻辑,和之前USB正常的版本保持一致,收到指令直接写引脚电平
  • 修改Python代码,将串口初始化逻辑提到全局,不要每次请求都重新打开串口:
import serial
from flask import Flask, redirect

app = Flask(__name__)
# 全局仅初始化一次串口
ser = serial.Serial('/dev/ttyAMA0',9600 , timeout=1)
ser.flush()

@app.route('/light/on')
def lights_on():
    line = serialComs(b"on\n")
    return redirect('/' + str(line))


@app.route("/light/off")
def lights_off():
    line = serialComs(b"off\n")
    return redirect('/' + str(line))


@app.route("/<line>")
def lights(line):
    print("The Light Is Now " + line)
    return str(line)

def serialComs(state):
    ser.write(state)
    line = ser.readline().decode('utf-8').rstrip()
    return line

if __name__ == '__main__':
    app.debug = True
    app.run()
  • 检查硬件接线,确认树莓派GND和Arduino GND已经可靠连接,确认继电器触发逻辑和代码电平匹配

内容的提问来源于stack exchange,提问作者Christiaan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 21:54:03