comparison Discovery/Src/cv_heartbeat.c @ 1034:195bfbdf961d Puls_Integration

Pulse measurement integration: Added function to parse standart GATT pulse service. Added compile switch to remove code from non dev builds.
author Ideenmodellierer
date Thu, 07 Aug 2025 20:18:52 +0200
parents 5f66e44d69f0
children 5b913cdaa9dc
comparison
equal deleted inserted replaced
1033:5f66e44d69f0 1034:195bfbdf961d
22 /// 22 ///
23 /// You should have received a copy of the GNU General Public License 23 /// You should have received a copy of the GNU General Public License
24 /// along with this program. If not, see <http://www.gnu.org/licenses/>. 24 /// along with this program. If not, see <http://www.gnu.org/licenses/>.
25 ////////////////////////////////////////////////////////////////////////////// 25 //////////////////////////////////////////////////////////////////////////////
26 26
27 #include "configuration.h"
28
29 #ifdef ENABLE_PULSE_SENSOR_BT
27 #include "cv_heartbeat.h" 30 #include "cv_heartbeat.h"
28 #include "tMenuEdit.h" 31 #include "tMenuEdit.h"
29 32
30 #include "gfx_fonts.h" 33 #include "gfx_fonts.h"
31 #include "tHome.h" 34 #include "tHome.h"
32 #include "ostc.h" 35 #include "ostc.h"
33 #include "tComm.h" 36 #include "tComm.h"
34 #include "tInfoLogger.h" 37 #include "tInfoLogger.h"
38 #include "stdlib.h"
35 39
36 static sensorHeartbeat_State_t heartbeatState = SENSOR_HB_OFFLINE; 40 static sensorHeartbeat_State_t heartbeatState = SENSOR_HB_OFFLINE;
37 41
38 static uint8_t OnAction_Heartbeat(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action); 42 static uint8_t OnAction_Heartbeat(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action);
39 static uint32_t startDetection_ms; 43 static uint32_t startDetection_ms;
50 static uint8_t curBtIndex = 0; 54 static uint8_t curBtIndex = 0;
51 static uint8_t connHandle = ' '; 55 static uint8_t connHandle = ' ';
52 static uint8_t evaluateDevIndex = 0xFF; 56 static uint8_t evaluateDevIndex = 0xFF;
53 static uint8_t evaluateSrvIndex = 0xFF; 57 static uint8_t evaluateSrvIndex = 0xFF;
54 static uint8_t evaluateCharIndex = 0xFF; 58 static uint8_t evaluateCharIndex = 0xFF;
55 static uint8_t evaluateDescIndex = 0xFF; 59
60 static void parsePulseMeasurement(uint8_t* pData, uint8_t length)
61 {
62 uint8_t rawData[10];
63 char text[40];
64 char* enptr;
65 uint8_t flags = 0;
66 uint16_t rr = 0;
67 uint8_t index = 0;
68 uint8_t* pRaw = (uint8_t*)&rawData;
69 char tmpStr[3];
70
71 tmpStr[2] = 0;
72
73 HRMeasurement_t pulseData;
74
75 for(index = 0; index < length; index +=2)
76 {
77 memcpy(tmpStr,&pData[index],2);
78 rawData[index / 2] = strtol(tmpStr, &enptr,16);
79 }
80 flags = pRaw[0];
81 index = 1;
82 /* 0: Heart Rate Format bit (0 = UINT8, 1 = UINT16) */
83 if (flags & 0x01)
84 {
85 pulseData.heart_rate = pRaw[index] | (pRaw[index + 1] << 8);
86 index += 2;
87 } else
88 {
89 pulseData.heart_rate = pRaw[index];
90 index += 1;
91 }
92
93 /* 3: Energy Expended Status */
94 if (flags & 0x08)
95 {
96 pulseData.energy_expended = pRaw[index] | (pRaw[index + 1] << 8);
97 index += 2;
98 } else
99 {
100 pulseData.energy_expended = 0;
101 }
102 /* 4: RR-Interval bit */
103 pulseData.rr_count = 0;
104 if (flags & 0x10)
105 {
106 while (index + 1 < 4 && pulseData.rr_count < 10)
107 {
108 rr = pRaw[index] | (pRaw[index + 1] << 8);
109 pulseData.rr_intervals[pulseData.rr_count++] = rr;
110 index += 2;
111 }
112 }
113 // snprintf(text,40,"Pulse: %d",pulseData.heart_rate);
114 // InfoLogger_writeLine((uint8_t*)text,strlen(text),0);
115 }
56 116
57 static indicatior_t checkIndicators(uint8_t* pdata) 117 static indicatior_t checkIndicators(uint8_t* pdata)
58 { 118 {
59 indicatior_t ret = NO_INDICATOR; 119 indicatior_t ret = NO_INDICATOR;
60 120
76 } 136 }
77 else if(strcmp((char*)pdata,"+UBTGDCD:") == 0) 137 else if(strcmp((char*)pdata,"+UBTGDCD:") == 0)
78 { 138 {
79 ret = DESCRIPTOR_INDICATOR; 139 ret = DESCRIPTOR_INDICATOR;
80 } 140 }
81 141 else if(strcmp((char*)pdata,"+UUBTGN:") == 0)
142 {
143 ret = PULSE_INDICATOR;
144 }
82 return ret; 145 return ret;
83 } 146 }
84 147
85 static void handleOK() 148 static void handleOK()
86 { 149 {
148 } 211 }
149 else 212 else
150 { 213 {
151 heartbeatState = SENSOR_HB_DISCONNECT; 214 heartbeatState = SENSOR_HB_DISCONNECT;
152 } 215 }
216 break;
217
218 case SENSOR_HB_SUBSCRIBE: heartbeatState = SENSOR_HB_CONNECTED;
153 break; 219 break;
154 case SENSOR_HB_DISCONNECT: evaluateDevIndex++; 220 case SENSOR_HB_DISCONNECT: evaluateDevIndex++;
155 connHandle= ' '; 221 connHandle= ' ';
156 if(evaluateDevIndex < curBtIndex) /* more devices to be evaluated? */ 222 if(evaluateDevIndex < curBtIndex) /* more devices to be evaluated? */
157 { 223 {
250 case BT_READ_DESC_UUID: if(writeIndex < 50) 316 case BT_READ_DESC_UUID: if(writeIndex < 50)
251 { 317 {
252 memcpy(curDevDescriptor.uuid, parameter, writeIndex); 318 memcpy(curDevDescriptor.uuid, parameter, writeIndex);
253 } 319 }
254 break; 320 break;
321 case BT_READ_PULSE_DATA: if(writeIndex < 50)
322 {
323 parsePulseMeasurement(parameter, writeIndex);
324 }
325 break;
255 default: 326 default:
256 break; 327 break;
257 } 328 }
258 curLineIndex = 0; 329 curLineIndex = 0;
259 writeIndex = 0; 330 writeIndex = 0;
273 case CONNECTION_INDICATOR: readType = BT_READ_CON_DETAILS; 344 case CONNECTION_INDICATOR: readType = BT_READ_CON_DETAILS;
274 break; 345 break;
275 case SERVICE_INDICATOR: readType = BT_READ_SERV_HANDLE; 346 case SERVICE_INDICATOR: readType = BT_READ_SERV_HANDLE;
276 break; 347 break;
277 case CHARACTERISTIC_INDICATOR: readType = BT_READ_CHAR_CONHANDLE; 348 case CHARACTERISTIC_INDICATOR: readType = BT_READ_CHAR_CONHANDLE;
278 // snprintf(text,40,"Found Char");
279 // InfoLogger_writeLine((uint8_t*)text,strlen(text),0);
280 break; 349 break;
281 case DESCRIPTOR_INDICATOR: readType = BT_READ_DESC_CONHANDLE; 350 case DESCRIPTOR_INDICATOR: readType = BT_READ_DESC_CONHANDLE;
282 break; 351 break;
283 352 case PULSE_INDICATOR: readType = BT_READ_PULSE_CONHANDLE;
353 break;
284 default: 354 default:
285 break; 355 break;
286 } 356 }
287 writeIndex = 0; 357 writeIndex = 0;
288 memset(parameter,0,sizeof(parameter)); 358 memset(parameter,0,sizeof(parameter));
374 { 444 {
375 memcpy(curDevDescriptor.descHandle, parameter, writeIndex); 445 memcpy(curDevDescriptor.descHandle, parameter, writeIndex);
376 } 446 }
377 readType = BT_READ_DESC_UUID; 447 readType = BT_READ_DESC_UUID;
378 break; 448 break;
449 case BT_READ_PULSE_CONHANDLE: curDevDescriptor.conHandle = parameter[0];
450 readType = BT_READ_PULSE_VALUEHANDLE;
451 break;
452 case BT_READ_PULSE_VALUEHANDLE: if(writeIndex < 10)
453 {
454 // if(strcmp((char*)curDevCharacteristic[evaluateCharIndex].valueHandle,(char*) parameter) == 0)
455 {
456 readType = BT_READ_PULSE_DATA;
457 }
458 #if 0
459 else
460 {
461 readType = BT_READ_NOTHING;
462 }
463 #endif
464 }
465 break;
379 default: readType = BT_READ_NOTHING; 466 default: readType = BT_READ_NOTHING;
380 break; 467 break;
381 } 468 }
382 writeIndex = 0; 469 writeIndex = 0;
383 memset(parameter,0 , sizeof(parameter)); 470 memset(parameter,0 , sizeof(parameter));
384 } 471 }
385 else 472 else
386 { 473 {
387 // if(readType != BT_READ_NOTHING) 474 if(readType != BT_READ_NOTHING)
388 { 475 {
389 parameter[writeIndex++] = data; 476 parameter[writeIndex++] = data;
390 } 477 }
391 } 478 }
392 } 479 }
489 break; 576 break;
490 #endif 577 #endif
491 case SENSOR_HB_CONNECT: if(evaluateDevIndex < curBtIndex) 578 case SENSOR_HB_CONNECT: if(evaluateDevIndex < curBtIndex)
492 { 579 {
493 snprintf(cmd, sizeof(cmd), "AT+UBTACLC=%s\r\n",btDeviceList[evaluateDevIndex].address); 580 snprintf(cmd, sizeof(cmd), "AT+UBTACLC=%s\r\n",btDeviceList[evaluateDevIndex].address);
494 // evaluateDevIndex = devicesIndex;
495 // devicesIndex++;
496 } 581 }
497 break; 582 break;
498 case SENSOR_HB_DISCONNECT: snprintf(cmd, sizeof(cmd), "AT+UBTACLD=%c\r\n",connHandle); 583 case SENSOR_HB_DISCONNECT: snprintf(cmd, sizeof(cmd), "AT+UBTACLD=%c\r\n",connHandle);
499 break; 584 break;
500 case SENSOR_HB_SERVICES: if((connHandle >= '0') && (connHandle <= '9') && (lastState != SENSOR_HB_SERVICES)) 585 case SENSOR_HB_SERVICES: if((connHandle >= '0') && (connHandle <= '9') && (lastState != SENSOR_HB_SERVICES))
507 ,curDeviceService[evaluateSrvIndex].end); 592 ,curDeviceService[evaluateSrvIndex].end);
508 memset(curDevCharacteristic, 0, sizeof(curDevCharacteristic)); 593 memset(curDevCharacteristic, 0, sizeof(curDevCharacteristic));
509 break; 594 break;
510 case SENSOR_HB_DESCRIPTOR: snprintf(cmd, sizeof(cmd), "AT+UBTGDCD=%c,%s,%s\r\n",connHandle,curDevCharacteristic[evaluateCharIndex].valueHandle 595 case SENSOR_HB_DESCRIPTOR: snprintf(cmd, sizeof(cmd), "AT+UBTGDCD=%c,%s,%s\r\n",connHandle,curDevCharacteristic[evaluateCharIndex].valueHandle
511 ,curDeviceService[evaluateSrvIndex].end); 596 ,curDeviceService[evaluateSrvIndex].end);
512 //memset(curDevDescriptor, 0, sizeof(curDevCharacteristic));
513 break; 597 break;
514 case SENSOR_HB_SUBSCRIBE: snprintf(cmd, sizeof(cmd), "AT+UBTGWC=%c,%s,1\r\n",connHandle,curDevDescriptor.descHandle); 598 case SENSOR_HB_SUBSCRIBE: snprintf(cmd, sizeof(cmd), "AT+UBTGWC=%c,%s,1\r\n",connHandle,curDevDescriptor.descHandle);
515 break; 599 break;
516 default: 600 default:
517 break; 601 break;
582 break; 666 break;
583 } 667 }
584 668
585 write_buttonTextline(TXT2BYTE_ButtonMinus, TXT2BYTE_ButtonEnter, TXT2BYTE_ButtonPlus); 669 write_buttonTextline(TXT2BYTE_ButtonMinus, TXT2BYTE_ButtonEnter, TXT2BYTE_ButtonPlus);
586 } 670 }
587 671 #endif