227|2

280

帖子

7

TA的资源

一粒金砂(高级)

楼主
 

【DigiKey创意大赛】便携生命探测仪04+驱动BME680并设计UI [复制链接]

 
000

 
上一帖介绍了如何使用DMA提高热成像显示帧率,本帖先介绍驱动BME680并将检测结果显示在屏幕上,然后设计一个操作交互界面,实现用户操作功能。

一、驱动BME680并显示在屏幕上

BME680具有SPI和I2C两种接口,由于我用的这个ESP32-S3开发板引出的SPI口接屏了并且SPI占IO口比较多,我优先选择使用I2C接口连接BME680小板,为了省事我把它和MLX90640挂在同一个I2C总线上了。如下图。
然后在PlatformIO中安装Adafruit BME680 Library,如下图。
直接使用默认例程测试,Adafruit造好的轮子基本不用费心,刷进板子就OK。测试代码如下。
代码1:
/***************************************************************************
  This is a library for the BME680 gas, humidity, temperature & pressure sensor

  Designed specifically to work with the Adafruit BME680 Breakout
  ----> http://www.adafruit.com/products/3660

  These sensors use I2C or SPI to communicate, 2 or 4 pins are required
  to interface.

  Adafruit invests time and resources providing this open source code,
  please support Adafruit and open-source hardware by purchasing products
  from Adafruit!

  Written by Limor Fried & Kevin Townsend for Adafruit Industries.
  BSD license, all text above must be included in any redistribution
 ***************************************************************************/

#include <Wire.h>
#include <SPI.h>
#include <Adafruit_Sensor.h>
#include "Adafruit_BME680.h"

#define BME_SCK 13
#define BME_MISO 12
#define BME_MOSI 11
#define BME_CS 10

#define SEALEVELPRESSURE_HPA (1013.25)

Adafruit_BME680 bme; // I2C
//Adafruit_BME680 bme(BME_CS); // hardware SPI
//Adafruit_BME680 bme(BME_CS, BME_MOSI, BME_MISO,  BME_SCK);

void setup() {
  Serial.begin(9600);
  while (!Serial);
  Serial.println(F("BME680 test"));

  if (!bme.begin()) {
    Serial.println("Could not find a valid BME680 sensor, check wiring!");
    while (1);
  }

  // Set up oversampling and filter initialization
  bme.setTemperatureOversampling(BME680_OS_8X);
  bme.setHumidityOversampling(BME680_OS_2X);
  bme.setPressureOversampling(BME680_OS_4X);
  bme.setIIRFilterSize(BME680_FILTER_SIZE_3);
  bme.setGasHeater(320, 150); // 320*C for 150 ms
}

void loop() {
  if (! bme.performReading()) {
    Serial.println("Failed to perform reading :(");
    return;
  }
  Serial.print("Temperature = ");
  Serial.print(bme.temperature);
  Serial.println(" *C");

  Serial.print("Pressure = ");
  Serial.print(bme.pressure / 100.0);
  Serial.println(" hPa");

  Serial.print("Humidity = ");
  Serial.print(bme.humidity);
  Serial.println(" %");

  Serial.print("Gas = ");
  Serial.print(bme.gas_resistance / 1000.0);
  Serial.println(" KOhms");

  Serial.print("Approx. Altitude = ");
  Serial.print(bme.readAltitude(SEALEVELPRESSURE_HPA));
  Serial.println(" m");

  Serial.println();
  delay(2000);
}

 

然后考虑怎么移植到现有的程序中。我在热成像图像右边留白的区域就是为BME680数据准备的。在右下角放置一个按钮用来切换屏幕功能。留白的显示效果如下图。
程序设计上,专门为BME680建立一个独立任务,设置成每2秒读一次数据。显示任务判断数据变化就更新屏幕,实际显示效果如下图。
虽然整个屏幕显示实现了,但是我发现一个问题,就是每次读取BME680时候,热成像刷新都会卡顿一下,体验不好,原因就是共用总线造成的。好在ESP32-S3有多个I2C,并且还有一个巨牛掰的GPIO交换矩阵,可以让外设使用任意IO口。于是我从引脚分配表上找了2个闲置的IO口A4和A5配置成了I2C总线,如下图。
在程序初始化中也适当修改,选择I2C1,直接调用即可,代码如下。
代码2:
#define SEALEVELPRESSURE_HPA (1019.25)
Adafruit_BME680 bme(&Wire1); // I2C

void Bme680Init(void)
{
    Serial.println(F("BME680 async test"));
    // I2C init
    Wire1.begin(BME_SDA, BME_SCL);

    // bme.Adafruit_BME680(Wire1);

    if (!bme.begin())
    {
        Serial.println(F("Could not find a valid BME680 sensor, check wiring!"));
        while (1)
            ;
    }

    // Set up oversampling and filter initialization
    bme.setTemperatureOversampling(BME680_OS_8X);
    bme.setHumidityOversampling(BME680_OS_2X);
    bme.setPressureOversampling(BME680_OS_4X);
    bme.setIIRFilterSize(BME680_FILTER_SIZE_3);
    bme.setGasHeater(320, 150); // 320*C for 150 ms
}

 

以上都弄好后,屏幕显示就流畅起来了,看着虽然简陋些,但是没啥问题。下一步就是设计人机交互。

二、设计操作交互界面

我的预期功能是这样的,本作品具备两个屏幕界面,第一屏界面显示热成像图像和环境信息,用于寻找体温高于环境温度的被施救人员,上面已经做完了。第二屏界面显示心电图,目的是在发现生命体后可以立即给被发现者做一个快速心电检测,帮助救援人员根据心电数据制定下一步的施救方案。
设计的心电图采集界面如下图所示。
整个屏幕上部分分配480x240点阵的区域用于显示心电波形,左下分两行文字,一行显示导联脱落信息,一行显示心率。右下角按钮用来切换两个界面。
心电数据预计从串口接收,这里我新建了一个单独的任务,暂时用于产生随机数模拟心电波形、心率、导联脱落信息。通过模拟数据与显示任务对接,可以仿真心电采集界面的各个功能。仿真数据产生代码如下。
代码3:
#include <Arduino.h>
#include <ecg.h>
#include <lcd.h>

uint8_t ECG_data = 0;
uint16_t ECG_hr = 0;
bool ECG_lead = true;
bool ECG_flag = true;

float ecg_data = 0;
float ecg_hr = 0;
float ecg_lead = 0;

void task_ecg(void *ptr)
{
    int i = 0;

    while (true)
    {
        vTaskDelay(4);
        ECG_flag = true;
        ECG_data = random(0, 239);
        ECG_hr = random(60, 120);
        if (ECG_hr > 110)
            ECG_lead = true;
        else
            ECG_lead = false;
    }
    vTaskDelete(NULL);
}

 

TFT_eSPI库本身支持触摸功能,可以直接调用API接口函数实现触摸输入事件解析,通过按钮锁定逻辑,每点击一次右下角按钮,切换一次界面,按钮文字也随之更改,具体代码如下。
代码4:

void LcdScreenSwitch(void)
{
    if (screen_lock == SCREEN_CAM)
    {
        lock_mxl = true;//禁能热成像采集
        screen_lock = SCREEN_ECG;
        tft.fillScreen(TFT_BLACK);
        LcdEcgBar();
        // Serial.println("ECG");
    }
    else
    {
        screen_lock = SCREEN_CAM;
        tft.fillScreen(TFT_BLACK);
        LcdColorBar();
        Bme680Display();
        lock_mxl = false;//使能热成像采集
        // Serial.println("CAM");
    }
}

bool Key_Short = false;
void LcdGetTouch(void)
{
    uint16_t x = 0, y = 0; // To store the touch coordinates

    // Pressed will be set true is there is a valid touch on the screen
    bool pressed = tft.getTouch(&x, &y);
    // Serial.println(pressed);
    // Draw a white spot at the detected coordinates
    if (pressed)
    {
        if ((x > 350) && (y > 260))
        {
            if (Key_Short == false)
            {
                Key_Short = true;
                LcdScreenSwitch(); // 切换屏幕
            }
        }
        else
        {
            Key_Short = false;
        }
    }
    else
    {
        Key_Short = false;
    }
}

 

至此用户交互界面基本设计完成,具体演示效果见开头视频。接下来要搞定心电数据的采集和处理。

 

最新回复

就是每次读取BME680时候,热成像刷新都会卡顿一下,这个看来是确实总线的问题   详情 回复 发表于 2024-9-23 07:29
点赞 关注
 
 

回复
举报

6555

帖子

0

TA的资源

五彩晶圆(高级)

沙发
 

就是每次读取BME680时候,热成像刷新都会卡顿一下,这个看来是确实总线的问题

点评

是滴,换个I2C口就好了,还好ESP32-S3的I2C口多  详情 回复 发表于 2024-9-26 12:19
 
 
 

回复

280

帖子

7

TA的资源

一粒金砂(高级)

板凳
 
Jacktang 发表于 2024-9-23 07:29 就是每次读取BME680时候,热成像刷新都会卡顿一下,这个看来是确实总线的问题

是滴,换个I2C口就好了,还好ESP32-S3的I2C口多

 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表