嵌入式人工智能(37-基于树莓派4B的电子罗盘传感器-HMC5883L)

1、电子罗盘传感器

电子罗盘传感器,是一种用于测量方向和航向的传感器。它能够感知地球的磁场,并根据磁场的方向来确定设备的方向。电子罗盘传感器通常包括一个磁力计和一个加速度计,用于测量磁场和设备的倾斜角度。根据测量的数据,可以计算出设备相对于地理北极的方向。电子罗盘传感器广泛应用于手机、平板电脑、导航仪等设备中,用于提供准确的方向信息和导航功能。

电子罗盘传感器可以叫电子指南针,与传统的指针式罗盘相比,电子罗盘能耗低、体积小、质量轻、精度高、可微型化、其输出信号通过处理可以实现数码显示,并传送到开发板上。

2、HMC5883L

霍尼韦尔 HMC5883L 是一种表面贴装的高集成模块,并带有数字接口的弱磁传感器芯片,应用于低成本罗盘和磁场检测领域。HMC5883L 包括最先进的高分辨率HMC118X 系列磁阻传感器,并附带霍尼韦尔专利的集成电路包括放大器、自动消磁驱动器、偏差校准、能使罗盘精度控制在1°~2°的12 位模数转换器.简易的I2C 系列总线接口。HMC5883L 是采用无铅表面封装技术,带有16 引脚,尺寸为3.0X3.0X0.9mm。HMC5883L 的所应用领域有手机、笔记本电脑、消费类电子、汽车导航系统和个人导航系统。

HMC5883L 采用霍尼韦尔各向异性磁阻(AMR)技术,该技术的优点是其他磁传感器技术所无法企及。这些各向异性传感器具有在轴向高灵敏度和线性高精度的特点.传感器带有的对于正交轴低敏感行的固相结构能用于测量地球磁场的方向和大小,其测量范围从毫高斯到 8 高斯(gauss)。 霍尼韦尔的磁传感器在低磁场传感器行业中是灵敏度最高和可靠性最好的传感器。

3、HMC5883L原理和引脚连接

HMC5883L可以读取沿x,y,z轴的地球磁感应强度,根据这些磁和函数atan2(),计算当前方位与正北方向的弧长,弧度=atan2(y,x)+ 偏角。

atan2是一个函数,在C语言里返回的是指方位角,C 语言中atan2的函数原型为 double atan2(double y, double x) ,返回以弧度表示的 y/x 的反正切。y 和 x 的值的符号决定了正确的象限。也可以理解为计算复数 x+yi 的辐角,计算时atan2 比 atan 稳定。

HMC5883L电子罗盘模块使用I2C协议与树莓派通信,该模块共有5个引脚,在上右图依为:VCC、GND、SCL、SDA 和 DRDY 引脚。其中 VCC 和 GND 为该模块的正负极,分别接树莓派的 5V 电源引脚和 GND引脚。SCL和 SDA为I2C协议的时钟线和数据线,分别接树莓派5号物理引脚(SCL引脚)和3号物理引脚(SDA引脚)。DRDY引脚为数据就绪状态信号输出引脚,可悬空。

4、实验代码与现象

通过该模块读取与正北方向的角度。代码中需要将寄存器A设置为以15Hz的默认数据输出速率,对8个样本进行平均测量,然后再使寄存器B设置增益。在模式寄存器中选择连续测量操作模式,因此模式寄存器的值变为0x00。

import time
import math
import smbus
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 

# 配置寄存器A的地址
Register_A = 0
# 配置寄存器B的地址
Register_B = 0x01
# 模式寄存器地址
Register_mode = 0x02

# X、Z和Y轴 MSB数据寄存器的地址
X_axis_H = 0x03
Z_axis_H = 0x05
Y_axis_H = 0x07

# 定义测量位置的偏角
declination = -0.00669
# 圆周率
pai = 3.14159265359

# 初始化一个bus对象
bus = smbus.SMBus(1)
# bus = smbus.SMBus(0)

# HMC5883L磁力计设备地址
HMC5883L_Address = 0x1e

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

def init():
    """初始化方法"""
    # 配置寄存器A
    bus.write_byte_data(HMC5883L_Address, Register_A, 0x70)
    # 配置寄存器B设置增益
    bus.write_byte_data(HMC5883L_Address, Register_B, 0xa0)
    # 设置操作模式
    bus.write_byte_data(HMC5883L_Address, Register_mode, 0)


def get_value(addr):
    """从传感器读取参数"""
    # 读取初始16位值
    high = bus.read_byte_data(HMC5883L_Address, addr)
    low = bus.read_byte_data(HMC5883L_Address, addr + 1)
    # 位运算
    value = ((high << 8) | low)
    # 从模块获取标记值
    if value > 32768:
        value = value - 65536
    return value


def main_loop():
    """主循环,打印读取到的数据"""
    # 初始化
    init()
    while True:
        # 读取原始值
        x = get_value(X_axis_H)
        z = get_value(Z_axis_H)
        y = get_value(Y_axis_H)
        # 计算弧度
        heading = math.atan2(y, x) + declination
        # 检查是否大于360度
        if heading > 2 * pai:
            heading = heading - 2 * pai
        # 检查标志
        if heading < 0:
            heading = heading + 2 * pai
        # 转换成角度
        heading_angle = int(heading * 180 / pai)
        print("航向角度为:%d°" % heading_angle)
        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(heading_angle), font=font, fill="white")
        time.sleep(1)

if __name__ == '__main__':
    global device
    device = load_device()
    font = ImageFont.truetype('STKAITI.TTF',17)
    try:
        main_loop()
    except KeyboardInterrupt:
        print("程序结束!")

这个航向角度是芯片x轴方向与正北方向的夹角,注意看芯片的坐标。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值