Hello, I'm counting state change with the program below that if sensor value reaches 800 it will blink on the pin 13 and count it as one. Is it possible with my sketch below to do it? i counted the times at 800 above however the counter shows more than that at almost 5 times.
First, could you please post your code in code tags? If you highlight your code, and click on the # icon above, it wil place the tags for you.
What is attached to your analog input pin?
How often do you expect it to go above 800?
Why are you limiting the program to counting excursions above 800 only in the first 15 seconds the program is running
Not necessarily. Saving the reading at the end of loop, and, on the next pass, comparing the current reading to the previous reading is a lot more obvious.
int currReading;
int prevReading;
int threashold = 800;
void loop()
{
currReading = analogRead(somePin);
if(currReading > threshold && prevReading < threshold)
{
counter++;
}
prevReading = currReading;
}
i'm programming arduino to count pulse in Analog input. My attached analog input is photodiode that reaches peak voltage value which relate to heart pulse. i want to count the peak value for only 15 seconds to shorten time since it could be multiply to 4 to complete 1 min. my project is pulse rate sensor using photodiode and led as attached components in arduino.
i appreciate using flag. it's my first time to use it. however i still have the problem. my project was to count total pulse rate(heartpulse) in 1 min utilizing photodiode and led as my attached components in arduino. i want to count the pulse when the analog input reaches peak which represents the pulse. however my sketch runs like this:
const int ledout = 13;
int sensorvalue1;
int counter;
int flag = 0;
void setup(){
Serial.begin(9600);
pinMode(ledout,OUTPUT);
}
void loop(){
if(millis()<15000){
int sensorvalue1 = analogRead(A0);
Serial.println(sensorvalue1);
if( sensorvalue1>1000 ){
if ( !flag ) {
digitalWrite(ledout,HIGH);
counter++;
flag = 1;
}
else {
digitalWrite(ledout,LOW);
flag = 0;
}
}
else{
Serial.println(counter);
delay(50);
}}
}
my serial output:
87
964
87 (counter)
1023 (peak serial value)
1023 (peak serial value)
1023 (peak serial value)
1023 (peak serial value)
1023 (peak serial value)
1023 (peak serial value)
655
90 (counter value)
173
90
0
90
0
90
0
90
it seems that program counter increments each loop time while serial value was at peak and not the way i want the counter to increment. from the serial output above, counter should be 88 after 87 because the peak values represents single pulse.
i am already confused with the void loop().
John_Ville6:
i'm programming arduino to count pulse in Analog input. My attached analog input is photodiode that reaches peak voltage value which relate to heart pulse. i want to count the peak value for only 15 seconds to shorten time since it could be multiply to 4 to complete 1 min. my project is pulse rate sensor using photodiode and led as attached components in arduino.
OK, just so you realize that the sketch will keep on taking readings, but will only act on them for 15 seconds, then will not act them at all until you reset it.
i also try to run the program that way but my output on the counter output was the same. the counter increments more than one value when analog input reaches its peak which value should be increment by one only.
just like this
87
964
87 (counter)
1023 (peak serial value)
1023 (peak serial value)
1023 (peak serial value)
1023 (peak serial value)
1023 (peak serial value)
1023 (peak serial value)
655
90 (counter value)
173
90
0
90
When you write your code in the IDE, use Tools->Auto Format to format your code. It helps to show you what is associated with what. In your code, you have a misplaced right-curly brace.
Try this one (untested)...
const int ledout = 13;
int sensorvalue1;
int counter;
int flag = 0;
void setup(){
Serial.begin(9600);
pinMode(ledout,OUTPUT);
}
void loop(){
if(millis()<15000){
int sensorvalue1 = analogRead(A0);
Serial.println(sensorvalue1);
if( sensorvalue1>1000 ){
if ( !flag ) {
digitalWrite(ledout,HIGH);
counter++;
flag = 1;
}
}
else {
digitalWrite(ledout,LOW);
flag = 0;
}
}
else{
Serial.println(counter);
delay(50);
}
}
i also try to run the program that way but my output on the counter output was the same. the counter increments more than one value when analog input reaches its peak which value should be increment by one only.
Please post your current code, as PaulS' code should be the correct(and easiest) way to do this.
thanks for your sketch examples. my analog state change counter is now working however the delay was approximately 50ms each loop because it will create too much error. the sketch was this:
int currReading;
int prevReading;
int threshold = 1022;
int counter;
int ledout = 13;
void setup(){
Serial.begin(9600);
pinMode(ledout,OUTPUT);
delay(1000);
}
void loop()
{ if(millis()<63143){
currReading = analogRead(A0);
Serial.println(currReading);
if(currReading > threshold && prevReading < threshold)
{
counter++;
digitalWrite(ledout,HIGH);
}
prevReading = currReading;
Serial.println(counter);
delay(49.1);}
else {
}
}
Your threshold and time are both way too high and I am guessing it's because you try and use them to fix what you don't understand. The code itself prints count with every loop inside the time window. You should expect repeats. The print should only be when time is up.
The delay which should only get an integer, not a float, is giving the board time to send the print message.
Try put the threshold back to 800 and time... you need work there to be able to take more than one reading without reset the board but do that later.
You can use delayMicroseconds() to get it finer but be aware the 'granularity' is 4 usecs, not 1.
Down the road in your learning you should learn to not use blocking code (delay) but have things trigger on time instead. Blocking code makes everything hold up for one thing, using non-blocking code allows many things to "happen at once".
Here's the best/clearest explanation I've seen and a sample superior to BlinkWithoutDelay:
John_Ville6:
thanks again. so i may use whole number only on delay values..
You don't need to use delay() in this code at all. If you have your threshhold set up properly, and if your photoresistor range for a pulse beat is right (rises to something less that 1023 in the analog pin read value), then you will only get one count per pulse. No need for delay(). I've made a few small changes in the latest code you posted (the one based on PaulS' code).
I've changed the millis() value to 10 seconds, so that you can get through testing faster. You can change this back later.
I removed all unnecessary delay() statements.
I changed the threshhold. If the counts are wrong, you probably need to adjust the threshhold up or down. Experiment if you don't have an oscilloscope.
Give this a try, then report back with results.
int currReading;
int prevReading;
int threshold = 600;
int counter;
int ledout = 13;
void setup(){
Serial.begin(9600);
pinMode(ledout,OUTPUT);
}
void loop()
{
if(millis() < 10000){
currReading = analogRead(A0);
Serial.println(currReading);
if(currReading > threshold && prevReading < threshold)
{
counter++;
digitalWrite(ledout,HIGH);
Serial.println(counter);
}
prevReading = currReading;
}
else {
Serial.print( "Number of beats is: ");
Serial.println(counter);
}
}
Saving the reading at the end of loop, and, on the next pass, comparing the current reading to the previous reading is a lot more obvious.
It's depends. For me saving logical results as a flag is preferable, as you don't have to do a comparison operation with threshold second times. In this particular case, both variable (ADC and threshold) int 16-bit, same time size of flag variable 8-bit. Difference in loading 4 registers instead of 1, which is may not be appropriate in time critical application.
Saving the reading at the end of loop, and, on the next pass, comparing the current reading to the previous reading is a lot more obvious.
It's depends. For me saving logical results as a flag is preferable, as you don't have to do a comparison operation with threshold second times. In this particular case, both variable (ADC and threshold) int 16-bit, same time size of flag variable 8-bit. Difference in loading 4 registers instead of 1, which is may not be appropriate in time critical application.
Unless the analog read might change between end of loop and next time read. It's hard to flag on future data.