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

树莓派Pico实现LCD显示传感器数据及SD卡记录功能求助

问题分析与解决建议

1. 修复SD卡功能缺失问题

原代码仅导入SD卡相关库,但未完成初始化与挂载,这是无法记录数据的核心原因。需添加SD卡初始化逻辑,同时优化SPI参数提升稳定性:

# 初始化SD卡
sd = sdcard.SDCard(spi, CS)
# 挂载SD卡文件系统
vfs = uos.VfsFat(sd)
uos.mount(vfs, "/sd")

建议将SPI波特率调整为10000000(10MHz),避免低速导致的读写超时;同时确认硬件接线:CS、SCK、MOSI、MISO引脚与SD卡模块对应无误。

2. 修复LCD显示错误

  • 参数传递错误:lcd.putstr()仅接受字符串参数,原代码直接传入多个变量会报错,需将数据格式化为字符串:
    lcd_str = f"{n:4d}  {motion:d}    {voltage:.2f}    {temperature:.1f}    {RoomLit:d}"
    lcd.putstr(lcd_str)
    
  • clear方法误用:lcd.clear(0,1)不是正确调用方式,若仅需刷新第二行,可移动光标到行首后用空格覆盖原有内容;若需清屏,直接调用lcd.clear()后重新写入标题行。
  • 变量名拼写错误:n=n+timeinterval中的timeinterval应为timeintervals,否则会抛出未定义错误。

3. 修复传感器数据覆盖问题

原代码中MQ2传感器的voltage变量被温度传感器的voltage覆盖,导致MQ2数据丢失,需重命名变量区分:

# MQ2电压读取
mq2 = machine.ADC(26)
conversion_factor = 3.3 / 65535
mq2_voltage = mq2.read_u16() * conversion_factor

# 温度传感器读取
sensor = machine.ADC(4)
reading = sensor.read_u16()
temp_voltage = reading * conversion_factor
temperature = 27 - (temp_voltage - 0.706) / 0.001721
temperature = temperature * 1.8 + 32

4. 实现SD卡数据记录功能

每次采集数据后,以追加模式写入SD卡日志文件,为避免断电丢失数据,需调用flush()立即写入:

# 初始化时打开日志文件
log_file = open("/sd/sensor_log.txt", "a")
# 首次运行写入表头
log_file.seek(0, 2)
if log_file.tell() == 0:
    log_file.write("time(s),motion,mq2_voltage,temperature,light\n")
log_file.flush()

# 循环内写入数据
log_line = f"{n},{motion},{mq2_voltage:.2f},{temperature:.1f},{RoomLit}\n"
log_file.write(log_line)
log_file.flush()

5. 长期运行稳定性优化

  • 添加异常捕获:针对SD卡读写、LCD通信异常做捕获处理,避免程序崩溃:
    try:
        # 数据采集、显示、写入逻辑
    except OSError as e:
        print(f"SD卡错误: {e}")
        lcd.clear()
        lcd.putstr("SD Card Error!")
        sleep(2)
    
  • 使用硬件I2C:若引脚允许,替换SoftI2C为硬件I2C(machine.I2C(0, sda=Pin(0), scl=Pin(1))),提升LCD通信稳定性。
  • 降低LCD刷新负载:无需每次循环清屏,仅刷新数据行即可。

完整修正示例代码

from machine import Pin, SoftI2C, ADC, SPI
import utime
from pico_i2c_lcd import I2cLcd
import sdcard
import uos
from time import sleep

# LCD初始化
I2C_ADDR = 0x27
I2C_NUM_ROWS = 2
I2C_NUM_COLS = 20
i2c = SoftI2C(sda=Pin(4), scl=Pin(5), freq=400000)
lcd = I2cLcd(i2c, I2C_ADDR, I2C_NUM_ROWS, I2C_NUM_COLS)

# SD卡初始化
CS = Pin(9, Pin.OUT)
spi = SPI(1, baudrate=10000000, polarity=0, phase=0, bits=8, firstbit=SPI.MSB,
          sck=Pin(10), mosi=Pin(11), miso=Pin(8))
sd = sdcard.SDCard(spi, CS)
vfs = uos.VfsFat(sd)
uos.mount(vfs, "/sd")

# 传感器初始化
pir_sensor = Pin(28, Pin.IN)
mq2 = ADC(26)
temp_sensor = ADC(4)
ldr = ADC(27)
conversion_factor = 3.3 / 65535

# 日志文件初始化
log_file = None
try:
    log_file = open("/sd/sensor_log.txt", "a")
    log_file.seek(0, 2)
    if log_file.tell() == 0:
        log_file.write("time(s),motion,mq2_voltage,temperature,light\n")
    log_file.flush()
except OSError as e:
    print(f"SD卡初始化失败: {e}")

# 初始化变量与LCD标题
n = 0
time_intervals = 3
lcd.clear()
lcd.putstr("time motion mq2 temp light")

while True:
    try:
        # 读取传感器数据
        motion = 1 if pir_sensor.value() == 1 else 0
        mq2_voltage = mq2.read_u16() * conversion_factor
        temp_reading = temp_sensor.read_u16()
        temp_voltage = temp_reading * conversion_factor
        temperature = 27 - (temp_voltage - 0.706) / 0.001721
        temperature = temperature * 1.8 + 32
        ldr_value = ldr.read_u16()
        room_lit = 1 if ldr_value < 20000 else 0

        # 串口打印
        print(f"{n:4d}  {motion:d}    {mq2_voltage:.2f}    {temperature:.1f}    {room_lit:d}")

        # LCD刷新第二行
        lcd.move_to(0, 1)
        lcd_str = f"{n:4d}  {motion:d}    {mq2_voltage:.2f}    {temperature:.1f}    {room_lit:d}"
        lcd.putstr(lcd_str.ljust(I2C_NUM_COLS))

        # SD卡写入
        if log_file:
            log_line = f"{n},{motion},{mq2_voltage:.2f},{temperature:.1f},{room_lit}\n"
            log_file.write(log_line)
            log_file.flush()

        n += time_intervals
        sleep(time_intervals)

    except OSError as e:
        print(f"SD卡错误: {e}")
        lcd.clear()
        lcd.putstr("SD Card Error!")
        sleep(2)
        lcd.clear()
        lcd.putstr("time motion mq2 temp light")
    except Exception as e:
        print(f"系统错误: {e}")
        sleep(1)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 04:00:58