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

树莓派Python多类函数问题:触摸传感器触发称重与退出逻辑实现

解决触摸传感器控制称重与退出的自动化逻辑问题

嘿,我明白你想要实现的功能:第一次触摸启动称重,第二次触摸退出程序。咱们一步步来修改你的代码,搞定这个逻辑!

首先,咱们先梳理下原代码里的几个小问题:

  • 触摸传感器的click方法只是打印"click",没有记录点击次数,也没触发对应的称重/退出动作
  • 称重的cliccato方法是个无限循环,会卡住主线程,导致无法响应第二次触摸
  • 称重逻辑里的add变量每次循环都重新创建,没法正确保存历史重量值

接下来是修改后的完整代码,我会在后面详细解释关键改动:

import time
import sys
import RPi.GPIO as GPIO
from hx711 import HX711
import threading

GPIO.setmode(GPIO.BCM)
padPin = 21
GPIO.setup(padPin, GPIO.IN)

class WeightScale:
    def __init__(self):
        self.running = False  # 标志位,控制称重循环的启停
        self.hx = None

    def init_sensor(self):
        # 初始化HX711传感器,只在第一次称重时执行一次
        self.hx = HX711(5, 6)
        self.hx.set_reading_format("LSB", "MSB")
        self.hx.reset()
        self.hx.tare()
        self.hx.set_reference_unit(-421)

    def cleanAndExit(self):
        print("Clean GPIO...")
        if self.hx:
            self.hx.power_down()  # 先关闭HX711电源
        GPIO.cleanup()
        print("Complete!")
        sys.exit()
    
    def start_weighing(self):
        if self.running:
            return  # 防止重复启动
        self.running = True
        self.init_sensor()
        weight_history = []  # 用来存储重量历史值
        max_duration = 100  # 最大称重时长100秒
        start_time = time.time()

        while self.running and (time.time() - start_time) < max_duration:
            time.sleep(0.1)
            # 获取重量值,取5次读数的平均值
            val = max(0, int(self.hx.get_weight(5)))
            weight_history.append(val)
            # 打印最新的重量值
            print(f"Latest weight: {weight_history[-1]}")
            # 休眠0.6秒后唤醒传感器
            self.hx.power_down()
            self.hx.power_up()
            time.sleep(0.6)
        
        self.running = False
        print(f"Weighing stopped. Final history: {weight_history}")

class TouchSensor:
    def __init__(self, weight_scale):
        self.weight_scale = weight_scale  # 持有WeightScale实例,方便调用方法
        self.click_count = 0  # 记录点击次数
        self.already_pressed = False  # 防止重复触发(防抖)

    def listen_clicks(self):
        while True:
            pad_pressed = GPIO.input(padPin)
            if pad_pressed and not self.already_pressed:
                self.click_count += 1
                print(f"Clicked {self.click_count} times")
                if self.click_count == 1:
                    # 第一次点击:启动称重,用线程避免阻塞主线程
                    threading.Thread(target=self.weight_scale.start_weighing, daemon=True).start()
                elif self.click_count == 2:
                    # 第二次点击:退出程序
                    self.weight_scale.cleanAndExit()
                # 防抖:防止一次长按被识别为多次点击
                self.already_pressed = True
                time.sleep(0.5)
            elif not pad_pressed and self.already_pressed:
                # 松开后重置按压状态
                self.already_pressed = False
            time.sleep(0.1)

# 初始化实例
scale = WeightScale()
touch_sensor = TouchSensor(scale)

# 启动触摸监听
touch_sensor.listen_clicks()

关键改动说明:

  • 添加点击计数与交互逻辑:在TouchSensor的构造函数里传入WeightScale实例,用click_count变量记录点击次数,第一次点击启动称重,第二次触发退出。
  • 解决称重阻塞问题:把称重逻辑放在子线程里运行,这样主线程可以继续监听触摸事件,不会被卡住;同时给WeightScale添加running标志位,方便控制称重循环的启停。
  • 优化传感器初始化与重量存储:把HX711的初始化逻辑移到单独方法,只执行一次;用weight_history列表统一保存重量值,避免每次循环重建列表。
  • 防抖处理:加入already_pressed变量,防止一次长按被识别为多次点击,提升触摸触发的稳定性。
  • Python3兼容:将原Python2风格的print语句改为Python3格式,如果你仍在使用Python2,可以改回原写法。

现在你运行这个代码,第一次触摸传感器会启动后台称重,第二次触摸就会自动清理GPIO并退出程序啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:08:37