【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]