我上个贴子发布了如何利用USB进行串口通信,

【树莓派Pico测评】- USB CDC串口通信(BSP编译,非MicroPython)

这次发布一个I2C的例子,刚好我手头上有MLX90614,市场上的手持红外测温的清一色的都是用的它

这个芯片我买了大概5-6年了,一直吃灰,刚好最近玩PICO时又从宝箱里翻出了它,刚好在这个疫情后时代用得上

程序基于我上次的程序进行修改,这里我只发出主程序

#include <stdio.h>
#include "pico/stdlib.h"
#include "pico/stdio_usb.h"
#include "hardware/i2c.h"

// I2C 声明
#define I2C_PORT i2c0
#define I2C_SDA 0
#define I2C_SCL 1
//MLX90614 声明
#define MLX90614_ADDR 0x5a        //地址

#define CMD_RAM(n)  (0|n)
#define CMD_EEPROM(n) (32|n)                 //001x xxxx* EEPROM Access
#define CMD_FLAG(n) (0xf0)            //1111_0000** Read Flags
#define CMD_SLEEP(n) (0xff)                      //1111_1111 Enter SLEEP mode


//led 声明
#define LED 25
//usb 声明

//函数申明
int ReadData(uint8_t reg_addr);       //
//变量申明
uint16_t MLX90614_value;            //读取的16位原始结果

int main()
{
    //USB初始化
    stdio_usb_init();
    //LED初始化
    gpio_init(LED);
    gpio_set_dir(LED,GPIO_OUT);
    gpio_put(LED,1);
    //LED闪烁提示
    sleep_ms(5000);
    for(int i=0;i<10;i++){
        sleep_ms(100);
        gpio_put(LED,0);
        sleep_ms(100);
        gpio_put(LED,1);
    }

    //MLX90614切换到I2C模式,SCL至少低电平 1.44ms
    gpio_set_function(I2C_SCL, GPIO_FUNC_SIO);
    gpio_set_dir(I2C_SCL, GPIO_OUT);
    gpio_put(I2C_SCL, 0);
    sleep_ms(5);
    gpio_put(I2C_SCL, 1);
    sleep_ms(30);

    // I2C 50Khz.
    i2c_init(I2C_PORT, 50*1000);
    
    gpio_set_function(I2C_SDA, GPIO_FUNC_I2C);
    gpio_set_function(I2C_SCL, GPIO_FUNC_I2C);
    gpio_pull_up(I2C_SDA);
    gpio_pull_up(I2C_SCL);

    /*  MLX90614 RAM地址
ta本体温度,      6
温度1              7
温度2              8
    */

    /*  MLX90614 EEPROM地址
Tomax           0x00 Yes
Tomin           0x01 Yes
PWMCTRL     0x02 Yes
Ta range        0x03 Yes
Emissivity      0x04 Yes
Config Register1 0x05 Yes
SMBus address (LSByte only) 0x0E Yes
    */
    //读取EEPROM配置数据
    float max, min;

    int r= ReadData(CMD_EEPROM(0));
    if (r < 3) {
        printf("读取配置失败\n");
        while (1);
    }
    printf("dat:%d\n", MLX90614_value);
    max = MLX90614_value / 100.0f - 273.15f;
    printf("Tomax:%f\n", max);
    r = ReadData(CMD_EEPROM(1));
    if (r < 3) {
        printf("读取RAM失败\n");
        while (1);
    }
    printf("dat:%d\n", MLX90614_value);
    min = MLX90614_value / 100.0f - 273.15f;
    printf("Tomax:%f\n", min);

    while(1){
        //本体温度
        float temp1,temp2;
        int r;

        r = ReadData(CMD_RAM(6));
        if (r < 3) {
            printf("读取温度6失败\n");
            while (1);
        } 
        temp1 = MLX90614_value * 0.02f-273.15;

        r = ReadData(CMD_RAM(7));
        if (r < 3) {
            printf("读取温度7失败\n");
            while (1);
        }
        temp2 = MLX90614_value * 0.02f - 273.15;
        printf("temp:%3.2f,%3.2f  \t@eeworld.fxyc87\n", temp1,temp2);

       //打印出读的数据
        
        gpio_put(LED, 1);
        sleep_ms(500);
        gpio_put(LED, 0);
        sleep_ms(500);
    }

    return 0;
}
/*
读取MLX90614寄存器数据   
reg_addr 地址有 CMD_RAM(a),CMD_EEPROM(a),CMD_FLAG(a),CMD_SLEEP(a)
读取成功,返回数据长度
失败:-1
*/
int ReadData(uint8_t reg_addr) {       //
    uint8_t bf[3];
    int r = 0;
        //先写站号及命令码 nostop=false 写入后不发送i2c停止指令
        //PICO_ERROR_TIMEOUT
    r = i2c_write_timeout_us(I2C_PORT, MLX90614_ADDR, ®_addr, 1, true, 2000);    //超时2ms
    if (r < 1) {
        return -1;
    }
    //再读数据      lsb,msb,pec
    r = i2c_read_timeout_us(I2C_PORT, MLX90614_ADDR, &bf[0], 3, false, 2000);
    if (r < 1) {
        return -1;
    }
    MLX90614_value = bf[0] + (bf[1] << 8);
    return r;
}

以主是主程序,程序比较简单,输出当前温度及芯片本体温度,参数及地址参照MLX90614手册进行就好了

python体温判断 python体温检测_数据

编译主程序,并且复制程序

python体温判断 python体温检测_数据_02

硬件链接图:

python体温判断 python体温检测_python体温判断_03

运行效果展示

python体温判断 python体温检测_#include_04

从上图中可以看出,室温/芯片温度约16度左右,基本正常,手摸一下温度会慢慢升高

目标物体温度,无物体时约15.61度,差不多室温,手腕放主去,2秒后升到33度左右,

和公司的每天早上量体温的机器基本一致,至于为什么不是36,37度我也不知道,应该是出厂就校准过的啊,不应该差这么多吧?可能是一些参数还需要配置,比如测量温度上下限等,有空了再试试。

等节后了加工一个PCB,再找个漂亮的盒子,再搞个小屏,这样就是一个成品模块了。

这芯片买的时候180,现在估计卖300也能卖出去,哈,增值啊。

不该2019年底的时候把 MLX90640,如果这个没卖玩起来更爽。32*24像素的红外相机啊!

再列个网址 https://raspberrypi.github.io/pico-sdk-doxygen/group__hardware__i2c.html

这个网址是关于I2C的SDK API说明,当然其它API这里也有看到介绍

https://raspberrypi.github.io/pico-sdk-doxygen/group__hardware.html