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

树莓派Zero W(Raspbian)下C与Python通信实现Flow Sensor数据交互咨询

嘿,这个需求我刚好有过类似实践,用popen(Python里对应subprocess.Popen)确实是最轻量化的方案,不用搞复杂的进程间通信框架,咱们直接拆解核心的双向通信方法就行:

核心思路:基于管道的文本/数值双向通信

本质上是让C程序后台持续运行,通过**标准输入(stdin)接收Python的请求指令,通过标准输出(stdout)**返回传感器数据,双方用简单的文本格式(比如一行一个指令/数值)来传递信息,避免解析复杂的二进制数据。

1. C程序的核心逻辑(后台待命,响应请求)

C程序要做的就是循环监听输入,收到请求后返回数据:

  • 持续读取标准输入的请求(比如"GET_DATA"这样的字符串指令)
  • 执行传感器读取逻辑,把结果输出到标准输出
  • 每次输出后必须刷新缓冲区(fflush(stdout)),不然数据会卡在缓冲区里,Python收不到
  • 支持退出指令(比如"EXIT"),方便Python关闭进程

极简核心代码片段:

#include <stdio.h>
#include <string.h>

int main() {
    char request[256];
    // 持续运行,等待请求
    while (1) {
        // 读取Python发来的一行请求
        if (fgets(request, sizeof(request), stdin) == NULL) {
            break; // 管道关闭时退出循环
        }
        // 去掉字符串末尾的换行符
        request[strcspn(request, "\n")] = '\0';
        
        // 处理请求
        if (strcmp(request, "GET_DATA") == 0) {
            // 这里替换成你的流量传感器读取逻辑,示例用固定数值
            int sensor_value = 456; 
            // 输出结果,加换行符方便Python读取
            printf("%d\n", sensor_value);
            fflush(stdout); // 必须刷新,否则数据不会立即发送
        } else if (strcmp(request, "EXIT") == 0) {
            break; // 收到退出指令,结束程序
        }
    }
    return 0;
}

2. Python端的核心逻辑(启动C进程,发请求收数据)

Python用subprocess.Popen启动C程序,同时把stdin和stdout设置为管道模式,实现双向通信:

  • 启动时指定stdin=subprocess.PIPE和stdout=subprocess.PIPE,开启文本模式(text=True)避免字节流处理
  • 发送请求时要加换行符,并且调用flush()确保数据立即发送
  • 接收数据时读取一行,解析成需要的数值类型(整数/浮点数)

极简核心代码片段:

import subprocess

# 启动编译后的C可执行文件(假设叫flow_reader)
c_process = subprocess.Popen(
    ["./flow_reader"],
    stdin=subprocess.PIPE,
    stdout=subprocess.PIPE,
    text=True  # 文本模式,直接处理字符串,不用转字节
)

# 封装请求数据的函数
def fetch_sensor_data():
    # 发送请求指令,加换行符,flush确保数据发出去
    c_process.stdin.write("GET_DATA\n")
    c_process.stdin.flush()
    # 读取返回的结果,去掉换行符后转成整数
    raw_result = c_process.stdout.readline().strip()
    return int(raw_result) if raw_result else None

# 示例用法
try:
    current_data = fetch_sensor_data()
    print(f"当前流量传感器数值:{current_data}")
finally:
    # 程序结束前,给C进程发退出指令,避免僵尸进程
    c_process.stdin.write("EXIT\n")
    c_process.stdin.flush()
    c_process.wait()

3. 必踩坑的注意事项

  • 编译C程序:在树莓派上用gcc your_c_file.c -o flow_reader编译,生成可执行文件后确保有执行权限(chmod +x flow_reader)
  • 缓冲区刷新:这是最容易卡壳的点!C端的fflush(stdout)和Python端的flush()缺一不可,否则数据会滞留在缓冲区,导致双方互相等待
  • 异常处理:Python端可以加try-except捕获进程意外退出的情况,比如检查c_process.poll()是否为None来判断进程是否存活
  • 数值扩展:如果要传递浮点数,只需要把C的printf改成"%f\n",Python那边转成float即可,文本格式兼容性极强

这样就实现了Python随时向后台C程序请求数据的双向通信,完全满足你的需求~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:14:38