This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Compiler/MSP430G2553: Heart Beat Counter using Analog Sensor: Cannot read values.

Part Number: MSP430G2553

Tool/software: TI C/C++ Compiler

Greetings! I'm working on a project about calculating beats per minute with MSP430G2553 using a pulse sensor. I've searched and found some resorces and firstly I'm trying to apply them. Later, I will improve my project. I am quite new on these microprocessors, so I'm waiting for your kind help.

(I don't know if can share a link but if I cannot, please edit my post.)

Related link for the project: www.instructables.com/.../

Pulse sensor: http://www.instructables.com/id/Heart-Beat-Counter-using-MSP430/

LCD Library: http://www.ece.utep.edu/courses/web3376/Lab_5_-_LCD_files/lcdLib.h

LCD C file: www.ece.utep.edu/.../lcdLib.c

At first, I've just tried to perform the project in this schematic with a pulse sensor. I just plugged my sensor's +VCC pin to a +5V source and GND pin to the ground then the OUTPUT pin to ninth pin of MSP430G2553. (P2.1)

Everything was OK but there should have been some problems about wiring LCD; I couldn't operate the LCD. So, I've decided to try another library for LCD. With this new library, my LCD just works fine. But there's another problem now. I cannot read any -true- values! (The value is always 8 or 12.)

Later, I've detected the problem here: LCD uses P2.1 for writing the DATA from pulse sensor. And pulse sensor is sending it's pulses to P2.1. I've decided to move my input pin from P2.1 to P2.6 but it just didn't work.

There's some issue but I cannot figure it out. Can you please help me? 

My code is below:

=========

main.c

#include <msp430.h>
#include "lcdLib.h"
void delay(int);
void configWDT();
void configIO();
void configIR();
void configT();
void disableT();
void int_char();

int i=0;
int j=0;
char lcdstr[4];

int main(void)
{

configWDT();

configIO();

configIR();

lcdInit();

lcdClear();

lcdSetText("Put your Finger", 0, 0);
lcdSetText("on the sensor :", 0, 1);

while(1)
{

}

}

void configWDT()
{
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
/*DCOCTL = 0;
DCOCTL = CALDCO_1MHZ;
BCSCTL1 = CALBC1_1MHZ;
*/}

void configIO()
{
P1OUT=0x00;

P1DIR |= (BIT0 + BIT6); // P1.0 output
}

void configIR()
{
P1REN |= BIT3; // P2 Enable Pullup/Pulldown
P1OUT |= BIT3; // P2 pullup
P1IE |= BIT3; // P2 interrupt enabled
P1IES |= BIT3; // P2 Hi/lo falling edge
P1IFG &= ~(BIT3); // P2 IFG cleared just in case
_EINT();
}

void enablePulseIR()
{
P2REN |= BIT6; // P2 Enable Pullup/Pulldown
P2OUT |= BIT6; // P2 pullup
P2IE |= BIT6; // P2 interrupt enabled
P2IES |= BIT6; // P2 Hi/lo falling edge
P2IFG &= ~(BIT6); // P2 IFG cleared just in case

}

void disablePulseIR()
{
P2REN &= ~BIT6; // P2 Enable Pullup/Pulldown
P2OUT &= ~BIT6; // P2 pullup
P2IE &= ~BIT6; // P2 interrupt enabled
P2IES &= ~BIT6; // P2 Hi/lo falling edge
P2IFG |= (BIT6); // P2 IFG cleared just in case

}

void configT()
{
CCTL0 = CCIE; // CCR0 interrupt enabled
CCR0 = 50000;
TACTL = TASSEL_2 + MC_1; // SMCLK, upmode
}

void disableT()
{
TACTL = 0x00;
}

void printResult()
{
int_char();
lcdClear();
lcdSetText("HeartBeat/min :",0,0);
lcdSetText(lcdstr,0,1);
}

#pragma vector=TIMER0_A0_VECTOR
__interrupt void Timer_A (void)
{
if(i<350) i++;
else
{
P1OUT &= (~BIT0); // Toggle P1.0
disableT();
configIR();
disablePulseIR();
j=j*4;
printResult();
i=0;
j=0;
}
}

#pragma vector=PORT1_VECTOR
__interrupt void Port_1(void)
{
if((P1IFG & 0x08) == 0x08)
{
P1OUT |= BIT0;
configT();
enablePulseIR();
P1IFG &= ~BIT3;
lcdClear();
lcdSetText("Please wait ...",0,0);
}
}
#pragma vector=PORT2_VECTOR
__interrupt void Port_2(void)
{
P2IE &= ~BIT6;
j++;
P2IE |= BIT6;
P2IFG &= ~BIT6;
}

void int_char()
{
int s;
s=j%10;
lcdstr[2]=(char)(s+48);
j=j/10;
s=j%10;
lcdstr[1]=(char)(s+48);
j=j/10;
s=j%10;
lcdstr[0]=(char)(s+48);
lcdstr[3]='\0';
}

========

Thanks in advance! I'm looking forward for a solution!

  • Hi,

    Could you please clarify what is not working when you changed the pin for the pulse sensor? Are you correctly configuring it as a GPIO? And does the LCD still work after you made this change?

    Regards,
    Nathan
  • Hi Nathan, thanks for the answer.

    If I set P2.1 as pulse input, LCD works a bit buggy and some texts are missing.

    If I set P2.6 as GPIO and pulse input, LCD works completely fine but I cannot read any values from that pin.

    Can you please check my code? I assume I correctly configure it as GPIO.
  • Pins usually start out as GPIOs, but P2.6 (and P2.7) don't on the G2 series. Rather they are connected to the clock system (XIN/XOUT) via P2SEL.6/7. [Ref SLAU144J Table 8-2 and SLAS735J Table 21].

    You need to clear the P2SEL bits to disconnect them from XIN/XOUT, presumably in configIO(), something like:

    P2SEL &= ~(BIT6|BIT7);
  • Oh, thank you sir! It worked!  

    Now I have some timing issue with my project. I cannot calculate pulses correctly. On Arduino, I get 65-70 BPM but on MSP, I get 8-10 BPM. 

    Sensor works fine, could be the problem about baud rate? My code counts pulse number in 15 secs, then the number is multiplied by 4. But it doesn't work. I always get smaller or much smaller BPM.

    By the way, the code is mainly OK, right? I can perform my project with this code? Or should I use ADC?

  • Hi,

    Do you have an oscilloscope or logic analyzer that you can use to see if the pulse train that is being generated by the sensor is correct?

    Regards,
    Nathan
  • Hi, thanks for the suggestions.

    I've checked if the pulses are correctly with Arduino Processing. Attached a screenshot about pulses.

    If the codes are correct, there might be some position problems between my finger and the sensor :) Sometimes I read really close values to the actual values with Processing app. But it's not stable. Sometimes I get "0" pulses.

  • I'm not sure I understand well what the analog section is doing, and that instructables page doesn't explain much. Your scope trace doesn't look very "digital", so those low-amplitude pulses might not be bit enough to trigger the pin logic.

    That said: lcdInit() is changing pins that it doesn't really "own", including P2.6. Specifically, it is turning P2.6 from a pullup to a pulldown, which may break some requirement of the circuit.

    This should probably be fixed, but a simple workaround would be to move your lcdInit call to precede the configIO() call, so the subsequent calls can fix what lcdInit broke. This may or may not fix your symptom, but is a good idea I think.
  • Thanks for the info. I can use an amplifier I think. Though I get true values now. It was about the position of sensor on my finger.

    --

    Now I removed LCD part from my project and I'm planning to write the BPM value to a SD card.
    I'll use pff.h and spi.h libraries to do this.

    I wrote a code but I get an error like below:

    Error[e24]: Segment DATA16_AN (seg part no 3, symbol "P1OUT" in module "main", address [21-21]) overlaps segment DATA16_AN (seg part no 1, symbol "_A_P1OUT" in module "mmc", address [21-21])



    I checked Google for this error but all I could find was a Serbian website. So, any help would be appreciated. Regards...

  • My first guess is that you don't have enough memory (RAM), and it's trying to allocate space over the MCU registers below it.

    It's fairly routine for SD/mmc applications to use a 512-byte buffer for blocks on the SD card, but the G2553 has only 512 bytes of RAM total [SLAS735J Table 1]. You may find this application difficult or even infeasible.
  • Hi!

    Thank you all guys for your kind support. I've justed finished my project. I used a G2452 and it gave better results. I could successfully write BPM value to a SD card.

    Regards!

**Attention** This is a public forum