pomin 发表于 2024-10-31 23:37

【2024 DigiKey 创意大赛】开发板读取D6T传感器值、LVGL显示

为了把 D6T 传感器连接到开发板,先查看原理图,开发板有一些预留的 IO 接口,但是大多数都不能随意使用



然后查看原理图可以知道 IO47 和 IO48 这两个引脚是作为了 IIC 使用,外接的是屏幕板的电容触摸芯片 FT5406,在代码中也可以看到:



然后查了查文档,FT5406 的 IIC 七位地址是 0x38,而 D6T 的 IIC 七位地址是 0x0A,所以可以把这两个器件都接在 IO47、IO48,然后把 D6T 模块接在开发板的 IO47、IO48上面,代码如下

```c
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: CC0-1.0
*/

#include "core/lv_disp.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"
#include "esp_check.h"
#include "nvs_flash.h"
#include "nvs.h"

#include "bsp_board_extra.h"
#include "bsp/esp-bsp.h"
#include <stdio.h>
#include <string.h>

#include "driver/i2c.h"

static char *TAG = "app_main";

#define LOG_MEM_INFO    (0)

/* defines */
#define D6T_ADDR 0x0A// for I2C 7bit address
#define D6T_CMD 0x4C   // for D6T-44L-06/06H, D6T-8L-09/09H, for D6T-1A-01/02

#define N_ROW 1
#define N_PIXEL 1
#define N_READ ((N_PIXEL + 1) * 2 + 1)

uint8_t rbuf;
double ptat;
double pix_data;

uint8_t calc_crc(uint8_t data) {
    int index;
    uint8_t temp;
    for (index = 0; index < 8; index++) {
      temp = data;
      data <<= 1;
      if (temp & 0x80) { data ^= 0x07; }
    }
    return data;
}

/** <!-- D6T_checkPEC {{{ 1--> D6T PEC(Packet Error Check) calculation.
* calculate the data sequence,
* from an I2C Read client address (8bit) to thermal data end.
*/
bool D6T_checkPEC(uint8_t buf[], int n) {
    int i;
    uint8_t crc = calc_crc((D6T_ADDR << 1) | 1);// I2C Read address (8bit)
    for (i = 0; i < n; i++) {
      crc = calc_crc(buf ^ crc);
    }
    bool ret = crc != buf;
    if (ret) {
      printf("PEC check failed:");
    }
    return ret;
}

/** <!-- conv8us_s16_le {{{1 --> convert a 16bit data from the byte stream.
*/
int16_t conv8us_s16_le(uint8_t* buf, int n) {
    uint16_t ret;
    ret = (uint16_t)buf;
    ret += ((uint16_t)buf) << 8;
    return (int16_t)ret;   // and convert negative.
}

void d6t_1a_01_read(void) {
    int i = 0;
    int16_t itemp = 0;
    uint8_t txbuf;

    memset(rbuf, 0, N_READ);
    txbuf = D6T_CMD;

    i2c_master_write_read_device(CONFIG_BSP_I2C_NUM, D6T_ADDR, txbuf, 1, rbuf, N_READ, 100 / portTICK_PERIOD_MS);

    //Convert to temperature data (degC)
    ptat = (double)conv8us_s16_le(rbuf, 0) / 10.0;
    for (i = 0; i < N_PIXEL; i++) {
      itemp = conv8us_s16_le(rbuf, 2 + 2 * i);
      pix_data = (double)itemp / 10.0;
    }

    //Output results
    printf("PTAT: %f", ptat);
    printf(" , Temperature: ");
    for (i = 0; i < N_PIXEL; i++) {
      printf("%f , ", pix_data);
    }
    printf(" \r\n");
}

void app_main(void)
{
    ESP_LOGI(TAG, "Compile time: %s %s", __DATE__, __TIME__);

    bsp_i2c_init();
    while (1) {
      d6t_1a_01_read();
      vTaskDelay(pdMS_TO_TICKS(5000));
    }
}
```

然后使用 idf 烧录到开发板,并打开串口监控

```
idf.py flash -p /dev/ttyUSB0 -b 460800 && idf.py monitor -p /dev/ttyUSB0 -b 115200
```




可以看到已经成功读取到了 D6T 传感器的温度值了,然后把这个数据用 LVGL 来显示,在 idf.py menuconfig 中配置好 LVGL 后编写代码

```c
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: CC0-1.0
*/

#include "core/lv_disp.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"
#include "esp_check.h"
#include "nvs_flash.h"
#include "nvs.h"

#include "bsp_board_extra.h"
#include "bsp/esp-bsp.h"
#include "lv_example_pub.h"
#include "lv_demos.h"
#include <stdio.h>
#include <string.h>

#include "driver/i2c.h"
#include "widgets/lv_label.h"

static char *TAG = "app_main";

#define LOG_MEM_INFO    (0)

/* defines */
#define D6T_ADDR 0x0A// for I2C 7bit address
#define D6T_CMD 0x4C   // for D6T-44L-06/06H, D6T-8L-09/09H, for D6T-1A-01/02

#define N_ROW 1
#define N_PIXEL 1
#define N_READ ((N_PIXEL + 1) * 2 + 1)

uint8_t rbuf;
double ptat;
double pix_data;

uint8_t calc_crc(uint8_t data) {
    int index;
    uint8_t temp;
    for (index = 0; index < 8; index++) {
      temp = data;
      data <<= 1;
      if (temp & 0x80) { data ^= 0x07; }
    }
    return data;
}

/** <!-- D6T_checkPEC {{{ 1--> D6T PEC(Packet Error Check) calculation.
* calculate the data sequence,
* from an I2C Read client address (8bit) to thermal data end.
*/
bool D6T_checkPEC(uint8_t buf[], int n) {
    int i;
    uint8_t crc = calc_crc((D6T_ADDR << 1) | 1);// I2C Read address (8bit)
    for (i = 0; i < n; i++) {
      crc = calc_crc(buf ^ crc);
    }
    bool ret = crc != buf;
    if (ret) {
      printf("PEC check failed:");
    }
    return ret;
}

/** <!-- conv8us_s16_le {{{1 --> convert a 16bit data from the byte stream.
*/
int16_t conv8us_s16_le(uint8_t* buf, int n) {
    uint16_t ret;
    ret = (uint16_t)buf;
    ret += ((uint16_t)buf) << 8;
    return (int16_t)ret;   // and convert negative.
}

void d6t_1a_01_read(void) {
    int i = 0;
    int16_t itemp = 0;
    uint8_t txbuf;

    memset(rbuf, 0, N_READ);
    txbuf = D6T_CMD;

    i2c_master_write_read_device(CONFIG_BSP_I2C_NUM, D6T_ADDR, txbuf, 1, rbuf, N_READ, 100 / portTICK_PERIOD_MS);

    //Convert to temperature data (degC)
    ptat = (double)conv8us_s16_le(rbuf, 0) / 10.0;
    for (i = 0; i < N_PIXEL; i++) {
      itemp = conv8us_s16_le(rbuf, 2 + 2 * i);
      pix_data = (double)itemp / 10.0;
    }

    //Output results
    printf("PTAT: %f", ptat);
    printf(" , Temperature: ");
    for (i = 0; i < N_PIXEL; i++) {
      printf("%f , ", pix_data);
    }
    printf(" \r\n");
}

void app_main(void)
{
    ESP_LOGI(TAG, "Compile time: %s %s", __DATE__, __TIME__);
    /* Initialize NVS. */
    esp_err_t err = nvs_flash_init();
    if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) {
      ESP_ERROR_CHECK(nvs_flash_erase());
      err = nvs_flash_init();
    }
    ESP_ERROR_CHECK(err);

    bsp_spiffs_mount();

    bsp_i2c_init();
    bsp_extra_codec_init();
    bsp_extra_player_init(BSP_SPIFFS_MOUNT_POINT"/mp3");

    bsp_display_start();

    bsp_display_lock(0);
    lv_style_pre_init();
    lv_obj_t *label = lv_label_create(lv_scr_act());
    // lv_create_home(&main_Layer);
    // lv_demo_benchmark();
    // lv_create_clock(&clock_screen_layer, TIME_ENTER_CLOCK_2MIN);
    bsp_display_unlock();


    while (1) {
      lv_label_set_text_fmt(label, "PTAT: %.2f , Temperature: %.2f ,", ptat, pix_data);
          lv_obj_set_style_text_font(label, &lv_font_montserrat_16, LV_PART_MAIN|LV_STATE_DEFAULT);

      d6t_1a_01_read();
      vTaskDelay(pdMS_TO_TICKS(5000));
    }
}

```

然后就可以在屏幕上用 LVGL 显示数据了

页: [1]
查看完整版本: 【2024 DigiKey 创意大赛】开发板读取D6T传感器值、LVGL显示