首页 > 解决方案 > 将 STM 库适配到 Arduino 时出错!(对于 ECG(BMD101))

问题描述

我尝试了很多方法来获取心电图信号,但在我的城市,心电图的最新卡和芯片并不容易获得。为此,我得到了 MikroElectronica 的 4click 卡。MikroElectronica 创建的库不适合 Arduino 使用。但是我已经为我的项目工作了 8 个月,并且我在 Nano 33 BLE Sense 上编写了所有代码。由于我是软件开发的初学者,因此将库适应 Arduino 对我来说并不容易。MikroElectronica 的 4click 库在链接中。

https://github.com/MikroElektronika/ECG_4_click

我为 Arduino 创建的头目录如下。

#ifndef ekgg
#define ekgg

#include "Arduino.h"
#define T_ECG4_RETVAL     uint8_t

typedef void ( *T_ecg4_hdl )( uint8_t*, uint8_t*, uint8_t*, uint8_t* );

static T_ecg4_hdl  driver_hdl;
static T_ECG4_RETVAL  response_ready=0;

const uint8_t _ECG4_SYNC_BYTE                    = 0xAA;
const uint8_t _ECG4_EXCODE_BYTE                  = 0x55;
const uint8_t _ECG4_SIGNAL_QUALITY_CODE_BYTE     = 0x02;
const uint8_t _ECG4_HEART_RATE_CODE_BYTE         = 0x03;
const uint8_t _ECG4_RAW_DATA_CODE_BYTE           = 0x80;
const T_ECG4_RETVAL _ECG4_RESPONSE_READY         = 0x01;
const T_ECG4_RETVAL _ECG4_RESPONSE_NOT_READY     = 0x00;





void ecg4_response_handler_set( void ( *handler )( uint8_t*, uint8_t*, uint8_t*, uint8_t* ) )
{
    driver_hdl = handler;
    
}



T_ECG4_RETVAL ecg4_responseReady( void )
{
    if (response_ready)
    {
        response_ready = _ECG4_RESPONSE_NOT_READY;
        

        return _ECG4_RESPONSE_READY;
        
    }

    return _ECG4_RESPONSE_NOT_READY;
}

void ecg4_uart_isr( void )
{
    static uint8_t rx_buff[ 256 ];
    static uint8_t rx_cnt = 0;
    static uint8_t rx_idx;
    static uint8_t payload_size;
    static uint8_t row_check = 0;
    static uint8_t op_code;
    static uint8_t row_size;
    static uint8_t row_size_check;
    static uint8_t checksum = 0;
    static uint8_t row_cnt = 0;
    uint8_t rx_dat;

    rx_dat = Serial1.read();
    
    
    
    if ((rx_cnt == 0) && (rx_dat != _ECG4_SYNC_BYTE))
    {
        rx_cnt = 0;
        
        return;
    }
    else if ((rx_cnt == 1) && (rx_dat != _ECG4_SYNC_BYTE))
    {
        rx_cnt = 0;
        
        return;
    }
    else if (rx_cnt == 2)
    {
        payload_size = rx_dat;
        rx_cnt++;
        row_check = 1;
        
        return;
    }
    else if (rx_cnt > 2)
    {
        if (rx_cnt - 3 < payload_size)
        {
            if (rx_dat == _ECG4_EXCODE_BYTE)
            {
                row_check = 1;
                checksum += rx_dat;
                rx_cnt++;
                
                return;
            }
            
            if (row_check == 1)
            {
                op_code = rx_dat;
                row_check = 0;
                checksum += rx_dat;
                
                if ((op_code == _ECG4_SIGNAL_QUALITY_CODE_BYTE) || (op_code == _ECG4_HEART_RATE_CODE_BYTE))
                {
                    row_size = 1;
                    row_size_check = 0;
                }
                else if (op_code == _ECG4_RAW_DATA_CODE_BYTE)
                {
                    row_size_check = 1;
                }
                else
                {
                    rx_cnt = 0;
                    checksum = 0;
                    
                    return;
                }
                
                rx_idx = 0;
                rx_cnt++;
                
                return;
            }
            
            if (row_size_check == 1)
            {
                row_size = rx_dat;
                row_size_check = 0;
                checksum += rx_dat;
                rx_cnt++;
                
                return;
            }
            
            if (rx_idx < row_size)
            {
                rx_buff[ rx_idx ] = rx_dat;
                rx_idx++;
                checksum += rx_dat;
                           
                if (rx_idx == row_size)
                {
                    driver_hdl( &op_code, &row_size, rx_buff, &row_cnt );
                    row_cnt++;
                    row_check = 1;
                }
                
                rx_cnt++;
                
                return;
            }
        }
        else
        {
            checksum = ~checksum;
            
            if (checksum == rx_dat)
            {
                response_ready = _ECG4_RESPONSE_READY;
                 
            }
            else
            {
                response_ready = _ECG4_RESPONSE_NOT_READY;
            }
            
            checksum = 0;
            row_cnt = 0;
            rx_cnt = 0;
            rx_idx = 0;
            
            return;
        }
    }
    
    rx_cnt++;
}



#endif

我的运行(.ino)目录在下面。

#include "ekgg.h"



uint8_t response[ 256 ];
uint8_t row_counter;
uint32_t plot_x;
uint8_t row_size_cnt;
T_ECG4_RETVAL resp_ready;


void setup() {
 Serial1.begin(57600);
 while(!Serial1);
 Serial.begin(57600);
 while(!Serial);
 attachInterrupt( 1ul , ecg4_uart_isr , FALLING ); //1ul -> Nano 33 BLE Sense RX address.

 

}

void loop() {

  
  applicationTask();
  ecg4_response_handler_set( &makeResponse );

}

void makeResponse( uint8_t *opCode, uint8_t *rowSize, uint8_t *rxBuff, uint8_t *rowCnt )
{

    uint8_t idx_cnt;
    
    if (*rowCnt == 0)
    {
        row_size_cnt = 0;
    }
    
    response[ row_size_cnt ] = *opCode;
    response[ row_size_cnt + 1 ] = *rowSize;

    for (idx_cnt = 0; idx_cnt < *rowSize; idx_cnt++)
    {
        response[ row_size_cnt + 2 + idx_cnt ] = rxBuff[ idx_cnt ];
    }
    
    row_size_cnt += (*rowSize + 2);
    row_counter = *rowCnt;
}

void applicationTask()
{
    resp_ready = ecg4_responseReady();
    
    if (resp_ready == _ECG4_RESPONSE_READY)
    {
        
        processResponse();
    }
   
}

void processResponse()
{
    uint8_t cnt;
    uint8_t idx_cnt;
    int16_t raw_data;
    
    idx_cnt = 0;
    
    for (cnt = 0; cnt <= row_counter; cnt++)
    {
        if (response[ idx_cnt ] == _ECG4_RAW_DATA_CODE_BYTE)
        {
        
            raw_data = response[ idx_cnt + 2 ];
            raw_data <<= 8;
            raw_data |= response[ idx_cnt + 3 ];
            plotData( raw_data );
        }
        /*
        if ((response[ idx_cnt ] == _ECG4_SIGNAL_QUALITY_CODE_BYTE) || (response[ idx_cnt ] == _ECG4_HEART_RATE_CODE_BYTE))
        {
            logData( response[ idx_cnt ], response[ idx_cnt + 2 ] );
        }
        */
        
        idx_cnt += (response[ idx_cnt + 1 ] + 2);
    }
}

void plotData( int16_t plot_data ){

  Serial.println(plot_data);
  delay(3);
 
}

void logData( uint8_t code_val, uint8_t data_val )
{
   

    if (code_val == _ECG4_SIGNAL_QUALITY_CODE_BYTE)
    {
        Serial.print( "** Signal Quality (0 - sensor off, 200 - sensor on) : ");
        Serial.println( data_val );
       
    }
    else if (code_val == _ECG4_HEART_RATE_CODE_BYTE)
    {
    
       Serial.print ( "** Real-time Heart Rate : " );
        Serial.println( data_val);
    }
}

这是我准备的代码。我得到了这段代码的输出,但只是到了一定程度。

bmd101_output

bmd101_output2

我可以在我的串行绘图仪上看到我的数据中的一个点,而在某个点之后我就看不到了。如果您能提供这方面的信息,我将不胜感激。我们是书面的出路。非常感谢您的关注。

标签: c++carduinostm32lib

解决方案


推荐阅读