bigbat

  • 2024-11-04
  • 回复了主题帖: 【NUCLEO-WB09KE】开箱及开发环境测试

    lijinlei 发表于 2024-11-3 15:28 我的怎么都识别不到设备,连接开发板之后端口根本没变化 板子上有个跳线,设置到boot loader状态,我上面有图

  • 2024-10-29
  • 发表了主题帖: 【NUCLEO-WB09KE】BLE应用架构与分析

    1、测试介绍 (1)测试前说明 为了了解ST BLE设备的编程架构,开始对ST提供的应用进行测试。最开始时使用“BLE_Peripheral_Lite”应用进行研究,结果该应用出现了配对失败的问题,随即放弃了该应用转而使用BLE_p2pServer应用进行测试。所以下面的测试为该应用的分析和测试。   (2)测试需要的硬件 PC主机:系统为windows 10版本 USB蓝牙适配器:版本为5.4,建议使用勉驱的产品,需要驱动的产品又可能出现兼容问题。 NUCLEO-WB09KE开发板:主要芯片为STM32WB09KE芯片,为低功耗产品ARM m0+内核 (3)测试需要的软件 Bluetooth LE Eplorer:该软件为微软提供的测试产品,虽然功能一般但是较为实用。可以从微软的应用商店免费获得。 BLE_p2pServer: STM32WB0 的演示程序。使用STM32CubeMX复制 ComAssistant串口助手:可以从EE下载,软件为本人编写 2、测试过程 (1)下载安装Bluetooth LE Eplorer软件   软件比较简洁,只要启动就可以使用了 (2)烧写BLE_p2pServer到开发板 注意:需要将开发板的跳线设置到Boot Loader状态。     打开keil软件编译程序,如果可以连接开发板则进行烧写   烧写到开发板后,重新上电,上电后       打开串口连接测试串口波特率:115200,N,8,1 按压B3停止系统指示灯不停闪烁,按压B1开始系统连接状态   (3)连接配对 将开发板的跳线设置到USER FLASH状态   进行配对,可以发现设备的PIN码一致,如果:多次配对需要在windows设备管理中删除设备。   配对成功后   进行操作,向设备写入0101打开LED1 ,写入0100关闭LED1   写入命令   3、程序结构分析 设备功能参数,设备包含三组“Service”   服务号:UUID SERVICE1   UUID:00001801-0000-1000-8000-00805f9b34fb SERVICE2   UUID:00001800-0000-1000-8000-00805f9b34fb SERVICE3   UUID:0000fe40-cc7a-482a-984a-7f2ed5b3e58f #define P2P_SERVER_UUID 0x8f,0xe5,0xb3,0xd5,0x2e,0x7f,0x4a,0x98,0x2a,0x48,0x7a,0xcc,0x40,0xfe,0x00,0x00 #define LED_C_UUID 0x19,0xed,0x82,0xae,0xed,0x21,0x4c,0x9d,0x41,0x45,0x22,0x8e,0x41,0xfe,0x00,0x00 #define SWITCH_C_UUID 0x19,0xed,0x82,0xae,0xed,0x21,0x4c,0x9d,0x41,0x45,0x22,0x8e,0x42,0xfe,0x00,0x00 这个与程序定义的一致。 /* USER CODE BEGIN Header */ /** ****************************************************************************** * [url=home.php?mod=space&uid=1307177]@File[/url] p2p_server_app.c * [url=home.php?mod=space&uid=1315547]@author[/url] MCD Application Team * [url=home.php?mod=space&uid=159083]@brief[/url] p2p_server_app application definition. ****************************************************************************** * [url=home.php?mod=space&uid=1020061]@attention[/url] * * Copyright (c) 2024 STMicroelectronics. * All rights reserved. * * This software is licensed under terms that can be found in the LICENSE file * in the root directory of this software component. * If no LICENSE file comes with this software, it is provided AS-IS. * ****************************************************************************** */ /* USER CODE END Header */ /* Includes ------------------------------------------------------------------*/ #include "main.h" #include "app_common.h" #include "app_ble.h" #include "ble.h" #include "p2p_server_app.h" #include "p2p_server.h" #include "stm32_seq.h" /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ /* USER CODE BEGIN PTD */ typedef struct{ uint8_t Device_Led_Selection; uint8_t Led1; }P2P_LedCharValue_t; typedef struct{ uint8_t Device_Button_Selection; uint8_t ButtonStatus; }P2P_ButtonCharValue_t; /* USER CODE END PTD */ typedef enum { Switch_c_NOTIFICATION_OFF, Switch_c_NOTIFICATION_ON, /* USER CODE BEGIN Service1_APP_SendInformation_t */ /* USER CODE END Service1_APP_SendInformation_t */ P2P_SERVER_APP_SENDINFORMATION_LAST } P2P_SERVER_APP_SendInformation_t; typedef struct { P2P_SERVER_APP_SendInformation_t Switch_c_Notification_Status; /* USER CODE BEGIN Service1_APP_Context_t */ P2P_LedCharValue_t LedControl; P2P_ButtonCharValue_t ButtonControl; /* USER CODE END Service1_APP_Context_t */ uint16_t ConnectionHandle; } P2P_SERVER_APP_Context_t; /* Private defines -----------------------------------------------------------*/ /* USER CODE BEGIN PD */ /* USER CODE END PD */ /* External variables --------------------------------------------------------*/ /* USER CODE BEGIN EV */ /* USER CODE END EV */ /* Private macros ------------------------------------------------------------*/ /* USER CODE BEGIN PM */ /* USER CODE END PM */ /* Private variables ---------------------------------------------------------*/ static P2P_SERVER_APP_Context_t P2P_SERVER_APP_Context; uint8_t a_P2P_SERVER_UpdateCharData[247]; /* USER CODE BEGIN PV */ /* USER CODE END PV */ /* Private function prototypes -----------------------------------------------*/ static void P2P_SERVER_Switch_c_SendNotification(void); /* USER CODE BEGIN PFP */ static void P2P_SERVER_APP_LED_BUTTON_context_Init(void); /* USER CODE END PFP */ /* Functions Definition ------------------------------------------------------*/ void P2P_SERVER_Notification(P2P_SERVER_NotificationEvt_t *p_Notification) { /* USER CODE BEGIN Service1_Notification_1 */ /* USER CODE END Service1_Notification_1 */ switch(p_Notification->EvtOpcode) { /* USER CODE BEGIN Service1_Notification_Service1_EvtOpcode */ /* USER CODE END Service1_Notification_Service1_EvtOpcode */ case P2P_SERVER_LED_C_READ_EVT: /* USER CODE BEGIN Service1Char1_READ_EVT */ /* USER CODE END Service1Char1_READ_EVT */ break; case P2P_SERVER_LED_C_WRITE_NO_RESP_EVT: /* USER CODE BEGIN Service1Char1_WRITE_NO_RESP_EVT */ if(p_Notification->DataTransfered.p_Payload[1] == 0x01) { BSP_LED_On(LED_BLUE); APP_DBG_MSG("-- P2P APPLICATION SERVER : LED1 ON\n"); P2P_SERVER_APP_Context.LedControl.Led1 = 0x01; /* LED1 ON */ } if(p_Notification->DataTransfered.p_Payload[1] == 0x00) { BSP_LED_Off(LED_BLUE); APP_DBG_MSG("-- P2P APPLICATION SERVER : LED1 OFF\n"); P2P_SERVER_APP_Context.LedControl.Led1 = 0x00; /* LED1 OFF */ } /* USER CODE END Service1Char1_WRITE_NO_RESP_EVT */ break; case P2P_SERVER_SWITCH_C_NOTIFY_ENABLED_EVT: /* USER CODE BEGIN Service1Char2_NOTIFY_ENABLED_EVT */ P2P_SERVER_APP_Context.Switch_c_Notification_Status = Switch_c_NOTIFICATION_ON; APP_DBG_MSG("-- P2P APPLICATION SERVER : NOTIFICATION ENABLED\n"); APP_DBG_MSG(" \n\r"); /* USER CODE END Service1Char2_NOTIFY_ENABLED_EVT */ break; case P2P_SERVER_SWITCH_C_NOTIFY_DISABLED_EVT: /* USER CODE BEGIN Service1Char2_NOTIFY_DISABLED_EVT */ P2P_SERVER_APP_Context.Switch_c_Notification_Status = Switch_c_NOTIFICATION_OFF; APP_DBG_MSG("-- P2P APPLICATION SERVER : NOTIFICATION DISABLED\n"); APP_DBG_MSG(" \n\r"); /* USER CODE END Service1Char2_NOTIFY_DISABLED_EVT */ break; default: /* USER CODE BEGIN Service1_Notification_default */ /* USER CODE END Service1_Notification_default */ break; } /* USER CODE BEGIN Service1_Notification_2 */ /* USER CODE END Service1_Notification_2 */ return; } void P2P_SERVER_APP_EvtRx(P2P_SERVER_APP_ConnHandleNotEvt_t *p_Notification) { /* USER CODE BEGIN Service1_APP_EvtRx_1 */ /* USER CODE END Service1_APP_EvtRx_1 */ switch(p_Notification->EvtOpcode) { /* USER CODE BEGIN Service1_APP_EvtRx_Service1_EvtOpcode */ /* USER CODE END Service1_APP_EvtRx_Service1_EvtOpcode */ case P2P_SERVER_CONN_HANDLE_EVT : P2P_SERVER_APP_Context.ConnectionHandle = p_Notification->ConnectionHandle; /* USER CODE BEGIN Service1_APP_CENTR_CONN_HANDLE_EVT */ /* USER CODE END Service1_APP_CENTR_CONN_HANDLE_EVT */ break; case P2P_SERVER_DISCON_HANDLE_EVT : P2P_SERVER_APP_Context.ConnectionHandle = 0xFFFF; /* USER CODE BEGIN Service1_APP_DISCON_HANDLE_EVT */ P2P_SERVER_APP_LED_BUTTON_context_Init(); /* USER CODE END Service1_APP_DISCON_HANDLE_EVT */ break; default: /* USER CODE BEGIN Service1_APP_EvtRx_default */ /* USER CODE END Service1_APP_EvtRx_default */ break; } /* USER CODE BEGIN Service1_APP_EvtRx_2 */ /* USER CODE END Service1_APP_EvtRx_2 */ return; } void P2P_SERVER_APP_Init(void) { P2P_SERVER_APP_Context.ConnectionHandle = 0xFFFF; P2P_SERVER_Init(); /* USER CODE BEGIN Service1_APP_Init */ UTIL_SEQ_RegTask( 1U << CFG_TASK_SEND_NOTIF_ID, UTIL_SEQ_RFU, P2P_SERVER_Switch_c_SendNotification); /** * Initialize LedButton Service */ P2P_SERVER_APP_Context.Switch_c_Notification_Status= Switch_c_NOTIFICATION_OFF; P2P_SERVER_APP_LED_BUTTON_context_Init(); /* USER CODE END Service1_APP_Init */ return; } /* USER CODE BEGIN FD */ void P2P_SERVER_APP_LED_BUTTON_context_Init(void) { BSP_LED_Off(LED_BLUE); P2P_SERVER_APP_Context.LedControl.Device_Led_Selection=0x01; /* Device1 */ P2P_SERVER_APP_Context.LedControl.Led1=0x00; /* led OFF */ P2P_SERVER_APP_Context.ButtonControl.Device_Button_Selection=0x01;/* Device1 */ P2P_SERVER_APP_Context.ButtonControl.ButtonStatus=0x00; return; } /* USER CODE END FD */ /************************************************************* * * LOCAL FUNCTIONS * *************************************************************/ __USED void P2P_SERVER_Switch_c_SendNotification(void) /* Property Notification */ { P2P_SERVER_APP_SendInformation_t notification_on_off = Switch_c_NOTIFICATION_OFF; P2P_SERVER_Data_t p2p_server_notification_data; p2p_server_notification_data.p_Payload = (uint8_t*)a_P2P_SERVER_UpdateCharData; p2p_server_notification_data.Length = 0; /* USER CODE BEGIN Service1Char2_NS_1*/ if(P2P_SERVER_APP_Context.ButtonControl.ButtonStatus == 0x00) { P2P_SERVER_APP_Context.ButtonControl.ButtonStatus = 0x01; } else { P2P_SERVER_APP_Context.ButtonControl.ButtonStatus = 0x00; } a_P2P_SERVER_UpdateCharData[0] = 0x01; /* Device Led selection */ a_P2P_SERVER_UpdateCharData[1] = P2P_SERVER_APP_Context.ButtonControl.ButtonStatus; /* Update notification data length */ p2p_server_notification_data.Length = (p2p_server_notification_data.Length) + 2; if(P2P_SERVER_APP_Context.Switch_c_Notification_Status == Switch_c_NOTIFICATION_ON) { APP_DBG_MSG("-- P2P APPLICATION SERVER : INFORM CLIENT BUTTON 1 PUSHED\n"); notification_on_off = Switch_c_NOTIFICATION_ON; } else { APP_DBG_MSG("-- P2P APPLICATION SERVER : CAN'T INFORM CLIENT - NOTIFICATION DISABLED\n"); } /* USER CODE END Service1Char2_NS_1*/ if (notification_on_off != Switch_c_NOTIFICATION_OFF && P2P_SERVER_APP_Context.ConnectionHandle != 0xFFFF) { P2P_SERVER_NotifyValue(P2P_SERVER_SWITCH_C, &p2p_server_notification_data, P2P_SERVER_APP_Context.ConnectionHandle); } /* USER CODE BEGIN Service1Char2_NS_Last*/ /* USER CODE END Service1Char2_NS_Last*/ return; } /* USER CODE BEGIN FD_LOCAL_FUNCTIONS*/ /* USER CODE END FD_LOCAL_FUNCTIONS*/ 程序摘抄与p2p_serverApp.c文件。 /* Private function prototypes -----------------------------------------------*/ static void P2P_SERVER_Switch_c_SendNotification(void); /* USER CODE BEGIN PFP */ static void P2P_SERVER_APP_LED_BUTTON_context_Init(void); 程序中有关键的回调函数:P2P_SERVER_Switch_c_SendNotification,这个函数在收到消息后被调用。 事件的执行如下: case P2P_SERVER_LED_C_WRITE_NO_RESP_EVT: /* USER CODE BEGIN Service1Char1_WRITE_NO_RESP_EVT */ if(p_Notification->DataTransfered.p_Payload[1] == 0x01) { BSP_LED_On(LED_BLUE); APP_DBG_MSG("-- P2P APPLICATION SERVER : LED1 ON\n"); P2P_SERVER_APP_Context.LedControl.Led1 = 0x01; /* LED1 ON */ } if(p_Notification->DataTransfered.p_Payload[1] == 0x00) { BSP_LED_Off(LED_BLUE); APP_DBG_MSG("-- P2P APPLICATION SERVER : LED1 OFF\n"); P2P_SERVER_APP_Context.LedControl.Led1 = 0x00; /* LED1 OFF */ } /* USER CODE END Service1Char1_WRITE_NO_RESP_EVT */ break; 这里含有一个开关控制:P2P_SERVER_SWITCH_C_NOTIFY_ENABLED_EVT可以扩展该函数。  

  • 2024-10-28
  • 回复了主题帖: 测评入围名单: 英飞凌PSOC™ 4100S Max Pioneer套件

    计划确认,可以按时完成测评。感谢英飞凌和EE

  • 2024-10-26
  • 回复了主题帖: #反激大作战#来聊一聊,在设计反激电源的时候,你觉得最重要的是什么?

    变压器最难的是基础知识,多数都是经验格式,但是又不告诉你这参数如何确定。先确定什么后确定什么。 例如: (1)开关频率和开关损耗什么关系 (2)线径和肌肤效应什么关系(频率一定的情况下) (3)变压器的电感如何确定等。 (4)气隙的距离和匝数关系等  

  • 2024-10-23
  • 发表了主题帖: 光耦模拟电位器原理

    1、如图:两个光耦模拟电位器的电路。 2、该电路使用两个光耦模拟电位器,PWM的脉宽通过上下两个光耦调节“电位器”的输出的电位。 这个电路通过RC滤波来控制电位器的输出电压,这个和简易的DAC非常相似。 我的问题是这个电路的功耗如何计算。是不是可以等效为电阻分压电路?  

  • 2024-10-22
  • 回复了主题帖: 请问,这个有两个MOS管控制的12V电压的工作过程怎么分析?

    就是EN-2端的电压不能直接开启Q3的G端电压,使用Q4作为中间转换一下。常见到的方案是Q4为三极管,这里用了MOS管

  • 回复了主题帖: 【NUCLEO-WB09KE】蓝牙通信与OTA升级

    wangerxian 发表于 2024-10-22 09:07 通过手机可以给它OTA升级吗。 可以,使用ST的工具软件或高版本的web页面都可以。这个比较方便

  • 2024-10-19
  • 回复了主题帖: 【NUCLEO-WB09KE】蓝牙通信与OTA升级

    感觉OTA应用的安全性有待提高

  • 2024-10-18
  • 发表了主题帖: 【NUCLEO-WB09KE】蓝牙通信与OTA升级

    本帖最后由 bigbat 于 2024-10-19 15:12 编辑 1、测试介绍 目前我们使用的升级都可以使用OTA进行升级,ST公司也可以使用蓝牙通讯进行OTA升级程序。本次测试将对OTA进行测试。测试的硬件除了NUCLEO-WB09KE开发板外,还需要准备手机硬件或PC主机。手机只可以用作OTA升级服务器,而PC机除了可以使用做OTA升级服务器外也可以用作开发使用。既然是OTA那么就应该使用方便才行。所以ST公司将提供了web方式的OTA服务程序。 按照ST公司的方案,只需要下载STM32WBA-Web-Bluetooth-App-Interfaces程序到本地,然后根据需要修改成公司的OTA页面。   但是这里有个BUG,我的应用在安装后,一直停在了”npm warn deprecated svgo@1.3.2: This SVGO version is no longer supported. Upgrade to v2.x.x.“就不再动了。 npm install     所以只能使用https://applible.github.io/Web_Bluetooth_App_WBA/   页面链接和配对和升级服务器。 2、NUCLEO-WB09KE开发板OTA存根服务器 开发板必须使用OTA服务的程序才可以。ST公司提供了BLE_ApplicationInstallManager、BLE_p2pServer_ota、BLE_HeartRate_ota三个程序带有OTA服务。 使用开发工具烧写到开发板   3、OTA服务建立程序 (1)建立配对   (2)配对成功   (3)升级设置   (4)进入OTA升级服务   (5)上传OTA程序,BLE_p2pServer_ota.bin程序   (6)升级程序成功后   (7)完后,程序就具有OTA功能的BLE_p2pServer_ota的程序   (8)连接配对后可以使用该页面测试   (9)测试程序   4、测试照片 Ligth ON 灯打开     Ligth OFF 灯关闭   5、总结 OTA程序的服务只要有OTA就可以使用OTA服务。    

  • 2024-10-17
  • 回复了主题帖: 【入围名单】Follow me第二季第3期,与得捷一起解锁开发板超能力!

    个人信息已更改,由于mail.tom.com的邮箱服务公司停止服务,邮箱已经更改。申请更改个人信息

  • 2024-10-13
  • 加入了学习《DigiKey 应用说:蓝牙5.4 新特性解读及实例演示》,观看 蓝牙5.4 新特性解读及实例演示

  • 2024-10-12
  • 回复了主题帖: 【NUCLEO-WB09KE】蓝牙通信的稳定性与BEACON服务

    dvacos 发表于 2024-10-11 16:43 Beacon 就是广播,不能连接代码专门设置的不给连接。 Beacon 协议可以包含指令的,例如:发出指令使得设备锁定等动作,只是需要设备服务端配合

  • 2024-10-11
  • 回复了主题帖: 【NUCLEO-WB09KE】PC机与蓝牙设备通讯与web编程

    dvacos 发表于 2024-10-11 16:42 你这个是谷歌的web ble的demo改的吧(询问,没恶意)? 这些demo没有服务器是不是不能在手机上运行,要 ... 手机上的需要看操作系统的版本,其实是浏览器的内核,我的程序也可以运行在web服务器当中。客户端本地不需要安装任何支持库

  • 回复了主题帖: 【NUCLEO-WB09KE】PC机与蓝牙设备通讯与web编程

    dvacos 发表于 2024-10-11 16:42 你这个是谷歌的web ble的demo改的吧(询问,没恶意)? 这些demo没有服务器是不是不能在手机上运行,要 ... 是web标准的BLE API,不需要额外的设置。最新的浏览器都支持。可以参考文章中的相关连接

  • 发表了主题帖: 【NUCLEO-WB09KE】蓝牙通信的稳定性与BEACON服务

    1、测试介绍 无线信标服务是一种物件定位跟踪服务,BLE Beacon服务可以用来监视我们身边的一些智能设备是否离开我们的距离。如:佩戴Beacon服务设备的儿童在该设备远离我们的距离足够远时,设备向我们发出“告警”,提示我们应该注意这一情况。本次测试将使用NUCLEO-WB09KE开发板模拟Beacon设备。 2、测试过程 (1)通过STM32Cube下载测试程序BLE_Beacon测试例程   (2)使用keil编译例程,烧写到开发板   (3)下载一个Beacon服务应用   Beacon服务软件比较多,我选择了BrigthBeacon软件。 (4)打开软件进行设置 注意:一定要给设备赋予蓝牙使用权限   打开后可以发现会从当前搜索到一些可以接收的Beacon设备,这些设备不需要预先和手机配对 (5)将开发板设备添加到软件当中。   需要添加的设备UUID为:00010203-0405-0607-0809-0a0b0c0d0e0f 这个UUID是从Readme.html文件中获得的。   开发板设备的UUID被登记后,就可以使用软件查看该设备的详细信息了。 (6)测试开发板的功能 因为开发板不能移动,所以我就将手机拿到远离开发板的地方进行测试。可能是我的USB BLE适配器太好了的缘故,我(我家在三楼,为板楼结构)将设备直到拿到一楼才发现设备信号丢失。   查找设备详细信息 回到二楼发现信号   设备信息   重新出现。 3、测试过程总结 测试中发现周围很多的Beacon设备,不知道开发板如何接收Beacon的信号。   对于Beacon服务和BLE设备关系是怎样定义的,本测试中的Beacon设备无法与主设备(PC或手机)都无法配对。后续我将继续深入的学习该协议。

  • 回复了主题帖: 【NUCLEO-WB09KE】PC机与蓝牙设备通讯与web编程

    最近正在学习node.js,发现js可以开发的内容大大超出了传统web的范畴,可以覆盖大部分的桌面APP。包括BLE API和摄像头等等外设。

  • 2024-10-10
  • 发表了主题帖: 【NUCLEO-WB09KE】PC机与蓝牙设备通讯与web编程

    1、测试介绍 本测试 使用开发板模拟心率仪,用来验证连接性、BLE、BLE 协议、BLE 配对、BLE 配置文件等项目。其中的程序可以作为BLE的编程框架来使用。测试使用NUCLEO-WB09KE作为BLE“服务端”,客户端使用web页面的javascript程序作为“客户端”。本测试最开始使用移动客户端作为测试工具,最近我在学习scratch编程时,发现现在的node.js也可以支持BLE的API,并且可以很好的使用web浏览器作为客户端向web网站发送测试数据,于是就改用javascript作为客户端了。 2、客户端介绍 客户端的源码是我从https://github.com/WebBluetoothCG/demos项目下载的。心率仪作为BLE的标准设备。通讯和数据格式已经被固定格式化了。只要提供规定的API函数就可以使用任何的客户端程序和设备链接。 首先是定义一个index.html文件作为页面 <!doctype html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Heart Rate Sensor Demo</title> <meta name="description" content="Monitor a heart rate sensor with a Web Bluetooth app."> <link rel="icon" sizes="192x192" href="../favicon.png"> <link rel="stylesheet" href="styles.css"> </head> <body> <div id="container"> <div id="statusText">GET &#x2764;</div> <canvas id="waves"></canvas> </div> <script src="/heartRateSensor.js"></script> <script src="/app.js"></script> </body> </html> 程序主要分为app.js,本程序主要是用来在画布“canvas”上面显示数据和界面交互。画布的id="waves"。 var canvas = document.querySelector('canvas'); var statusText = document.querySelector('#statusText'); statusText.addEventListener('click', function() { statusText.textContent = 'Breathe...'; heartRates = []; heartRateSensor.connect() .then(() => heartRateSensor.startNotificationsHeartRateMeasurement().then(handleHeartRateMeasurement)) .catch(error => { statusText.textContent = error; }); }); function handleHeartRateMeasurement(heartRateMeasurement) { heartRateMeasurement.addEventListener('characteristicvaluechanged', event => { var heartRateMeasurement = heartRateSensor.parseHeartRate(event.target.value); statusText.innerHTML = heartRateMeasurement.heartRate + ' &#x2764;'; heartRates.push(heartRateMeasurement.heartRate); drawWaves(); }); } var heartRates = []; var mode = 'bar'; canvas.addEventListener('click', event => { mode = mode === 'bar' ? 'line' : 'bar'; drawWaves(); }); function drawWaves() { requestAnimationFrame(() => { canvas.width = parseInt(getComputedStyle(canvas).width.slice(0, -2)) * devicePixelRatio; canvas.height = parseInt(getComputedStyle(canvas).height.slice(0, -2)) * devicePixelRatio; var context = canvas.getContext('2d'); var margin = 2; var max = Math.max(0, Math.round(canvas.width / 11)); var offset = Math.max(0, heartRates.length - max); context.clearRect(0, 0, canvas.width, canvas.height); context.strokeStyle = '#00796B'; if (mode === 'bar') { for (var i = 0; i < Math.max(heartRates.length, max); i++) { var barHeight = Math.round(heartRates[i + offset ] * canvas.height / 200); context.rect(11 * i + margin, canvas.height - barHeight, margin, Math.max(0, barHeight - margin)); context.stroke(); } } else if (mode === 'line') { context.beginPath(); context.lineWidth = 6; context.lineJoin = 'round'; context.shadowBlur = '1'; context.shadowColor = '#333'; context.shadowOffsetY = '1'; for (var i = 0; i < Math.max(heartRates.length, max); i++) { var lineHeight = Math.round(heartRates[i + offset ] * canvas.height / 200); if (i === 0) { context.moveTo(11 * i, canvas.height - lineHeight); } else { context.lineTo(11 * i, canvas.height - lineHeight); } context.stroke(); } } }); } window.onresize = drawWaves; document.addEventListener("visibilitychange", () => { if (!document.hidden) { drawWaves(); } }); heartRateSensor.js文件,js使用BLE通过API从设备中调测试数据。设备BLE被定义在navigator.bluetooth.requestDevice中,函数将返回一个设备class,成功后装配该对象。 (function() { 'use strict'; class HeartRateSensor { constructor() { this.device = null; this.server = null; this._characteristics = new Map(); } connect() { return navigator.bluetooth.requestDevice({filters:[{services:[ 'heart_rate' ]}]}) .then(device => { this.device = device; return device.gatt.connect(); }) .then(server => { this.server = server; return server.getPrimaryService('heart_rate'); }) .then(service => { return this._cacheCharacteristic(service, 'heart_rate_measurement'); }) } /* Heart Rate Service */ startNotificationsHeartRateMeasurement() { return this._startNotifications('heart_rate_measurement'); } stopNotificationsHeartRateMeasurement() { return this._stopNotifications('heart_rate_measurement'); } parseHeartRate(value) { // In Chrome 50+, a DataView is returned instead of an ArrayBuffer. value = value.buffer ? value : new DataView(value); let flags = value.getUint8(0); let rate16Bits = flags & 0x1; let result = {}; let index = 1; if (rate16Bits) { result.heartRate = value.getUint16(index, /*littleEndian=*/true); index += 2; } else { result.heartRate = value.getUint8(index); index += 1; } let contactDetected = flags & 0x2; let contactSensorPresent = flags & 0x4; if (contactSensorPresent) { result.contactDetected = !!contactDetected; } let energyPresent = flags & 0x8; if (energyPresent) { result.energyExpended = value.getUint16(index, /*littleEndian=*/true); index += 2; } let rrIntervalPresent = flags & 0x10; if (rrIntervalPresent) { let rrIntervals = []; for (; index + 1 < value.byteLength; index += 2) { rrIntervals.push(value.getUint16(index, /*littleEndian=*/true)); } result.rrIntervals = rrIntervals; } return result; } /* Utils */ _cacheCharacteristic(service, characteristicUuid) { return service.getCharacteristic(characteristicUuid) .then(characteristic => { this._characteristics.set(characteristicUuid, characteristic); }); } _readCharacteristicValue(characteristicUuid) { let characteristic = this._characteristics.get(characteristicUuid); return characteristic.readValue() .then(value => { // In Chrome 50+, a DataView is returned instead of an ArrayBuffer. value = value.buffer ? value : new DataView(value); return value; }); } _writeCharacteristicValue(characteristicUuid, value) { let characteristic = this._characteristics.get(characteristicUuid); return characteristic.writeValue(value); } _startNotifications(characteristicUuid) { let characteristic = this._characteristics.get(characteristicUuid); // Returns characteristic to set up characteristicvaluechanged event // handlers in the resolved promise. return characteristic.startNotifications() .then(() => characteristic); } _stopNotifications(characteristicUuid) { let characteristic = this._characteristics.get(characteristicUuid); // Returns characteristic to remove characteristicvaluechanged event // handlers in the resolved promise. return characteristic.stopNotifications() .then(() => characteristic); } } window.heartRateSensor = new HeartRateSensor(); })(); 当收到数据后调用相关的事件函数。BLE的API请参考:https://developer.mozilla.org/en-US/docs/Web/API/BluetoothDevice 3、测试过程 (1)首先使用STM32Cub下载BLE_HeartRate程序到本地磁盘。  (2)使用编译工具烧写到开发板。   我使用的是keil工具烧写到开发板。烧写完成后,开发板就可以模拟心率仪了。 (3)使用PC机连接和配对心率仪HR_5C   这里需要注意使用比较高的BLE适配器,最初我使用的是4.0的适配器,只能连接但是会出现问题。这里不知道是我的适配器的问题还是什么问题。我换成BLE 5.4的适配器就没有出现问题了。我的BLE 4.0是需要驱动的。是不是和这个有关系就不知道了,所以还请知道的朋友科普。 (4)配对连接设备   如果不配对就会连接失败   这个API会记录上次的配对设备,如果连接不上可以将设备重新上电和运行程序。 (5)配对连接后就可以从页面上显示数据了   4、总结 蓝牙设备有很多的属性文件。如果想开发BLE设备需要仔细的研究GATT官方。ST官方的协议栈编程的框架学习曲线较为陡直。目前我也是入门,在后期的测试中我会分享一些心得。    

  • 2024-09-16
  • 回复了主题帖: 【NUCLEO-WB09KE】开箱及开发环境测试

    不知道为什么链接配对成功,但是windows中没有出现串口设备。我的windows是win10,蓝牙是4.0模块。是不是需要5.4的模块呀  

  • 2024-09-15
  • 发表了主题帖: 【NUCLEO-WB09KE】开箱及开发环境测试

    1、开发板介绍 NUCLEO-WB09KE,其中核心MCU STM32WB09KE为超低功耗Arm Cortex-M0+ MCU,运行频率64 MHz,具有512 KB Flash存储器、64 KB RAM,支持Bluetooth LE 5.4。这个与ST公司推出的STM32WB的其它系列采用的是基于以64 MHz运行的Arm® Cortex®‐M4内核,该系列从结构上推断STM32WB0XX应该功耗要更低。 Bluetooth®低功耗5.4的传输距离更长,速度快的特点。我拿到手的ST NUCLEO-WB09KE开发板是由两块组成的。下层的是ST-Link调试和按键、LED开发板。上层是蓝牙核心开发板。   2、开发环境搭建 开发环境搭建的测试只测试出了keil的环境。STM32CubeProgrammer的环境一直没有成功,我为此还下载了最新版本的环境。VSCode+OpenOCD的环境因为没有STM32WB0XX芯片的支持有没有成功。期待ST能够尽快的完善该款芯片的支持。 (1)首先下载或升级STM32CubeMX的最新版本。从首页安装添加STM32WB0的支持包。   最新版本是默认支持的。低版本可能无法安装该支持包,因此需要新版STM32Cube   安装完成后安装keil的支持。 (2)STM32WB0的芯片在keil的官方无法直接获得支持包。需要手工安装该开发包。 从C:\Users\[username]\STM32Cube\Repository\STM32Cube_FW_WB0_V1.0.0\Utilities\PC_Softwarem目录可以获得keil和IAR的支持包。   (3)手工安装该支持包到keil环境。 解压zip文件     单机文件或从keil包管理其中手工安装   (4)从STM32Cube中导入STM32WB0的BLE_SerialPort_Server 例程。   (5)烧录程序到开发板   完成后就可以测试。 3、测试过程 烧录前需要将开发板的启动模式使用跳线设置为Bootloader模式,否则无法烧写程序。   上电后如果再次烧写程序,需要按开发板的RESET按钮!!!     (2)windows PC的蓝牙中可以添加SPortS_5C的设备。   (3)链接配对完成   至此环境搭建成功  

  • 2024-09-13
  • 回复了主题帖: 反激电源新手看过来,开源项目准备好了,是时候动手了~

    很好,谢谢楼主总结

统计信息

已有1181人来访过

  • 芯积分:5093
  • 好友:10
  • 主题:549
  • 回复:2317

留言

你需要登录后才可以留言 登录 | 注册


现在还没有留言