嵌入式人工智能(36-基于树莓派4B的压力传感器-HX711)

力是引起物质运动变化的最直接原因,如果要精确地检测力的值,需要借助传感器来实现。力传感器是将力的值转换为相关电信号的器件,它能够检测张力、拉力、压力和应变等力学量,具体器件有力敏元件、转换元件和电路部分等。

1、压力传感器

压力传感器是能感受压力信号,并按照一定的规律将压力信号转换成可用于输出的电信号的器件或装置。常见的压力传感器通常由压力敏感元件和信号处理单元组成。其中信号处理单元内部线路用惠斯通电桥,当压力敏感元件承受载荷产生变形时,电阻应变片(转换元件)受到拉伸或压缩应片变形后,它的电阻将发生变化,从而使电桥失去平衡,产生相应的差动信号,供后续的信号处理单元进行测量和处理。但树莓派无法直接处理这样的信号,还需借助专门的AD转换器芯片进行转换,本文介绍一种常见的转换器芯片 HX711。

2、HX711

HX711 是一款专为高精度电子秤设计的24位AD转换器芯片。与同类型其他芯片相比,该芯片集成了包括稳压电源、片内时钟振荡器等其他同类型芯片所需要的外围电路,具有集成度高、响应速度快、抗干扰性强等优点,降低了电子秤的整机成本,提高了整机的性能和可靠性。芯片内提供的稳
压电源可以直接向外部传感器和芯片内的 AD转换器提供电源,系统板上无须另外的模拟电源。芯片内的时钟振荡器不需要任何外接器件,上电自动复位功能也简化了开机的初始化过程。组装后的5KG压力传感器和HX711模块如图所示。

 3、与树莓派连接

HX711模块共有左右两排引脚,其中左侧共有6个引脚。
E+:接桥式传感器的激励电压正,红线
E-:接桥式传感器的激励电压负,黑线。
A-:接桥式传感器的输出电压负,白线。
A+:接桥式传感器的输出电压正,绿/蓝线。
B-:接另一个桥式传感器的输出电压负,白线。
B+:接另一个桥式传感器的输出电压正,绿/蓝线,
右侧共有4个引脚:
GND:电源地。
DT:数据线。
SCK:时钟线。
VCC:电源正,5V输入。
接好压力传感器和 HX711 模块,再将该模块与树莓派连接,其中 VCC 和 GND 分别接树莓派电源5V引脚和 GND 引脚,DT 和 SCK 分别接树莓派的 29 号物理引脚(GPIOS5引脚)和 31号物理引脚
(GPIO6引脚)。

4、实验代码与现象

import time
import RPi.GPIO as GPIO
from PIL import Image  
from PIL import ImageDraw
from PIL import ImageFont
import RPi.GPIO as GPIO
import luma.oled as oled  
from luma.core.interface.serial import i2c    
from luma.oled.device import ssd1306  
from luma.core.render import canvas
  
WIDTH=128
HEIGHT=64 


# 设置使用的引脚
DT = 29
SCK = 31

def load_device():
    # 创建I2C接口对象  
    serial = i2c(port=1, address=0x3C)  # 地址可能因显示屏型号而异,由命令行“sudo i2cdetect -y 1”得到
    # 创建OLED设备对象  
    device = ssd1306(serial, WIDTH, HEIGHT) 
    return device 

def init():
    """初始化方法"""
    # 忽略警告
    GPIO.setwarnings(False)
    # 设置编号方式
    GPIO.setmode(GPIO.BOARD)
    # 设置为输出模式
    GPIO.setup(SCK, GPIO.OUT)


def get_count():
    """从传感器读取参数"""
    count = 0
    GPIO.setup(DT, GPIO.OUT)
    GPIO.output(DT, 1)
    GPIO.output(SCK, 0)
    GPIO.setup(DT, GPIO.IN)
    # 检测DT是否有高电平
    while GPIO.input(DT) == 1:
        continue
    for i in range(24):
        GPIO.output(SCK, 1)
        count = count << 1
        GPIO.output(SCK, 0)
        time.sleep(0.001)
        if GPIO.input(DT) == 0:
            count = count + 1
    GPIO.output(SCK, 1)
    # 清除第24位
    count = count ^ 0x800000
    GPIO.output(SCK, 0)
    return count


def main_loop():
    global device
    device = load_device()
    font = ImageFont.truetype('STKAITI.TTF',17)
    # 初始化
    init()
    while True:
        count = get_count()
        print("重量为:", count)
        with canvas(device) as draw:
            draw.rectangle(device.bounding_box, outline=0, fill=0)
            draw.text((0,0), "物体称重:",font=font, fill='white')
            draw.text((10,20), str(count), font=font, fill="white")
        time.sleep(2)


if __name__ == '__main__':
    try:
        main_loop()
    except KeyboardInterrupt:
        print("程序结束!")
    finally:
        GPIO.cleanup()

结果下来重量为: 8419974,简直不忍直视,看来是没有校准的原因,差别真大啊。

以下是校准使用的HX711压力传感器方法。

(1)到github下载校准程序。

git clone https://github.com/tatobari/hx711py,可惜的是下载不了。只好求助一些歪门了。

网易UU加速器——不止快,还很稳

登录后搜索学术,你懂的,加速下学习资源。

(2)将压缩包ftp到开发板解压,修改里面的example.py文件

修改里面的referenceUnit ,先改为1,然后将一罐330ml的物体,或者其他已知重量的东西放上得到一个固定值,这个值可能很大,也可能是负数,不过没有关系,重要的是物体要放在电子秤中心要稳当不要倾斜,我得到的这个值是66450,如果有负号去掉。

66450/330(已知物体的重量)=201.36

这个值就是要修改的最终参考值,也就是校准值。修改example文件。回头我们要改程序,但是我还是发现第二次称重和第一次有误差,差距不小。主要原因是电子称盘下面的螺丝导致每次放物体不能均匀受力,其次多调整几次参考值,一定要先不要放东西,然后再放东西。这个调整挺麻烦的,毕竟这玩意就当一乐吧,要是用来卖黄金,能被人打死。

(3)最终的程序

这里需要引用下载压缩包里面的函数hx711.py,和重新写的程序放在一个目录下。

import time
import sys
import RPi.GPIO as GPIO
from hx711 import HX711
from PIL import Image  
from PIL import ImageDraw
from PIL import ImageFont
import RPi.GPIO as GPIO
import luma.oled as oled  
from luma.core.interface.serial import i2c    
from luma.oled.device import ssd1306  
from luma.core.render import canvas
  
WIDTH=128
HEIGHT=64 


def load_device():
    # 创建I2C接口对象  
    serial = i2c(port=1, address=0x3C)  # 地址可能因显示屏型号而异,由命令行“sudo i2cdetect -y 1”得到
    # 创建OLED设备对象  
    device = ssd1306(serial, WIDTH, HEIGHT) 
    return device 

def hx711_Init():
    global hx
    hx = HX711(5, 6)
    hx.set_reading_format("MSB", "MSB")
    referenceUnit =228
    hx.set_reference_unit(referenceUnit)
    hx.reset()
    hx.tare()
    print("Tare done! Add weight now...")


def main_loop():
    global device
    device = load_device()
    font = ImageFont.truetype('STKAITI.TTF',17)
    # 初始化
    hx711_Init()
    while True:
        val = int(abs(hx.get_weight(5)))
        print(val)
        print("重量为:", val)
        with canvas(device) as draw:
            draw.rectangle(device.bounding_box, outline=0, fill=0)
            draw.text((0,0), "物体称重:",font=font, fill='white')
            draw.text((10,20), str(val), font=font, fill="white")
            draw.text((30,20), "克", font=font, fill="white")
        time.sleep(2)


if __name__ == '__main__':
    try:
        main_loop()
    except KeyboardInterrupt:
        print("程序结束!")
    finally:
        hx.power_down()
        hx.power_up()
        time.sleep(0.1)
        GPIO.cleanup()

最终实验结果:

这个实验给我累坏了,不搞了。

### 压力传感器的工作原理 压力传感器依据不同类型的物理现象设计而成,其中最广泛应用的是压阻式压力传感器[^1]。这种传感器依赖于材料的电阻随所受应力的变化而改变的现象——即所谓的压阻效应。当施加外力时,传感元件发生形变,导致其内部结构中的电阻发生变化。 对于扩散硅压力传感器而言,工作机理同样基于压阻效应。具体来说,待测介质的压力直接作用在由不锈钢或陶瓷制成的膜片上,引起与该压力成比例的小幅度变形。这使得安装在其上的敏感组件(通常是掺杂有杂质形成特定电阻特性的硅片)经历相应的电阻变动。随后,配套电路会捕捉到这个细微变化并将其转化为标准电信号输出给外部设备处理分析[^2]。 ### 应用领域 由于具备成本低廉、精确度高以及良好的线性响应等特点,上述提到的压阻式压力传感器被广泛应用于工业自动化控制过程监控等多个方面;而在医疗保健行业里,则可用于监测血压等生理参数;另外,在汽车制造中也发挥着重要作用,比如用于ABS防抱死制动系统的液压感应部分等等。 ```python # Python代码示例展示如何读取来自模拟输入端口连接的压力传感器数值 import spidev import time spi = spidev.SpiDev() spi.open(0, 0) def readadc(channel): r = spi.xfer2([1,(8+channel)<<4,0]) adcout = ((r[1]&3) << 8) + r[2] return adcout while True: value = readadc(0) voltage = (value * 3.3) / 1024 pressure = some_conversion_function(voltage) # 将电压转换为实际压力值 print(f"Pressure: {pressure} Pa") time.sleep(0.5) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值