Can't help with flowcode but if the interrupt is running continuously then it is probably because you aren't clearing INTF in the interrupt.
Mike.
Try increasing a register every time Timer0 overflows, then when your RB0 pin goes high you can read the register count (to give you the last time between heart beats) and then reset the register to 0 in order to read the next time between beats.
Hi Gobbledok
Thanks for your reply
I am using Flowcode to write the program for the PIC16F84A. i set a push to make switch for RB0 which everytime i press it its like a possitive peak enters the RB0 input and when i release it goes back to zero. each time i press it the program is interrupted by RB0/INT (rising edge) where i set it to do (Peak=Peak+1). in the same interrupt (RB0/INT) i set another interrupt for RB0 timer overflow but i dont know how to use it and get the time between two heart pulses. do i need both interrupts (RB0/INT for rising edge and TMR0 overflow)? if you know how to use flowcode i can upload my code and tell me what i am doing wrong.
Thanks
Regards
kokos
Hi, no idea about flowcode sorry.
Yep you will need to use both interrupts. Whenever Timer 0 overflows you need to increase a register count. Then when the interrupt (heart beat) occurs on RB0, you have to read the value of the register which you increase with Timer 0.
For example, if the value of the register is 55 and your Timer 0 interrupt occurs every 10 milliseconds, then that means there was 550 milliseconds between the last beats.
The last thing you need to do with the RB0 interrupt is reset the count register back to 0 in order to count the next period.
So basically:
TMR0 Interrupt: Increase a counter (that's all it needs to do)
RB0 Interrupt: Read the counter, store the number for use in the main program, reset the counter.
You want to increase your count register by the timer, not by RB0 interrupt. As it is now, each register increases with RB0 and you are counting 5 pulses and then resetting the timer and count to 0. Nowhere there are you actually timing the length of time if takes for 5 interrupts on RB0.
Therefore every time you get 5 pulses, you are multiplying the number of pulses (always 5) by 12, which will always give you 60 BPM.
So you need to increase Count every time Timer 0 overflows. Increase Peak every time you detect a heart beat. Then when Count reaches 5 (or whatever), you need to look at the Peak register to see how many heart beats occured during that period.
You want to increase your count register by the timer, not by RB0 interrupt. As it is now, each register increases with RB0 and you are counting 5 pulses and then resetting the timer and count to 0. Nowhere there are you actually timing the length of time if takes for 5 interrupts on RB0.
Therefore every time you get 5 pulses, you are multiplying the number of pulses (always 5) by 12, which will always give you 60 BPM.
So you need to increase Count every time Timer 0 overflows. Increase Peak every time you detect a heart beat. Then when Count reaches 5 (or whatever), you need to look at the Peak register to see how many heart beats occured during that period.
You don't need to reset the Count register now in the Rising_edge macro. That was before when we were going to measure the period between heart beats. Now, because we are measuring the number of beats over a 10 second period, the Count register only gets reset when it reaches 150.
In the InputRB0 macro, where you call the Rising_Edge macro, replace it with [Heart_Beat = Heart_Beat + 1] and take [Heart_Beat = Heart_Beat + 1] out of the Rising_Edge macro.
Then, change the name of the Rising_Edge macro (to something like Timer_Done), and call it once your timer count reaches 150. Then you are working out the BPM after the counter has reached 150 (the only way to do it this way). The only problem with this (may not even be a problem) is that you will only get a reading every ten seconds and the initial reading will take ten seconds to show properly.
I imagine it will be pretty accurate, the only way to make it more accurate would be to increase the time over which you measure the BPM.
Looking at the code I have no idea why the heartbeat is updated each time RB0 goes high. As it is, it should only be updated every time the counter reaches 150 (if I'm reading it right).
I don't think it will change anything but I would also change the Timer macro to the picture below.
For the interrupt: Yep that's right. Because the interrupt occurs at 15.2588Hz, I would change your counter to 152 or 153 for more accuracy, though it won't make much difference.
The way you are counting heart beats is probably better and more accurate, however slower. If you can handle waiting 10 seconds for a reading I'd leave it as it is.
I've been meaning to have a play with flowcode for a while and so thought this would be a good time. I implemented your code without the LCD stuff but with a few changes. I've looked at the C code produced and it appears to be correct. The main change I made was to use a second variable (DoneCount) which the interrupt sets to count after 150 timer interrupts. This new variable (DoneCount) is then used in the main loop to update the display.
You can't really see from the diagram but when count=150 I do the following,
DoneCount=Heart_Beat
Heart_Beat=0
count=0
Edit, forgot to mention why I did it this way. It is because calling the display routines from the interrupt takes a long time and pulses could be missed during this time.
Mike.
It is because your main code is calling the two interrupt macros. If you remove these two calls I think it will work correctly.
Mike.
There is something strange going on with flowcode. I ran the code I implemented and set a breakpoint in the timer interrupt and it never triggered. The C code is correct but in the flowcode simulation it never executes the timer0 interrupt.
Mike.
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?