I'm looking to use a PulseSensor as a countdown clock. Everytime your heartbeats the numbers go down. I've not got the sensor yet but i've hit a little roadblock when i start to think about the code. So the PulseSensor on the example sketch library needs to be plugged into the analog pins. Would it work the same if i was to plug it into the digital pins and use the stock StateChangeDetection example?
Here's what i have so far. It's just been modified from the original
const int buttonPin = 2; // Push Button Pin
// Variables will change:
int buttonPushCounter = 5001; // Start number of count
int buttonState = 0; // current state of the button - 0 No Push
int lastButtonState = 0; // previous state of the button - 0 No Push
void setup() {
pinMode(buttonPin, INPUT);
Serial.begin(9600);
}
void loop() {
// read the pushbutton input pin:
buttonState = digitalRead(buttonPin);
// compare the buttonState to its previous state
if (buttonState != lastButtonState) {
// if the state has changed, increment the counter
if (buttonState == HIGH) {
buttonPushCounter--; //-- denotes countdown not up
Serial.print("number of button pushes: ");
Serial.println(buttonPushCounter);
}
delay(50);
}
// save the current state as the last state, for next time through the loop
lastButtonState = buttonState;
}
You have the pulse sensor, you have the code, you have a pulse, I assume, so why not test it instead of asking us?
I suspect it will not work because the output of the sensor will not be a large enough range of values to register as HIGH and LOW. But I could be wrong.
But the State Change example can be easily adapted to use an analog input, it is meant to illustrate a principle which can be applied in many situations, not just reading digital inputs.
All you need to adapt the State Change example to work with your pulse sensor is a threshold value to compare with the reading from the analog pin. I suspect that calculating that threshold is the tricky part. The demo sketch for the pulse sensor should show you how that is done. Can you post that sketch also?
By the way, thank you and well done for using code tags. Some links to the pulse sensor should be useful. The forum sticky post will tell you how to post links.
I couldn't find a data sheet but here's a schematic (hope that helps) Schematic
Here's an example sketch from the PulseSensor Library. It does mention the Threshold as you mentioned.
int PulseSensorPurplePin = 0; // Pulse Sensor PURPLE WIRE connected to ANALOG PIN 0
int LED13 = 13; // The on-board Arduion LED
int Signal; // holds the incoming raw data. Signal value can range from 0-1024
int Threshold = 550; // Determine which Signal to "count as a beat", and which to ingore.
// The SetUp Function:
void setup() {
pinMode(LED13,OUTPUT); // pin that will blink to your heartbeat!
Serial.begin(9600); // Set's up Serial Communication at certain speed.
}
// The Main Loop Function
void loop() {
Signal = analogRead(PulseSensorPurplePin); // Read the PulseSensor's value.
// Assign this value to the "Signal" variable.
Serial.println(Signal); // Send the Signal value to Serial Plotter.
if(Signal > Threshold){ // If the signal is above "550", then "turn-on" Arduino's on-Board LED.
digitalWrite(LED13,HIGH);
} else {
digitalWrite(LED13,LOW); // Else, the sigal must be below "550", so "turn-off" this LED.
}
delay(10);
}
The example uses an adjustable "threshold" to set the sensitivity of the sensor. In the example the threshold is set to 550 which is approximately Vcc * 0.5.
Using a digital input means that there are two thresholds (Google "hysteresis") and they are fixed. Any voltage below Vcc * 0.3 is LOW, any voltage above Vcc * 0.6 is HIGH. What the input reads in between 0.3Vcc and 0.6Vcc depends on the last state. For example if the input was LOW and rose to 0.45Vcc it will remain LOW.
So like PaulRB said, it depends on if the sensor output will be high enough to register a HIGH and low enough to register a LOW.
Data sheet says output can vary between 0.3V and Vcc, but no info on whether it's a digital or analog signal. I suspect it's the last, making digital input unreliable.
So like PaulRB said, it depends on if the sensor output will be high enough to register a HIGH and low enough to register a LOW.
I think i already know the answer but i guess in the case that the jump between voltages isn't big enough i'd have to write some new script? Or could i use an analog to digital converter?
You need some level of hysteresis, just switching at 550 (or any one value) has the risk of false signals if the output hovers around that value.
Instead of checking HIGH or LOW on a digitalRead, do an analogRead() and state checking.
bool lastState = LOW;
void loop() {
bool sensorState;
int result = analogRead(sensorPin);
if (result > 600) sensorState = HIGH; // HIGH signal if >600.
else if (result < 500) sensorState = LOW; // LOW signal if <500
else sensorState = lastState; // Between these values: whatever the previous signal state was.
if (sensorState == HIGH && lastState == LOW) {
// Beat detected!
beatCounter++;
}
lastState = sensorState;
}
Amend the 500 and 600 values to suit your sensor's output, and desired amount of hysteresis (larger hysteresis = greater stability; lower hysteresis = greater sensitivity).
Thats great thank you so much. I guess the loop you've written just replaces the one i already had but i just need to suit it to the sensor using the hysteresis values?
Pretty much. The beatCounter++ line you replace with whatever you want to do with the beats, such as decreasing the counter, and at the end you can add other functionality.
And result should be an int - declared right there. Forgot that one (fixed now).