You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

391 lines
12 KiB

1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
  1. #include "zble_module.h"
  2. #include "zdatachannel_service.h"
  3. #include "znordic.h"
  4. //
  5. #include <stdarg.h>
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9. //
  10. #include <math.h>
  11. #include "app_scheduler.h"
  12. #include "znordic.h"
  13. #if defined(UART_PRESENT)
  14. #include "nrf_uart.h"
  15. #endif
  16. #if defined(UARTE_PRESENT)
  17. #include "nrf_uarte.h"
  18. #endif
  19. #if 0
  20. int main() {
  21. one_conduction_main();
  22. return 0;
  23. }
  24. #else
  25. #include "nrfx_timer.h"
  26. ZDATACHANNEL_DEF(m_zhrs, 2 /*���ȼ�*/, 1 /*client num*/); // ��������
  27. static const nrfx_timer_t m_timer = NRFX_TIMER_INSTANCE(1); /**< Timer used for channel sweeps and tx with duty cycle. */
  28. #define PI 3.14159265358979323846
  29. /********************************************************************************************************
  30. * LOW PASS FILTER
  31. ********************************************************************************************************/
  32. typedef struct {
  33. float coef[2];
  34. float v_out[2];
  35. } LPFilter;
  36. void LPFilter_Init(LPFilter *filter, float cutoffFreqHz, float sampleTimeS);
  37. float LPFilter_Update(LPFilter *filter, float v_in);
  38. /********************************************************************************************************
  39. * HIGH PASS FILTER
  40. ********************************************************************************************************/
  41. typedef struct {
  42. float coef;
  43. float v_out[2];
  44. float v_in[2];
  45. } HPFilter;
  46. void HPFilter_Init(HPFilter *filter, float cutoffFreqHz, float sampleTimeS);
  47. float HPFilter_Update(HPFilter *filter, float v_in);
  48. /********************************************************************************************************
  49. * BAND PASS FILTER
  50. ********************************************************************************************************/
  51. typedef struct {
  52. LPFilter lpf;
  53. HPFilter hpf;
  54. float out_in;
  55. } PBFilter;
  56. void PBFilter_Init(PBFilter *filter, float HPF_cutoffFreqHz, float LPF_cutoffFreqHz, float sampleTimeS);
  57. float PBFilter_Update(PBFilter *filter, float v_in);
  58. /********************************************************************************************************
  59. * NOTCH FILTER
  60. ********************************************************************************************************/
  61. typedef struct {
  62. float alpha;
  63. float beta;
  64. float vin[3];
  65. float vout[3];
  66. } NOTCHFilter;
  67. void NOTCHFilter_Init(NOTCHFilter *filter, float centerFreqHz, float notchWidthHz, float sampleTimeS);
  68. float NOTCHFilter_Update(NOTCHFilter *filter, float vin);
  69. #define PI 3.141592653
  70. /********************************************************************************************************
  71. * LOW PASS FILTER
  72. ********************************************************************************************************/
  73. void LPFilter_Init(LPFilter *filter, float cutoffFreqHz, float sampleTimeS) {
  74. float RC = 0.0;
  75. RC = 1.0 / (2 * PI * cutoffFreqHz);
  76. filter->coef[0] = sampleTimeS / (sampleTimeS + RC);
  77. filter->coef[1] = RC / (sampleTimeS + RC);
  78. filter->v_out[0] = 0.0;
  79. filter->v_out[1] = 0.0;
  80. }
  81. float LPFilter_Update(LPFilter *filter, float v_in) {
  82. filter->v_out[1] = filter->v_out[0];
  83. filter->v_out[0] = (filter->coef[0] * v_in) + (filter->coef[1] * filter->v_out[1]);
  84. return (filter->v_out[0]);
  85. }
  86. /********************************************************************************************************
  87. * HIGH PASS FILTER
  88. ********************************************************************************************************/
  89. void HPFilter_Init(HPFilter *filter, float cutoffFreqHz, float sampleTimeS) {
  90. float RC = 0.0;
  91. RC = 1.0 / (2 * PI * cutoffFreqHz);
  92. filter->coef = RC / (sampleTimeS + RC);
  93. filter->v_in[0] = 0.0;
  94. filter->v_in[1] = 0.0;
  95. filter->v_out[0] = 0.0;
  96. filter->v_out[1] = 0.0;
  97. }
  98. float HPFilter_Update(HPFilter *filter, float v_in) {
  99. filter->v_in[1] = filter->v_in[0];
  100. filter->v_in[0] = v_in;
  101. filter->v_out[1] = filter->v_out[0];
  102. filter->v_out[0] = filter->coef * (filter->v_in[0] - filter->v_in[1] + filter->v_out[1]);
  103. return (filter->v_out[0]);
  104. }
  105. /********************************************************************************************************
  106. * BAND PASS FILTER
  107. ********************************************************************************************************/
  108. void PBFilter_Init(PBFilter *filter, float HPF_cutoffFreqHz, float LPF_cutoffFreqHz, float sampleTimeS) {
  109. LPFilter_Init(&filter->lpf, LPF_cutoffFreqHz, sampleTimeS);
  110. HPFilter_Init(&filter->hpf, HPF_cutoffFreqHz, sampleTimeS);
  111. filter->out_in = 0.0;
  112. }
  113. float PBFilter_Update(PBFilter *filter, float v_in) {
  114. filter->out_in = HPFilter_Update(&filter->hpf, v_in);
  115. filter->out_in = LPFilter_Update(&filter->lpf, filter->out_in);
  116. return (filter->out_in);
  117. }
  118. /********************************************************************************************************
  119. * NOTCH FILTER
  120. ********************************************************************************************************/
  121. void NOTCHFilter_Init(NOTCHFilter *filter, float centerFreqHz, float notchWidthHz, float sampleTimeS) {
  122. // filter frequency to angular (rad/s)
  123. float w0_rps = 2.0 * PI * centerFreqHz;
  124. float ww_rps = 2.0 * PI * notchWidthHz;
  125. // pre warp center frequency
  126. float w0_pw_rps = (2.0 / sampleTimeS) * tanf(0.5 * w0_rps * sampleTimeS);
  127. // computing filter coefficients
  128. filter->alpha = 4.0 + w0_rps * w0_pw_rps * sampleTimeS * sampleTimeS;
  129. filter->beta = 2.0 * ww_rps * sampleTimeS;
  130. // clearing input and output buffers
  131. for (uint8_t n = 0; n < 3; n++) {
  132. filter->vin[n] = 0;
  133. filter->vout[n] = 0;
  134. }
  135. }
  136. float NOTCHFilter_Update(NOTCHFilter *filter, float vin) {
  137. // shifting samples
  138. filter->vin[2] = filter->vin[1];
  139. filter->vin[1] = filter->vin[0];
  140. filter->vout[2] = filter->vout[1];
  141. filter->vout[1] = filter->vout[0];
  142. filter->vin[0] = vin;
  143. // compute new output
  144. filter->vout[0] = (filter->alpha * filter->vin[0] + 2.0 * (filter->alpha - 8.0) * filter->vin[1] + filter->alpha * filter->vin[2] - (2.0f * (filter->alpha - 8.0) * filter->vout[1] + (filter->alpha - filter->beta) * filter->vout[2])) / (filter->alpha + filter->beta);
  145. return (filter->vout[0]);
  146. }
  147. /*******************************************************************************
  148. * MAIN *
  149. *******************************************************************************/
  150. static void zdatachannel_data_handler(zdatachannel_evt_t *p_evt) {
  151. /**
  152. * @brief
  153. */
  154. if (p_evt->type == ZDATACHANNEL_EVT_RX_DATA) {
  155. }
  156. }
  157. static void on_service_init(void) {
  158. ZLOGI("init zdatachannel service");
  159. zdatachannel_init_t zdatachannle_init;
  160. memset(&zdatachannle_init, 0, sizeof(zdatachannle_init));
  161. zdatachannle_init.data_handler = zdatachannel_data_handler;
  162. ZERROR_CHECK(zdatachannel_init(&m_zhrs, &zdatachannle_init));
  163. }
  164. int16_t adc_val_cache0[5] = {0};
  165. int16_t adc_val_cache1[5] = {0};
  166. int16_t adc_val_cache2[5] = {0};
  167. int16_t adc_val_cache3[5] = {0};
  168. int adc_val_index = 0;
  169. void sendpacket_to_pc() {
  170. uint8_t data[255];
  171. // adc_val_cache[0] = 1;
  172. // adc_val_cache[1] = 2;
  173. // adc_val_cache[2] = 3;
  174. // adc_val_cache[3] = 4;
  175. // adc_val_cache[4] = 5;
  176. for (int i = 0; i < adc_val_index; i++) {
  177. if (adc_val_cache0[i] > 4096) {
  178. adc_val_cache0[i] = 4096;
  179. }
  180. if (adc_val_cache1[i] > 4096) {
  181. adc_val_cache1[i] = 4096;
  182. }
  183. if (adc_val_cache2[i] > 4096) {
  184. adc_val_cache2[i] = 4096;
  185. }
  186. if (adc_val_cache3[i] > 4096) {
  187. adc_val_cache3[i] = 4096;
  188. }
  189. if (adc_val_cache0[i] < 0) {
  190. adc_val_cache0[i] = 0;
  191. }
  192. if (adc_val_cache1[i] < 0) {
  193. adc_val_cache1[i] = 0;
  194. }
  195. if (adc_val_cache2[i] < 0) {
  196. adc_val_cache2[i] = 0;
  197. }
  198. if (adc_val_cache3[i] < 0) {
  199. adc_val_cache3[i] = 0;
  200. }
  201. }
  202. for (int i = 0; i < adc_val_index; i++) {
  203. data[i * 12 + 0] = 0xA2;
  204. data[i * 12 + 1] = 0x2;
  205. data[i * 12 + 2] = adc_val_cache0[i] & 0xff;
  206. data[i * 12 + 3] = adc_val_cache0[i] >> 8 & 0xff;
  207. data[i * 12 + 4] = adc_val_cache1[i] & 0xff;
  208. data[i * 12 + 5] = adc_val_cache1[i] >> 8 & 0xff;
  209. data[i * 12 + 6] = adc_val_cache2[i] & 0xff;
  210. data[i * 12 + 7] = adc_val_cache2[i] >> 8 & 0xff;
  211. data[i * 12 + 8] = adc_val_cache3[i] & 0xff;
  212. data[i * 12 + 9] = adc_val_cache3[i] >> 8 & 0xff;
  213. data[i * 12 + 10] = 0x2;
  214. data[i * 12 + 11] = 0xA2;
  215. }
  216. zdatachannel_data_send2(data, 12 * adc_val_index);
  217. }
  218. #if 1
  219. #if 0
  220. // ����һ�׸�ͨ�˲����ṹ��
  221. typedef struct {
  222. float alpha; // ʱ�䳣��
  223. float previous_output; // ��һʱ�̵�����
  224. } HighPassFilter;
  225. HighPassFilter myFilter;
  226. // ��ʼ���˲���
  227. void initializeFilter(HighPassFilter* filter, float alpha) {
  228. filter->alpha = alpha;
  229. filter->previous_output = 0.0;
  230. }
  231. // һ�׸�ͨ�˲�����
  232. float filterValue(HighPassFilter* filter, float input) {
  233. // ��������
  234. float output = filter->alpha * (input - filter->previous_output) + filter->previous_output;
  235. // ������һ�ε�����
  236. filter->previous_output = output;
  237. return output;
  238. }
  239. #endif
  240. #endif
  241. NOTCHFilter notchfilter;
  242. LPFilter lowpassfilter;
  243. static void nrfx_timer_event_handler(nrf_timer_event_t event_type, void *p_context) { //
  244. // raw data
  245. int16_t val = SingleLeadECG_ecg_plod_get_ecg_val(); //
  246. adc_val_cache0[adc_val_index] = val;
  247. int16_t notchf_val = NOTCHFilter_Update(&notchfilter, val);
  248. adc_val_cache1[adc_val_index] = notchf_val;
  249. int16_t lowpassf_val = LPFilter_Update(&lowpassfilter, notchf_val);
  250. adc_val_cache2[adc_val_index] = lowpassf_val;
  251. // val = low_pass_filter(val);
  252. /*******************************************************************************
  253. * ʾݼֵ *
  254. *******************************************************************************/
  255. adc_val_index++;
  256. if (adc_val_index >= 5) {
  257. if (zdatachannel_is_connected()) {
  258. sendpacket_to_pc();
  259. } else {
  260. }
  261. adc_val_index = 0;
  262. }
  263. static int cnt;
  264. static bool state;
  265. cnt++;
  266. if (zdatachannel_is_connected()) {
  267. SingleLeadECG_led_green_set_state(1);
  268. } else {
  269. if (cnt % 20 == 0) {
  270. SingleLeadECG_led_green_set_state(state);
  271. state = !state;
  272. }
  273. }
  274. }
  275. int main() { //
  276. APP_SCHED_INIT(APP_TIMER_SCHED_EVENT_DATA_SIZE, 20);
  277. // low_pass_filter_init();
  278. // initializeFilter(&myFilter, alpha);
  279. NOTCHFilter_Init(&notchfilter, 50, 30, 0.002);
  280. LPFilter_Init(&lowpassfilter, 200, 0.002);
  281. znordic_init();
  282. NRF_LOG_INFO("compile time :%s", __TIME__);
  283. ztm_t tm;
  284. static zble_module_cfg_t cfg = //
  285. {
  286. .deviceName = "OneLeadTest",
  287. .on_service_init = on_service_init,
  288. };
  289. zble_module_init(&cfg);
  290. SingleLeadECG_adc_module_init();
  291. SingleLeadECG_led_init();
  292. SingleLeadECG_led_green_set_state(0);
  293. zble_module_start_adv();
  294. /*******************************************************************************
  295. * ʱʼ *
  296. *******************************************************************************/
  297. /**
  298. * @brief ʼʱ
  299. */
  300. nrfx_err_t err;
  301. nrfx_timer_config_t timer_cfg = {
  302. .frequency = NRF_TIMER_FREQ_500kHz,
  303. .mode = NRF_TIMER_MODE_TIMER,
  304. .bit_width = NRF_TIMER_BIT_WIDTH_24,
  305. .p_context = NULL,
  306. .interrupt_priority = NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY,
  307. };
  308. err = nrfx_timer_init(&m_timer, &timer_cfg, nrfx_timer_event_handler);
  309. if (err != NRFX_SUCCESS) {
  310. NRF_LOG_ERROR("nrfx_timer_init failed with: %d\n", err);
  311. }
  312. uint32_t timer_ticks = nrfx_timer_ms_to_ticks(&m_timer, 2); // 500HZ
  313. nrfx_timer_extended_compare(&m_timer, NRF_TIMER_CC_CHANNEL0, timer_ticks, NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK, true);
  314. nrfx_timer_enable(&m_timer);
  315. znordic_loop();
  316. }
  317. #endif