首页 > 其他分享 >#打卡不停更#【FFH】OpenHarmony设备开发(六)-红外温度传感器

#打卡不停更#【FFH】OpenHarmony设备开发(六)-红外温度传感器

时间:2022-10-08 12:01:46浏览次数:83  
标签:OpenHarmony 温度传感器 uint8 crc GPIO 打卡 I2C data

前言

最近的一个项目需要用到红外温度传感器,便想着能不能在Hi3861上开发这个外设,经过摸索了一阵子,终于把红外温度传感器简单的开起来了,后面还会追加对传感器的使用。

本次使用开发板:HiSpark_WiFi_IoT

红外温度传感器

介绍

红外温度传感器应用广泛,在疫情期间可做体温测量,在汽车上可做空调控制、防雾应用,在家庭中可做家电温度控制等等。

MLX90614是一款红外非接触温度计(下文多以gy906简称)。TO-39金属封装里同时集成了红外感应热电堆探测器芯片和信号处理专用集成芯片。用以阻碍可见光和近红外光辐射的光学滤波器(可传播长波)集成在封装内提供对环境和日光的免疫。需注意的是封装内部的温差会影响温度计测量的精度,需要尽量将传感器和环境隔离。

image.png

协议

查阅文档时,发现这个红外温度传感器是使用SMBus通信协议或者PWM(默认SMBus输出格式),其中SMBus协议需要IO口设置为开漏输出,在Hi3861的IO口模式选择中并未发现有开漏输出选项,因此暂时不选择SMBus协议

image.png

通过摸索了一大阵子得知,SMbus 规格是由 I2C 简化而来。两条信号线为 SMBCLK 和 SMBDATA. 这和 I2C 上的 Clock(SCL) 和 Data(SDA) 是一样的。SMBus的读取数据格式与I2C协议大差不差,差别只在于电平认定。

image.png

两者协议的电平认定虽有不同,但也有部分交集。

I2C协议中有两者电平认定:相对认定和绝对认定,其中的相对认定是依据Vdd的电压来决定,高电平为0.7 Vdd,低电平低于0.3 Vdd即可。

再看一看红外温度传感器上的SMBus协议(如下图),高电平需要高于Vdd-0.1,和I2C协议符合。而低电平最大只能0.6V,这里就只能希望Hi3861的I2C能将低电平拉得到0.6V以下了。但巧合了,经过验证Hi3861可以使用!

image.png

准备

本次使用到的是MLX90614BCC版本,该型号的供电是3V,注意不要不要插到5V的供电。! image.png

接线:

VIN->3V3,GND->GND,SLK->SLK,SDA->SDA

image.png

既然已经使用到了I2C,那么便需要知道该设备的地址,查阅了挺久的,发现了该设置的默认地址为0X00或者是0XB4,其中0x00是单个I2C设备连接时默认都能访问到。并且可以修改EEPROM,对其进行修改I2C地址。如果不小心修改了地址,又忘记了地址,便可以把传感器单独插上去,读0X0E的数值便可以得到设备的地址。

image.png

传感器将温度数据存在RAM里面的Tojb1,而ram里面Tobj1的地址为0x07,则得知读取温度的指令则为0x07,向该设备发送0x07,便可读取到温度数据

image.png

image.png

代码编写

IO口初始化

老步骤,第一步先IO口初始化

流程:

GPIO口初始化(开发板背后有标注GPIO口:13,14)

IO口复用成I2C

I2C口初始化(从hi_io.h里面的GPIO口管脚功能列举可得知I2C口)

#define GPIO_SDA 13
#define GPIO_SCL 14
#define GY906_I2C 0

void gy906_init(void)
{
    IoTGpioInit(GPIO_SDA);
    IoTGpioInit(GPIO_SCL);
    hi_io_set_func(GPIO_SDA, HI_IO_FUNC_GPIO_13_I2C0_SDA);
    hi_io_set_func(GPIO_SCL, HI_IO_FUNC_GPIO_14_I2C0_SCL);
    hi_i2c_init(GY906_I2C, 400000);
}

主函数及线程

查询相关文档,gy906反馈的信息有三个,第一个是低位数据,第二个是高位数据,第三个是校验位.将高位数据和低位数据拼接,再通过公式计算即可得出温度数据.

image.png

流程:

  1. 初始化I2c传输数据
  2. 接收传感器反馈回来的数据
  3. 判断数据的正确性
  4. 对数据做拼接计算,即可得出温度数据
#define GY906_I2C 0
#define GY906_addr 0x00 // 0x00 or 0xB4
//获取温度数值
void gy906_get(void)
{
    hi_i2c_data gy_data = {0};	//I2C数据结构
    uint8_t recv_data[3] = {0};	//接收数据缓存
    uint8_t send_data[1] = {0x07};	//读取温度的指令
	//初始化gy_data
    gy_data.send_buf = send_data;
    gy_data.send_len = 1;
    gy_data.receive_buf = recv_data;
    gy_data.receive_len = 3;
	//I2C读写操作
    hi_i2c_writeread(GY906_I2C, (GY906_addr << 1) | 0x01, &gy_data);
    //进行校验位判断
    uint8_t addr[6] = {0, 0, 0, 0x01, 0x07, 0x00};
    addr[1] = recv_data[1];	//高位
    addr[2] = recv_data[0];	//低位
    uint8_t PY_CRC1 = PEC_Calculation(addr);
    //如果校验位正确
    if (PY_CRC1 == recv_data[2])
    {
        printf("temperture correct!\n");
    }
    //如果校验位错误,返回全部数值
    else
    {	
        printf("temperature false!\n");
        printf("recv_data:low:%x high:%x CRC:%x\n", recv_data[0], recv_data[1], recv_data[2]);
        printf("CRC1:%x\n", PY_CRC1);
    }
    //打印温度  T= (DataH:DataL)*0.02-273.15
    float temperature_f = (((float)((recv_data[1] << 8) | recv_data[0])) * 2 - 27315) / 100;
    printf("temperature:%.2f\n", temperature_f);
}
//主函数
void gy906_demo(void)
{
    //IO口初始化
    gy906_init();
    while (1)
    {
        gy906_get();
        sleep(1);
    }
}
//线程创建
void gy_demo(void)
{
    osThreadAttr_t attr;

    attr.name = "gy_demo";
    attr.attr_bits = 0U;
    attr.cb_mem = NULL;
    attr.cb_size = 0U;
    attr.stack_mem = NULL;
    attr.stack_size = 10240;
    attr.priority = 25;

    if (osThreadNew((osThreadFunc_t)gy906_demo, NULL, &attr) == NULL)
    {
        printf("[gy_demo] Falied to create gy_demo!\n");
    }
}

SYS_RUN(gy_demo);

校验算法

image.pngimage-20220928130415936 算法的代码如下(部分介绍打在注释上):

uint8_t PEC_Calculation(uint8_t pec[])
{
    uint8_t crc[6];           //存放多项式
    uint8_t BitPosition = 47; //存放所有数据最高位,6*8=48 最高位就是47位
    uint8_t shift;
    uint8_t i;
    uint8_t j;
    uint8_t temp;

    do
    {
        /*初始化 0x00 00 00 00 01 07*/
        crc[5] = 0;
        crc[4] = 0;
        crc[3] = 0;
        crc[2] = 0;
        crc[1] = 0x01;
        crc[0] = 0x07;

        //设置最大位位位置为47,记录位位置
        BitPosition = 47;

        /*Set shift position at 0*/
        shift = 0;

        /*查找pec[5]开始的传输消息中的第一个“1”*/
        i = 5;
        j = 0;
        //0x80 -> 1000 0000,一位一位地找第一个"1"
        while ((pec[i] & (0x80 >> j)) == 0 && i > 0)
        {
            //位位置-1
            BitPosition--;
            if (j < 7)
            {
                j++;
            }
            else
            {
                j = 0x00;
                i--;
            }
        } /*End of while*/

        /*记录位位置*/
        shift = BitPosition - 8;

        /*校验操作 */
	//循环次数为:shift
        while (shift)
        {
            for (i = 5; i < 0xFF; i--)	//i<0xff即是i>0,遍历crc数组
            {
		//以下操作即是把一个八位的数据整体向左移一位,最高位移到最低位,例:1001 1000 ->0011 0001	
                if ((crc[i - 1] & 0x80) && (i > 0))
                {
                    temp = 1;
                }
                else
                {
                    temp = 0;
                }
                crc[i] <<= 1;	//左移一位
                crc[i] += temp;
            } /*End of for*/
            shift--;
        } /*End of while*/

        //将已经操作过的位 置0
        for (i = 0; i <= 5; i++)
        {
            pec[i] ^= crc[i];
        }                      /*End of for*/
    } while (BitPosition > 8); /*循环操作*/

    return pec[0];
}

编译脚本BUILD.gn

static_library("my_gy906_demo") {
    sources = [
        "gy906.c",

    ]

    include_dirs = [
        "//utils/native/lite/include",
        "//kernel/liteos_m/components/cmsis/2.0",
        "//base/iot_hardware/peripheral/interfaces/kits",
        "//device/soc/hisilicon/hi3861v100/sdk_liteos/include",

    ]
}

效果

image.png

image.png

附件链接:https://ost.51cto.com/resource/2302

想了解更多关于开源的内容,请访问:

51CTO 开源基础软件社区

https://ost.51cto.com/#bkwz

标签:OpenHarmony,温度传感器,uint8,crc,GPIO,打卡,I2C,data
From: https://blog.51cto.com/harmonyos/5737152

相关文章

  • OpenHarmony/HarmonyOS的ArkUI的类Web范式开发详解
    一.OpenHarmony/HarmonyOS的ArkUI的类Web范式开发1.1类Web范式~三件套开发基于JS扩展的类****Web开发范****式的方舟开发框架包括应用层(Application)、前端框架层(Framewo......
  • LeetCode打卡
    目录927.三等分927.三等分https://leetcode.cn/problems/three-equal-parts/classSolution{public:vector<int>threeEqualParts(vector<int>&arr){......
  • #打卡不停更#家庭健康管理平台
    0.项目简介身体健康是一切生产生活的硬性基础。健康是福,一切安好,未来才可期。为什么经常跑步体重缺还在往上飘?突发紧急情况怎么处理?在数字时代,如何更好的为人们提供健康福......
  • 刘潇翔:基于OpenHarmony的仿生四足狗开发分享
    刘潇翔:基于OpenHarmony的仿生四足狗开发分享​说起人工智能机器人界的网红,那就不得不提到——“机器狗”。此前,著名机器人公司波士顿动力制造的“Spot”机器狗、国内知名科......
  • 4步成功将三方库——speexdsp移植到OpenHarmony
    4步成功将三方库——speexdsp移植到OpenHarmony​战码先锋,PR征集令(以下简称“战码先锋”)第二期正如火如荼地进行中,涉及OpenAtomOpenHarmony(以下简称“OpenHarmony”)主干仓......
  • #打卡不停更# OpenHarmony-ArkUI(TS)声明式开发之列表拖动排列
    作者:梁青松项目介绍本项目基于OpenHarmony的ArkUI框架:TS扩展的声明式开发范式,关于语法和概念直接看官网官方文档地址:基于TS扩展的声明式开发范式,因为OpenHarmony的API相对......
  • #打卡不停更#编译效率快三倍,使用WSL2编译OpenHarmony嘎嘎得劲!!
    笔者发现使用wsl(WindowsSubsystemforLinux,适用于Linux的Windows子系统)编译openharmony镜像比传统虚拟机快3倍以上。编译环境换成wsl后,编译ohos只需要传统虚拟机上三......
  • 4步成功将三方库——speexdsp移植到OpenHarmony
     战码先锋,PR征集令(以下简称“战码先锋”)第二期正如火如荼地进行中,涉及OpenAtomOpenHarmony(以下简称“OpenHarmony”)主干仓、SIG仓、三方库,共计1000+代码仓任君挑战。......
  • 身边的人脸安全:员工用人脸作弊工具打卡,企业该如何防范?
    为全面分析人脸识别市场现状、面临的风险隐患及有效的安全保障措施,顶象近日发布《人脸识别安全白皮书》。《白皮书》就保险行业人脸安全事件进行了详细分析,并阐述了保险行......
  • 如何贡献OpenHarmony开发样例
    单丝不成线,独木不成林,一个社区想要健康蓬勃发展离不开社区参与者的持续贡献。而社区贡献点有很多种,本文以贡献OpenAtomOpenHarmony(以下简称“OpenHarmony”)开发样例为例,围......