Esy pulse sensor Coding for BPM - Page 1
Forum section: electronics / general

author: KJ
author_rank: Newbie
timestamp: April 14, 2016, 05:25:04 pm
content: Hey guys , i have build a easy pulse sensor and i need to deal with it using arduinoi have develop some code for the BPMTell me what ya guy things/*AnalogReadSerialReads an analog input on pin 0, prints the result to the serial monitorThis example code is in the public domain.*/int counter=0;double lowEdge=0;double highEdge=0;void setup() {Serial.begin(115200);}void loop() {int sensorValue = analogRead(A0);Serial.println(sensorValue);counter++;delay_x(5);while(sensorValue=0){lowEdge=counter;}do{highEdge=counter;}while(sensorValue>0);double bpm=60/(highEdge-lowEdge)*5*pow(10,-3);}void delay_x(uint32_t millis_delay){uint16_t micros_now = (uint16_t)micros();while (millis_delay > 0) {if (((uint16_t)micros() - micros_now) >= 1000) {millis_delay--;micros_now += 1000;}}}

author: rstofer
author_rank: Super Contributor
timestamp: April 14, 2016, 06:17:48 pm
content: Does it work? It seem to me that there are a couple of issues but if it works that's all that matters.

author: KJ
author_rank: Newbie
timestamp: April 14, 2016, 06:22:20 pm
content: my sensor is otw~what is your opinion or suggestion?

author: rstofer
author_rank: Super Contributor
timestamp: April 14, 2016, 07:12:18 pm
content: I really hate to give an opinion unless I have tried the code and I'm not in a position to do that at the moment.However, I'll stick my neck out and do it anyway.In my view, the code doesn't work. Here's why:void loop() {int sensorValue = analogRead(A0);Serial.println(sensorValue);counter++; ==== counter gets updated by one every time through loop(), okdelay_x(5); ==== we wait 5 units of time each time through the loopwhile(sensorValue=0) ==== did you mean (sensorValue == 0) Otherwise, you just set the value of sensorValue to 0{ ==== further, if you did set the value to 0 then the loop would never be executedlowEdge=counter; ==== counter is never updated because we are hung up in the while loop} ==== and we're hung up in the loop because sensorValue never changes while we are hung in the while loopdo{highEdge=counter;}while(sensorValue>0); ==== again, we are hung up in the do loop waiting on sensorValue to change and it never will because we are hung in the loopdouble bpm=60/(highEdge-lowEdge)*5*pow(10,-3);}I know you are trying to make a superloop out of the code and that's fine. But you can't get hung up in loops and avoid reading the sensor.I would probably make a state machine using a SWITCH statement that let me test for changes in sensorValue and process counter readings without getting stuck in a loop.Next, I would probably use a hardware timer so I didn't have to rely on the delay function. I could just read the timer whenever the sensor changed values.I'm not sure you can count on only a single digit change in the A/D converter. Testing for 0 or >0 would seem to me to be a problem. I would want to spread out the values like < 5 and > 10 so I had a little hysteresis.enum states {IDLE, FOUND_LEADING_EDGE} state;state = IDLE;value = 0;while (1) {// big loop starts here// read sensor and update counter// code omitted// now process the sensorValueif (sensorValue > 10) // pick your own values for high and lowvalue = 1;elseif (sensorValue < 5)value = 0;switch state {case IDLE : if (value == 1) {counter = 0;state = FOUND_LEADING_EDGE;}break;case FOUND_LEADING_EDGEif (value == 0) {print counter;state = IDLE;}break;}} // end of while(1)I'm not guaranteeing the syntax but the idea is that the state machine approach allows you to run through the loop, reading the sensor, updating counter and all that stuff without getting hung up in loops.There's a reason I don't reply to this stuff without my handy dandy breadboard so, here it comes!

author: KJ
author_rank: Newbie
timestamp: April 15, 2016, 02:14:48 am
content: Thanks man~ i still waiting my sensor to arrive. Third world problem.I let you know whether my code work or not.I post it because i just realize no one doing bpm coding using ADCSo i was thinking why dun give a shot . I appreciate your suggestion.

author: rstofer
author_rank: Super Contributor
timestamp: April 15, 2016, 02:24:42 am
content: Quote from: KJ on April 15, 2016, 02:14:48 amYou can use a potentiometer or even a resistor and a switch for the A/D input. You are only looking for highs and lows. Set up the A/D converter, add a 10k resistor from the pin to Vcc and a switch from the pin to ground. Now you can sample your code without waiting for your sensor. You should read a really big value with the switch open and a very small value with the switch closed. In a perfect world the values will be 0 and 1023 (for a 10 bit A/D).With this range, you can do the tests like this:if (reading < 256)value = 0;elseif (reading > 768)value = 1;

author: KJ
author_rank: Newbie
timestamp: April 18, 2016, 01:10:32 pm
content: hey buddy, i have a solution//unsigned long data type: only computer data type that capable to store 32 bit of positive only integer.Min number is 0,max number of this variable is equal 2 power of 32unsigned long startmillis=0; // declare startmillis in unsigned long data type, initial at zerounsigned long lastmillis=0; // declare lastmililis in unsigned long data type, initial at zerounsigned long calmillis=0; // declare calmillis in unsigned long data type, initial at zerofloat BPM=0; // delcare BPM in float data type , intial at 0const int pin =2;int state=0;void setup() {Serial.begin(115200); // initial serial monitor at baud rate of 115200.For effectiveserial communication}void loop() {// the easy pulse sensor output connect to digital pin to display digital output/* As sensor output >> particular threshold let say 512, the digital pin will count as 1else will count as 0 *//*millis() library function--> a counter that count how many milisecond has passed once serial monitor start */while(digitalRead(2)==1) //as output equal to 1, last millis = startmillis. at intial =0. If dtect another logic high lastmililis wil store previous logic low millis() value{ state=1;lastmillis=startmillis;}while(digitalRead(2)==0) // startmilis() store value of millis() once it detect logic low(heart beat){ state=0;startmillis=millis();}calmillis=startmillis-lastmillis; // different of these 2 variable correpond to heartbeat intervalBPM=60000/calmillis; // relation between BPM and heartbeat interval/*This serial arrangemnet is outputing variable in one dimension data type*/Serial.print(state);Serial.print(",");Serial.print(startmillis);Serial.print(",");Serial.print(lastmillis);Serial.print(",");Serial.print(calmillis);Serial.print(",");Serial.println(BPM);delay_x(5); // delay 5 milisecond}void delay_x(uint32_t millis_delay){uint16_t micros_now = (uint16_t)micros();while (millis_delay > 0) {if (((uint16_t)micros() - micros_now) >= 1000) {millis_delay--;micros_now += 1000;}}}