嵌入式人工智能(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()

最终实验结果:

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

  • 15
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值