电子产品世界 » 论坛首页 » 活动中心 » 板卡试用 » 跳动的心之三——另辟蹊径出心跳

共4条 1/1 1 跳转至

跳动的心之三——另辟蹊径出心跳

工程师
2019-01-01 21:51:28    评分

用STM32CubeMX和keil5组合,编出来的程序无论怎么查都找不出问题,头疼啊

没办法,找过一些程序作参考,但小白终究是小白,还是调不出来,正当我要放弃的时候,突然想起在查找板子相关资料的时候发现这个板子是可以支持mebd项目中的在线开发环境的,我要是从那个方向下手,换个程序编会不会成功呢,与其纠缠在原来的程序中,倒不如尝试一下新的编程方式。

说干就干。首先,点开mbed在线调试。

image.png

image.png

image.png

第一次使用需要注册,注册完直接登录,创建工程。可以直接导入创建例程工程。随便选择一个,点击“OK”创建工程,直接打开main.c文件。

image.png

可以看到直接就有例程了,咱们的项目用不到,直接全选删除即可。

image.png

界面比较简洁,一看就懂。

加入程序。

#include "mbed.h"


#define false 0

#define true 1

Ticker tick;

DigitalOut leds(D12);

DigitalOut led1(LED1);

AnalogIn pulsepin(A0);//analog input pin

Serial pc(SERIAL_TX, SERIAL_RX);//USB TO SERIAL


// these variables are volatile because they are used during the shorterrupt service routine!

volatile short BPM;                   // used to hold the pulse rate

volatile short Signal;                // holds the incoming raw data

volatile short IBI = 600;             // holds the time between beats, must be seeded!

volatile char Pulse = false;     // true when pulse wave is high, false when it's low

volatile char QS = false;        // becomes true when Arduoino finds a beat.

volatile short rate[10];                    // array to hold last ten IBI values

volatile unsigned long sampleCounter = 0;          // used to determine pulse timing

volatile unsigned long lastBeatTime = 0;           // used to find IBI

volatile short P =512;                      // used to find peak in pulse wave, seeded

volatile short T = 512;                     // used to find trough in pulse wave, seeded

volatile short thresh = 512;                // used to find instant moment of heart beat, seeded

volatile short amp = 100;                   // used to hold amplitude of pulse waveform, seeded

volatile char firstBeat = true;        // used to seed rate array so we startup with reasonable BPM

volatile char secondBeat = false;      // used to seed rate array so we startup with reasonable BPM


//void ledFadeToBeat()

//{

//    fadeRate -= 15;                         //  set LED fade value

//    fadeRate = constrain(fadeRate,0,255);   //  keep LED fade value from going shorto negative numbers!

//    analogWrite(fadePin,fadeRate);          //  fade LED

//}

void timer_isr(void)

{

    //cli();                                      // disable shorterrupts while we do this

    

    Signal = pulsepin.read_u16()>>6;              // read the Pulse Sensor

    sampleCounter += 2;                         // keep track of the time in mS with this variable

    short N = sampleCounter - lastBeatTime;       // monitor the time since the last beat to avoid noise


    //  find the peak and trough of the pulse wave

    if(Signal < thresh && N > (IBI/5)*3) {      // avoid dichrotic noise by waiting 3/5 of last IBI

        if (Signal < T) {                       // T is the trough

            T = Signal;                         // keep track of lowest poshort in pulse wave

        }

    }


    if(Signal > thresh && Signal > P) {         // thresh condition helps avoid noise

        P = Signal;                             // P is the peak

    }                                        // keep track of highest poshort in pulse wave


    //  NOW IT'S TIME TO LOOK FOR THE HEART BEAT

    // signal surges up in value every time there is a pulse

    if (N > 250) {                                  // avoid high frequency noise

        if ( (Signal > thresh) && (Pulse == false) && (N > (IBI/5)*3) ) {

            Pulse = true;                               // set the Pulse flag when we think there is a pulse

            leds=1;                // turn on pin 13 LED

            IBI = sampleCounter - lastBeatTime;         // measure time between beats in mS

            lastBeatTime = sampleCounter;               // keep track of time for next pulse


            if(secondBeat) {                       // if this is the second beat, if secondBeat == TRUE

                secondBeat = false;                  // clear secondBeat flag

                for(short i=0; i<=9; i++) {            // seed the running total to get a realisitic BPM at startup

                    rate[i] = IBI;

                }

            }


            if(firstBeat) {                        // if it's the first time we found a beat, if firstBeat == TRUE

                firstBeat = false;                   // clear firstBeat flag

                secondBeat = true;                   // set the second beat flag

                //sei();                               // enable shorterrupts again

                return;                              // IBI value is unreliable so discard it

            }



            // keep a running total of the last 10 IBI values

            unsigned short runningTotal = 0;                  // clear the runningTotal variable


            for(short i=0; i<=8; i++) {               // shift data in the rate array

                rate[i] = rate[i+1];                  // and drop the oldest IBI value

                runningTotal += rate[i];              // add up the 9 oldest IBI values

            }


            rate[9] = IBI;                          // add the latest IBI to the rate array

            runningTotal += rate[9];                // add the latest IBI to runningTotal

            runningTotal /= 10;                     // average the last 10 IBI values

            BPM = 60000/runningTotal;               // how many beats can fit shorto a minute? that's BPM!

            QS = true;                              // set Quantified Self flag

            // QS FLAG IS NOT CLEARED INSIDE THIS ISR

        }

    }


    if (Signal < thresh && Pulse == true) {  // when the values are going down, the beat is over

        leds=0;            // turn off pin 13 LED

        Pulse = false;                         // reset the Pulse flag so we can do it again

        amp = P - T;                           // get amplitude of the pulse wave

        thresh = amp/2 + T;                    // set thresh at 50% of the amplitude

        P = thresh;                            // reset these for next time

        T = thresh;

    }


    if (N > 2500) {                          // if 2.5 seconds go by without a beat

        thresh = 512;                          // set thresh default

        P = 512;                               // set P default

        T = 512;                               // set T default

        lastBeatTime = sampleCounter;          // bring the lastBeatTime up to date

        firstBeat = true;                      // set these to avoid noise

        secondBeat = false;                    // when we get the heartbeat back

    }

    //sei();                                   // enable shorterrupts when youre done!

}


void sendDataToProcessing(char symbol, short data )

{

    pc.putc(symbol);                // symbol prefix tells Processing what type of data is coming

    pc.printf("%d\r\n", data);                // the data to send culminating in a carriage return

}

int main()

{

    pc.baud(115200);             // we agree to talk fast!

    tick.attach_us(&timer_isr,2000);                 // sets up to read Pulse Sensor signal every 2mS

    while(1) {

        led1 =1;

        sendDataToProcessing('S', Signal);     // send Processing the raw Pulse Sensor data

        if (QS == true) {                      // Quantified Self flag is true when arduino finds a heartbeat

            //fadeRate = 255;                  // Set 'fadeRate' Variable to 255 to fade LED with pulse

            sendDataToProcessing('B',BPM);   // send heart rate with a 'B' prefix

            sendDataToProcessing('Q',IBI);   // send time between beats with a 'Q' prefix

            QS = false;                      // reset the Quantified Self flag for next time

        }


        //ledFadeToBeat();

        wait(0.02);                             //  take a break

    }

}

image.png

点击编译,会弹出窗口,等编译完,会提示下载,直接选择板子内存,下载进去就行。

image.png

image.png

image.png

下栽进去后板子上的程序就会自动运行了。

对了,引脚接法是

pulse sensor:

VOUT       ->       PA0
VCC         <-      3.3V
GND        <-      GND

LED小灯:

VOUT       ->       PA5
VCC         <-      5V
GND        <-      GND

运行效果如下图,我的心在那跳动

我用找到的心率传感器上位机显示程序processing显示如下图。

换了一种方法,果然成功了。LED小灯闪烁频率和我的心跳一样,“跳动的心”终于跳动起来了,实现了功能。不容易啊,以前玩c51系列的,初碰stm32,还是挺有难度的,我发现,实际上,论坛上的资源还是挺多的,只是有些程序比较难读,不同型号的板子之间的联系和代码替换相关的帖子也比较少,在查找上还不是那么方便。至此,我的“跳动的心”就告一段落了,真心感谢论坛给我这次机会,也感谢在我遇到困难时对我给予帮助的小伙伴们!

PS:如果有哪位大神知道我用keil5编写的程序问题在哪,或者有对我的程序有兴趣的小伙伴,欢迎指教哦

我把PulseSensor的相关资料和显示程序链接附上,需要的自取吧。

链接:https://pan.baidu.com/s/1G-tCvMk8MdAT8EDx_KjUCQ 

提取码:gngs 






关键词: 跳动的心     pulse sensor     mbed    

管理员
2019-01-02 10:39:41    评分
2楼

谢谢楼主分享


助工
2019-01-02 11:46:19    评分
3楼

谢谢楼主分享


高工
2019-01-03 10:12:07    评分
4楼

不错哦,上位机软件很可爱


共4条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]