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

树莓派4使用Python spidev与MCP3008时出现Segmentation fault错误

解决Segmentation Fault及脚本启动问题

你的代码存在几个关键错误,这些是导致段错误和无法启动的核心原因,以下是逐一修正方案:

1. 修复SPI传输函数调用错误

spidev.SpiDev.xfer()的参数应为字节列表,而非三个独立整数。MCP3008的正确读取逻辑是发送包含3个字节的指令:

  • 第一个字节:1(起始位)
  • 第二个字节:(8 + 通道号) << 4(通道选择,比如通道0对应128、通道3对应176)
  • 第三个字节:0(填充位,用于接收数据)

错误写法:

answerV = spi.xfer(1,128,0)
answerC = spi.xfer(1,176,0)

正确写法:

answerV = spi.xfer([1, 128, 0])
answerC = spi.xfer([1, 176, 0])

2. 修复函数缩进错误

get_voltage()中的return voltage_measurement缩进错误(位于函数外部),会触发语法错误,需缩进至函数内部:

修正后:

def get_voltage():
    answerV = spi.xfer([1, 128, 0])
    if 0 <= answerV[1] <= 3:
        voltage_measurement = ((((answerV[1] * 256) + answerV[2]) * 0.00322) * 90) // 40
        print(voltage_measurement, " V")
    return voltage_measurement

3. 修复变量未定义问题

  • get_current()中,若第一个if条件不满足,current_measurement会未定义就返回,需提前初始化默认值:
def get_current():
    current_measurement = 0  # 初始化默认值
    answerC = spi.xfer([1, 176, 0])
    if 0 <= answerC[1] <= 3:
        current_measurement = ((answerC[1] * 256) + answerC[2]) * 0.00322 * 0.066
        print(current_measurement, " A")
    if ((answerC[1] * 256) + answerC[2]) * 0.00322 == 2:
        current_measurement = 0
    return current_measurement
  • 主循环中p变量未定义,需先调用get_power()计算功率:
while True:
    tm = get_time()
    i = get_current()
    v = get_voltage()
    p = get_power(v, i)  # 新增该行
    writer.writerow([tm, v, i, p])
    time.sleep(1)

4. 优化文件写入逻辑

直接open("data.csv", "w")可能导致数据缓冲无法及时写入,建议用with语句管理文件,确保正确打开/关闭,同时手动触发刷新:

# 替换原writer初始化及主循环代码
with open("data.csv", "w", newline='') as f:
    writer = csv.writer(f)
    writer.writerow(["time", "voltage", "current", "power"])
    
    while True:
        tm = get_time()
        i = get_current()
        v = get_voltage()
        p = get_power(v, i)
        writer.writerow([tm, v, i, p])
        f.flush()  # 确保数据立即写入文件
        time.sleep(1)

5. 调整SPI速度(可选)

MCP3008支持最高1MHz的SPI速度,原代码5000Hz过低,可调整为更合理的值:

spi.max_speed_hz = 100000  # 100kHz,兼顾稳定性和速度

完整修正后的代码

import spidev
import time
import csv
import datetime as dt

spi = spidev.SpiDev()
spi.open(0, 1)
spi.max_speed_hz = 100000

def get_time():
    tm = dt.datetime.now().strftime("%d.%m.%Y-%H:%M")
    return tm

def get_voltage():
    voltage_measurement = 0
    answerV = spi.xfer([1, 128, 0])
    if 0 <= answerV[1] <= 3:
        voltage_measurement = ((((answerV[1] * 256) + answerV[2]) * 0.00322) * 90) // 40
        print(voltage_measurement, " V")
    return voltage_measurement

def get_current():
    current_measurement = 0
    answerC = spi.xfer([1, 176, 0])
    if 0 <= answerC[1] <= 3:
        current_measurement = ((answerC[1] * 256) + answerC[2]) * 0.00322 * 0.066
        print(current_measurement, " A")
    # 替换浮点数精确比较,改用范围判断避免精度问题
    raw_voltage = ((answerC[1] * 256) + answerC[2]) * 0.00322
    if abs(raw_voltage - 2) < 0.01:
        current_measurement = 0
    return current_measurement

def get_power(v, i):
    return v * i

with open("data.csv", "w", newline='') as f:
    writer = csv.writer(f)
    writer.writerow(["time", "voltage", "current", "power"])
    
    while True:
        tm = get_time()
        i = get_current()
        v = get_voltage()
        p = get_power(v, i)
        writer.writerow([tm, v, i, p])
        f.flush()
        time.sleep(1)

注:原代码中浮点数==2的判断可能因精度问题失效,改用范围判断更可靠。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 10:07:48