Any advice on what coding to adjust. New to Arduino.

const int sensorPin = A0; 
float voltage=0.0;
int sensorVal=0; 
int heartbeats=9;
float BPM=0.0;
const int led1=2;
const int led2=3;
int starttime = 0;
boolean counted = false;

void setup() {
pinMode(sensorPin, INPUT);
pinMode(led1, OUTPUT);
pinMode(led2, OUTPUT);  
boolean counted = false;
void loop() {

starttime = millis();
while (millis()<starttime+10000)                          
  sensorVal = analogRead(sensorPin);
  if (sensorVal >550 && counted == false)         
    counted = true;  
  else if (sensorVal < 500)
    counted = false; 

    BPM = heartbeats*6;
 Serial.println("Your BPM is");
BPM =0;
heartbeats =0;

  • 1
    Where are you actually counting the BPM? Also, starttime is too small to store time. Also your method of calculating time is wrong, since it won't cope with millis rollover.
    – Majenko
    Nov 27, 2017 at 13:03
  • Minor issues in your code could be fixed, but actual beat per minute measurement is a complex processing algorithm far beyond the scope of this site - and not something anyone would want to run on an ATmega based Arduino. You'll have better luck picking a different project. Nov 27, 2017 at 14:19
  • I tested your code and it print the values anyway.
    – user31481
    Nov 27, 2017 at 15:04
  • Depend on the way you're doing this, but the process of detecting pulse is very simple, as detecting the level of gaz in blood (confusion is often made with Oxymeter which in fact measure "gaz" and not O2 and can be fooled by CO intoxication). In order to get an exact count, I suggest to use interrupt or, maybe have a look at code like those about water flow rate which you must read at a specific velocity, a bit like in your case. Have a lokk here: sparkfun.com/products/11574 In the document tab of this product, you'll find code.
    – Peter
    Nov 27, 2017 at 20:24

2 Answers 2


There's two basic methods of measuring a frequency, which is basically what you are trying to do.

There is Frequency Counting and Frequency Timing. The latter involves measuring the time between successive pulses and calculating the instantaneous frequency from that. Good for rapidly changing frequencies where you need to know the frequency right away.

Frequency counting is what you are attempting, and is basically counting the number of edges that occur within a certain timeframe.

However your method is slightly flawed: chiefly because you forgot to actually count the edges. You wrote some reasonable code for finding an edge, but failed to actually do anything with that edge.

Also your code is blocking for 10 seconds, which may be fine in this scenario, but is not a good habit to allow yourself to get into.

Instead you should consider something more like this:

void loop() {
    static int count = 0;
    static bool counted = false;
    static uint32_t ts = millis();

    int val = analogRead(sensorPin);

    if ((val > 550) && (counted == false)) {
        counted = true;
    } else if (val < 500) {
        counted = false;

    if (millis() - ts >= 10000) {
        ts += 10000; // You could assign ts the millis() value, but
                     // by adding 10 seconds it cancels any drift
                     // caused by other delays in your sketch.
        int BPM = count * 10;
        count = 0;
        Serial.print("BPM: ");

Assuming the input waveform is a low frequency square wave. Multiple ways to do it.

  1. Use the input to gate a counter on internal clock. It gives the most precise measurement, with a sub-us resolution.

  2. Use external or pcint interrupts to time the start and beginning of an edge.

  3. Wait in between edges.


Oversampling and algorithm will help smooth out the measurement.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.