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

PLC与Raspberry Pi信号交互触发Python脚本循环运行方案咨询

PLC触发树莓派执行脚本实现方案

硬件连接要点

  • 优先确认PLC输出类型:如果是继电器干接点输出,接线最简单最安全,直接将输出两端分别接树莓派选定的GPIO引脚、GND引脚即可,不需要额外电平转换。
  • 如果是晶体管型24V输出,必须加装24V转3.3V光耦隔离模块,绝对不能直接把24V信号接到树莓派GPIO上,否则会直接烧毁引脚甚至整板;光耦还能隔绝工厂现场的电磁干扰,大幅降低死机、误触发概率。
  • 接线时必须保证PLC侧和树莓派侧共地,否则电平参考不一致,会出现信号检测不准的问题;GPIO引脚优先选没有默认复用I2C、SPI功能的通用引脚,比如BCM编码的17号引脚,避免和其他硬件功能冲突。

软件实现核心逻辑

不要用轮询扫引脚的方式,资源占用高响应还慢,直接用GPIO边沿中断做触发,同时加两层防护避免异常:

  • 第一层是硬件/软件防抖,过滤PLC触点抖动、电磁干扰产生的尖峰误触发信号。
  • 第二层是运行状态锁,脚本执行过程中直接忽略新的触发请求,避免重复启动脚本占满系统资源,等当前工作周期完全结束、脚本退出后再释放锁,回到等待状态。
  • 依赖安装直接执行命令:sudo apt update && sudo apt install python3-rpi.gpio,不需要额外装第三方库;把运行监听服务的用户加入gpio组就能访问GPIO,不用长期用root权限跑服务,命令是sudo usermod -aG gpio 你的当前用户名。

参考实现代码

将下面的代码保存为plc_listener.py,记得修改里面的引脚号、目标脚本路径为你自己的实际配置:

import RPi.GPIO as GPIO
import subprocess
import time
import threading

# 配置参数
TRIGGER_PIN = 17  # 对应BCM编码的GPIO引脚号
BOUNCE_DURATION = 200  # 防抖时长,单位毫秒
WORK_SCRIPT_PATH = "/home/pi/your_preset_work.py"  # 要触发的Python脚本绝对路径

# 运行锁,防止重复执行
task_running = False

def execute_work_script():
    global task_running
    try:
        # 调用子进程执行目标脚本,阻塞等待执行完成
        exec_result = subprocess.run(
            ["python3", WORK_SCRIPT_PATH],
            capture_output=True,
            text=True
        )
        print(f"[{time.ctime()}] 工作脚本执行结束,返回码:{exec_result.returncode}")
        if exec_result.returncode != 0:
            print(f"脚本异常信息:{exec_result.stderr}")
    finally:
        # 无论脚本正常结束还是抛错,都释放运行锁,避免服务卡死
        task_running = False

def trigger_handle(channel):
    global task_running
    # 短延时后二次确认电平,过滤短脉冲干扰
    time.sleep(0.05)
    if GPIO.input(channel) == GPIO.HIGH and not task_running:
        task_running = True
        print(f"[{time.ctime()}] 检测到PLC触发信号,启动工作流程")
        # 开独立子线程跑任务,不阻塞GPIO中断监听
        task_thread = threading.Thread(target=execute_work_script, daemon=True)
        task_thread.start()

if __name__ == "__main__":
    try:
        GPIO.setmode(GPIO.BCM)
        # 配置引脚为输入模式,默认下拉,触发时输入高电平
        GPIO.setup(TRIGGER_PIN, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
        # 注册上升沿中断触发
        GPIO.add_event_detect(
            TRIGGER_PIN,
            GPIO.RISING,
            callback=trigger_handle,
            bouncetime=BOUNCE_DURATION
        )
        print("监听服务启动,等待PLC触发信号...")
        # 主线程保活
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        print("服务被手动终止")
    finally:
        GPIO.cleanup()

开机自启配置

用systemd托管监听服务是最稳的方式,开机自动启动,服务异常退出还能自动拉起,不要用老旧的rc.local方案:

  1. 新建服务配置文件,执行命令:sudo nano /etc/systemd/system/plc_listen.service
  2. 写入以下配置,把用户名、脚本路径替换成你的实际值:
[Unit]
Description=PLC Signal Listener Service
After=multi-user.target

[Service]
User=pi
WorkingDirectory=/home/pi
ExecStart=/usr/bin/python3 /home/pi/plc_listener.py
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target
  1. 执行以下命令加载配置、设置开机自启并启动服务:
sudo systemctl daemon-reload
sudo systemctl enable plc_listen.service
sudo systemctl start plc_listen.service
  1. 实时查看服务运行日志用命令:journalctl -u plc_listen.service -f,出问题直接看日志排查。

常见避坑点

  • 光耦隔离必须加,工厂现场电磁环境复杂,没隔离的话树莓派很容易死机、误触发,甚至被浪涌打坏。
  • 你自己写的业务工作脚本不要写死无限循环,必须保证一个工作周期结束后能正常退出,否则运行锁会一直被占用,后续触发信号不会有响应。
  • 如果需要给PLC反馈工作状态,可以多接一个GPIO引脚连到PLC输入点,脚本启动时输出高电平、执行完成后输出低电平,PLC就能实时知道树莓派当前是忙还是空闲,避免重复发信号。
  • 不要把防抖时间设太短,一般PLC继电器触点抖动在几十毫秒级,设200ms足够过滤,不会影响正常响应速度。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 17:25:02