FastBond阶段2 办公室小精灵(靠近自动开启、唤醒电脑)
使用24G毫米波人体检测雷达探测是否有人在工位上,并由ESP32 S3将检测到的人体状态通过BLE发送到电脑。并且通过检测BLE的连通性来判断电脑的状态,进而实现人体靠近自动唤醒电脑的功能。
标签
FastBond第二季
Kadam
更新2023-11-30
830

第二阶段项目文档

项目介绍

我的参赛作品名称是办公室小精灵。我将使用24G毫米波人体检测雷达探测是否有人在工位上,并由ESP32 S3将检测到的人体状态通过BLE发送到电脑。并且通过检测BLE的连通性来判断电脑的状态,进而实现人体靠近自动唤醒电脑的功能。

基于此,本作品实现了两个功能

  1. 持续通过BLE发送雷达检测状态

  2. 当有人靠近时,而电脑处于不活跃状态(关机、睡眠),主控板通过继电器唤醒电脑。

  • 当ESP32S3主控板能够通过BLE将人体检测状态发送给PC时,可以用来干很多事情,如久坐提醒等。后续如果时间充足,将持续开发相关功能。

市场应用介绍

目前市场上常用的人体检测传感器为红外热释电,体积大不方便开发,使用新兴的毫米波雷达传感器可以检测到更加微小的人体动作,并且在检测的时候均为无感,具有良好的使用前景。

项目设计思路

核心器件为ESP32 - S3与毫米波雷达传感器。基于检测人是否在检测区域、在检测区域的时间等数据,可以做久坐提醒、久坐时间统计等,可用于健康领域。

方案框图

FkPKLlJzNHPHByE-pX3lhzCXtmJF

系统逻辑框图

Fu3QrUQ3Gir2CZVr5kxWMZVeRTX-

  • 目前功能比较基础,主要通过定时器的配合实现

    1. ESP32 S3周期性发送信息给PC

    2. ESP32 S3周期性检查蓝牙连接情况与周围的人体情况,来决定是否驱动继电器

    3. 考虑到传感器存在误判的情况,需要对重启次数进行一定的限制

    4. 两次重启时间需要留有充足的时间,让电脑能够正常启动,并且连接到ESP32S3上

主要元器件介绍

ESP32-S3-WROOM-1

ESP32-S3-WROOM-1 是一款通用型 Wi-Fi + 低功耗蓝牙 MCU 模组,搭载 ESP32-S3系列芯片。

ESP32-S3 是一款集成 2.4 GHz Wi-Fi 和 Bluetooth 5 (LE) 的 MCU 芯片,支持远距离模式 (Long Range)。ESP32-S3 搭载 Xtensa® 32 位 LX7 双核处理器,主频高达 240 MHz,内置 512 KB SRAM (TCM),具有 45 个可编程 GPIO 管脚和丰富的通信接口。ESP32-S3 支持更大容量的高速 Octal SPI flash 和片外 RAM,支持用户配置数据缓存与指令缓存。

ESP32-S3芯片具有行业领先的低功耗性能和射频性能,支持 WiFi IEEE802.11b/g/n 协 议和 Bluetooth 5。该芯片搭载 Xtensa-R32 位 LX7 双核处 理器,工作频率高达 240 MHz。支持二次开发,无需使用其它微控制器或处理器。芯片内置 512 KB SRAM,384 KB ROM, 16KB RTC SRAM。芯片支持多种 低功耗工作状态,能够满足各种应用场景的功耗需求。芯片所特有的精细时钟门控功能、动态电压时钟频率调节功能、射频输出功率可调节功能等特性,可以实现通信距离、通信速率和功耗之间的最佳平衡。

模组提供丰富的外设接口,包括 UART,PWM,SPI,I2S,I2C,ADC,LCD, DVP,RMT(TX/RX),脉冲计数器,USB OTG,USB Serial/JTAG,SDIO,DMA 控制器, TWAI 控制器,温度传感器,电容式传感器和多个IO 口。

使用ESP32-S3模组相比于ESP32-S3芯片更有利于降低PCB布线难度,加快开发进度。

安信可24G人体雷达传感器模块 Rd-03

FkRSsZ250Tv7eXWYaFTo_IC0Kx3-

Rd-03是由深圳市安信可科技有限公司开发的雷达模组,搭载砂典微的S3KM1110芯片。S3KM1110芯片是一种基于FMCW雷达收发器技术的集成单片机毫米波传感SoC。它工作在24GHz的K波段,每个单频扫描的调制带宽高达1GHz.利用FMCW调频连续波,对设定空间内的目标进行探测。结合雷达信号处理实现高灵敏度的运动检测和微动检测。

Rd-03模组可感知区域内是否有运动或微动的人体,实现实时检测结果,提供可视化的配置工具,可轻松配置感应距离范围、不同区间的感应灵敏度和无人延时时间等。

PCB绘制打板介绍及遇到的问题和解决方法

绘制打板没有遇到太大的问题,但也存在一些困难。首先是此前没有使用过KiCad,所以需要花时间看视频、查询网络资源进行入门。再然后是KiCad的默认元器件库没有我想要的元器件,导入引脚图与封装花费了一点功夫。

因为我的画板、打板与焊接经验不足,为了能够在有限的时间内完成整个项目,所以我选择只对ESP32S3核心板进行画板和打板,继电器与毫米波雷达通过杜邦线与ESP32S3进行连接,从而降低项目是实施难度。在后续积累了足够的经验与对此项目进行充分的开发后,会将多个模块通过画板、打板的方式集成在一起。

除此之外,没有遇到其他什么困难。

关键代码及说明

本项目目前实现的功能十分简单,所以没有太多的关键代码。

  1. 依据乐鑫提供的BLE的Demo,在此基础上进行小修小改,实现了BLE连接后的逻辑控制与信息发送。

    ESP32 S3使用定时器周期检查相关参数,看看是否需要进行逻辑控制

    1. 周期性扫描全局参数,进行重启次数清空或者启动重启计数

      // 定时扫描参数,决定是否重启PC
      static void ble_timer2_task(void *arg)
      {
          if (enable_reset_pc == 1) //授权可以控制PC
          {
              // 有人靠近 且 BLE长时间未连接 且 重启次数小于最大重启次数
              if(is_human_nearby == 1 && connect_state == 2 && current_reset_time <= reset_max_time){
                  if(!timer3_active) // 计算机启动最长时间定时器计时未开始
                  {
                      if(current_reset_time == 0) //当前重启次数为第一次
                      {
                          turn_on_pc(); //驱动继电器打开电脑
                      }
                      xTimerStart(timer3, 0); //开启计时器,倒计时结束驱动继电器打开电脑
                      current_reset_time++;   //重启次数加一
                      printf("start timer3\r\n");
                      timer3_active = 1;      //计时器开启标志
                  }
              // 无人靠近 且 连续四次未检测到人体 或 BLE已连接 或 BLE短时间未连接,则清空重启次数
              }else if((is_human_nearby == 0 && no_human_time >5)  || connect_state == 0 || connect_state == 1) 
              {   
                  current_reset_time = 0; // 重置重启次数
                  xTimerStop(timer3, 0);  // 关闭计时器3
                  timer3_active = 0;      // 关闭计时器3开启标志
                  printf("reset reset time\r\n");
              }
          }
      }
    1. 串口接受与发送信息任务

      //串口任务
      static void uart_task(void *arg)
      {
          // Configure a temporary buffer for the incoming data
          char *data = (char *) malloc(BUF_SIZE);
      
          while (1) {
              // 从与雷达连接的UART读取数据 
              int len = uart_read_bytes(LIDAR_UART_PORT_NUM, data, (BUF_SIZE - 1), 20 / portTICK_PERIOD_MS);
              // 如果接受到的字符串里有"ON",则说明有人靠近
              if(strncmp(data, "ON", 2) == 0){
                  printf("Human is nearby\n");
                  is_human_nearby = 1; //有人在附近变量置1
                  no_human_time = 0;   //无人靠近次数置0
              }
              // 否则无人靠近
              else
              {
                  printf("Human is not nearby\n");
                  is_human_nearby = 0; //有人在附近变量置0
                  no_human_time++;     //无人靠近次数置0
              }
              data[0] = '\0'; //清空data
              vTaskDelay(1000 / portTICK_PERIOD_MS); //延时,方便FreeRTOS调度
          }
      }
    1. BLE通信的回调函数

      // GAP回调函数
      static int blehr_gap_event(struct ble_gap_event *event, void *arg)
      {
          switch (event->type) {
          case BLE_GAP_EVENT_CONNECT: // 连接事件
              /* A new connection was established or a connection attempt failed */
              MODLOG_DFLT(INFO, "connection %s; status=%d\n",
                          event->connect.status == 0 ? "established" : "failed",
                          event->connect.status);
      
              if (event->connect.status != 0) {
                  //连接到一半失败了,重新广播
                  ble_advertise();
              }
              conn_handle = event->connect.conn_handle;
              // 1. 修改连接状态
              connect_state = 0;
              // 2. 停止短断开到长断开的定时器
              xTimerStop(ble_long_dcnn_timer, 0);
              break;
      
          case BLE_GAP_EVENT_DISCONNECT: // 断开连接事件
              MODLOG_DFLT(INFO, "disconnect; reason=%d\n", event->disconnect.reason);
              // 1.修改连接状态
              connect_state = 1;
              // 2.关闭发送信息计时器
              ble_lidar_timer_stop();
              // 3.开启短断开到长断开的定时器
              ble_long_dcnn_timer_start();
              // 4.恢复广播
              ble_advertise();
              break;
      
          case BLE_GAP_EVENT_ADV_COMPLETE:
              MODLOG_DFLT(INFO, "adv complete\n");
              ble_advertise();
              break;
      
          //订阅信息
          case BLE_GAP_EVENT_SUBSCRIBE:
              MODLOG_DFLT(INFO, "subscribe event; cur_notify=%d\n value handle; "
                          "val_handle=%d\n",
                          event->subscribe.cur_notify, event->subscribe.attr_handle);
              if (event->subscribe.attr_handle == esp_send_info_handle) {
                  if(event->subscribe.cur_notify == 1){
                      printf("PC订阅ESP信息\r\n");
                      // 开启发送信息
                      ble_lidar_timer_start();
                      }
                  else{
                      printf("PC取消订阅ESP信息\r\n");
                      ble_lidar_timer_stop();
                      }
              }
              ESP_LOGI("BLE_GAP_SUBSCRIBE_EVENT", "conn_handle from subscribe=%d", conn_handle);
              break;
      
          case BLE_GAP_EVENT_MTU:
              MODLOG_DFLT(INFO, "mtu update event; conn_handle=%d mtu=%d\n",
                          event->mtu.conn_handle,
                          event->mtu.value);
              break;
          }
          return 0;
      }
     
  2. 依据Qt6 BLE的Demo,在此基础上进行小修改,实现了定时扫描蓝牙,自动连接设备等功能。

    1. 通过BLE 服务UUID判断BLE设备是否为我们的ESP32S3 LIDAR设备

      void MainWindow::addLowEnergyService(const QBluetoothUuid &serviceUuid)
      {
          qDebug()<<"addLowEnergyService";
          // 通过UUID创建服务
          QLowEnergyService *service = controller->createServiceObject(serviceUuid);
      
          if (!service) {
              qWarning() << "Cannot create service for uuid";
              return;
          }
      
          qDebug()<<service->serviceUuid().toString();
          qDebug()<<"this service has "<< service->characteristics().length()<<"characteristics ";
          // 对比当前扫描到的服务UUID与目标UUID来判断是否为Lidar设备
          if (getUUID(service->serviceUuid()) == targetUUID){
              qDebug()<<"this device have lidar service";
              hasLidarService = true; //如果是,则标志位置1
              lidarService = service; //将该服务保存下来
              qDebug()<<"lidarService->serviceUuid()"<<lidarService->serviceUuid();
          }
      
      }
    2. 扫描BLE服务的特性并保存,用于后续的双方通讯句柄

      // 扫描特性
      void MainWindow::serviceDetailsDiscovered(QLowEnergyService::ServiceState newState)
      {
          qDebug()<<"serviceDetailsDiscovered 356";
          if (newState != QLowEnergyService::RemoteServiceDiscovered) {
              if (newState != QLowEnergyService::RemoteServiceDiscovering) {
                  QMetaObject::invokeMethod(this, "characteristicsUpdated",
                                            Qt::QueuedConnection);
              }
              return;
          }
      
          auto service = qobject_cast<QLowEnergyService *>(sender());
          if (!service)
              return;
      
          // 遍历特性
          const QList<QLowEnergyCharacteristic> chars = service->characteristics();
          for (const QLowEnergyCharacteristic &ch : chars) {
              for (QLowEnergyDescriptor &desc : ch.descriptors() ){
                  qDebug() << desc.uuid();
                  service->writeDescriptor(desc,QByteArray::fromHex("0100")); // 订阅notify
              }
      		// 如果是ESP32s3 的notify特性则保存
              if (getUUID(ch.uuid()) == chr_esp_notify_pc_UUID){
                  qDebug()<<"chr_esp_notify_pc get";
                  chr_esp_notify_pc =  ch;
              }else if (getUUID(ch.uuid()) == chr_pc_write_esp_UUID){ //PC 向 esp32 写信息的句柄
                  chr_pc_write_esp =  ch;
      		//  service->writeCharacteristic(chr_pc_write_esp,QByteArray::fromHex("0100"));
                  sendData("0100");
                  qDebug()<<"chr_pc_write_esp_UUID";
              }else if (getUUID(ch.uuid()) == chr_pc_wr_esp_UUID){  //PC 与 esp32 确认信息同步的句柄
                  chr_pc_wr_esp = ch;
                  qDebug()<<"chr_pc_wr_esp_UUID";
                  service->readCharacteristic(chr_pc_wr_esp);
              }
          }
      //    emit PCStateChanged(true);
      }
  3. 实现windows11 开机自启动QT6编译的应用,主动连接ESP32S3。该操作可通过可视化的方式完成,具体步骤可查询网络资源。

     

功能展示及说明

  • 本项目实现的功能较为简单,概括的说就是人体靠近,实现电脑唤醒,辅以其他小设计,实现一个简单好用的功能。均为动态场景,通过文字不太好充分展示,大家可以观看相关视频(但不要保有太大期望,就是一个小功能)

  1. 通过毫米波雷达的调试工具,将毫米波雷达的感受范围、阈值设定到合理的范围内,此处我选择的是70cm的最大触发距离。

    Fmu89C5eTD-ZK1xFWr9ME0uW1o_r

  2. 将毫米波雷达、ESP32S3开发板、继电器通过杜邦线连接,并在毫米波雷达安装在合适的位置上。

    Fje8Yre9eucZhUPErNJ_k_rZgEyy

  3. 然后连接继电器与电脑主板的开机线

  4. 上电即开启功能。

  5. PC成功连接上ESP32S3后显示该页面

FsjvbfBZwGZS0PxwUYjMFXGoNDKe

 

 

对本大赛的心得体会

很高兴能够参与到硬禾学堂的FastBond第2季 - How2Make设计大赛阶段二的活动中。在参加完阶段一之后,我也开始抓紧时间投入到了阶段二的过程中,但因为种种原因,实现项目的时间还是比较紧张的,但最终也还是完成了基本的功能。在该活动中,我学习到如何使用KiCad,积累到了一定的打板、画板的经验,有助于我以后的电子创作。再次感谢硬禾学堂,举办了这次活动,让我把心中所想做了出来,后续我将继续完善该项目,也会积极参与到硬禾学堂的其他相关活动。

 

 

软硬件
电路图
附件下载
pcb_esp_lidar.zip
PCB板资料
qt_lidar.7z
QT程序
ble_lidar.zip
esp32 S3 程序
团队介绍
评论
0 / 100
查看更多
目录
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2024 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号