embarrassing IF question?

this is embarrassing, can i do the following:

const int inPin = 8;
int val =0;
int enc_counter =0;

val = digitalRead(inPin);
if (val == HIGH) //can i use HIGH or 0 ???
{
enc_counter +=1;
}

count every time a high is sent to PIN 8:

thank you

bassam

You can do that, just bear in mind that if this is inside loop() enc_counter will increment at a very rapid rate while the input is high, it won't just count the number of times it goes high.

Also, and a bit simpler

enc_counter += digitalRead(inPin);

will do the same thing because digitalRead() returns either 0 or 1.


Rob

thnx for replying, I guess I can use your line:

enc_counter += digitalRead(inPin);

to count the number of time my input goes to HIGH.

BUT, how can I Read (inPin) for say 5 seconds then execute the next line?
OR, how can I read for 5 seconds without delaying the program?

Graynomad:
You can do that, just bear in mind that if this is inside loop() enc_counter will increment at a very rapid rate while the input is high, it won't just count the number of times it goes high.

Also, and a bit simpler

enc_counter += digitalRead(inPin);

will do the same thing because digitalRead() returns either 0 or 1.


Rob

Hey! not to hijack his thread but I have a similar problem with my coding where it is supposed to calculate RPM but the value increments at a very rapid rate when the sensor is HIGH which i don't want.

could you help me?

KE7GKP:

thnx for replying, I guess I can use your line:

enc_counter += digitalRead(inPin);

to count the number of time my input goes to HIGH.

No. That code (and your original code) will count the number of times through the loop that it finds your pin high. That is not the same as what you are asking.

If you want to count the number of times the pin goes high, then you must also track when it goes low so that you will know that it is a new instance of "going high". Else you can't tell if it just went high, or it was already high.

okay and how would he do this? because I too have a similar problem :slight_smile:

Give this a spin...

const int inPin = 8;

int PreviousValue;

int enc_counter;

void setup( void )
{
  pinMode( inPin, INPUT );
  
  PreviousValue = digitalRead( inPin );
}

void loop( void )
{
  int CurrentValue;
  
  CurrentValue = digitalRead( inPin );
  
  enc_counter += (! PreviousValue) && (CurrentValue);
  
  PreviousValue = CurrentValue;
}

Or this...

const int inPin = 8;

int PreviousValue;

int enc_counter;

void setup( void )
{
  pinMode( inPin, INPUT );
  
  PreviousValue = digitalRead( inPin );
}

void loop( void )
{
  int CurrentValue;
  
  CurrentValue = digitalRead( inPin );

  if ( (PreviousValue == LOW) && (CurrentValue == HIGH ) )
  {
    ++enc_counter;
  }
  
  PreviousValue = CurrentValue;
}

KE7GKP:
Set up another boolean variable. Let's call it "armed".
Start by setting armed = TRUE.
Then as soon as you see the pin go high AND armed = TRUE, increment the counter, and set armed = FALSE
Then as soon as you see the pin go low AND armed = FALSE, set armed = TRUE

okay but this is what I have and I'm kinda not sure how to implement what you said into it,

Here's a snippett of that specific section :

if((lastReedSwitchState == LOW) && (reedSwitchState == HIGH)){  //if the reed switch is high and was previously low...
    DoTimeAndDistanceCalcs();
    lcd.clear();  //Clear the LCD to show the new results
   
    
    if(showRPM) lcd.print(RPM);  //show the RPM on the LCD
    else if(showSpeeds) lcd.print(speeds);  //show the speed on the LCD
    else if(showMaximumSpeeds) lcd.print(maximumSpeed);  //Show the maximum speed on the LCD
    else if(showDistanceTravelled) lcd.print(distanceTravelled);  //Show the distance travelled on the LCD
    else if(showAverageSpeed) lcd.print(averageSpeed);  //Show the average speed on the LCD

  }

KE7GKP:
@polishdude20, yes what you have there looks OK, but note that somewhere you must reset "lastReedSwitchState" or it will count to infinity (or overflow, whichever comes first) :slight_smile:

sorry to be a noob but how would I reset it?

KE7GKP:
@polishdude20, yes what you have there looks OK, but note that somewhere you must reset "lastReedSwitchState" or it will count to infinity (or overflow, whichever comes first) :slight_smile:

because for me when i touch the sensor to 5v which sets it high, the reading gets very unstable and does VERY high numbers.

For example if I were to touch the sensor to 5v ever second it should show me 60 RPM but it doesn't.
I think that right before the wire touches the 5v it counts MANY highs and lows because of debounce.
I need debounce in it ?

KE7GKP:
Set up another boolean variable. Let's call it "armed".
Start by setting armed = TRUE.
Then as soon as you see the pin go high AND armed = TRUE, increment the counter, and set armed = FALSE
Then as soon as you see the pin go low AND armed = FALSE, set armed = TRUE

this is my part of my code now:

val = digitalRead(inPin);
if (val == 1 && armed == true)
{
enc_counter +=1;
armed = false;
}

val = digitalRead(inPin);
if (val == 0 && armed == false)
{
armed = true;
}

assuming my code is correct, and I got the revolutions now.
how can I get the RPM or RPS (per second). in another word, how can digitalRead(inPin) within certain TIME, say 5 seconds?

Bassam:

KE7GKP:
Set up another boolean variable. Let's call it "armed".
Start by setting armed = TRUE.
Then as soon as you see the pin go high AND armed = TRUE, increment the counter, and set armed = FALSE
Then as soon as you see the pin go low AND armed = FALSE, set armed = TRUE

this is my part of my code now:

val = digitalRead(inPin);
if (val == 1 && armed == true)
{
enc_counter +=1;
armed = false;
}

val = digitalRead(inPin);
if (val == 0 && armed == false)
{
armed = true;
}

assuming my code is correct, and I got the revolutions now.
how can I get the RPM or RPS (per second). in another word, how can digitalRead(inPin) within certain TIME, say 5 seconds?

here's some code to help you out, this is from my program and it calculates RPM, speed, distance, max speed and average speed.

See how you can adapt your code to include mine

polishdude20:

Bassam:

KE7GKP:
Set up another boolean variable. Let's call it "armed".
Start by setting armed = TRUE.
Then as soon as you see the pin go high AND armed = TRUE, increment the counter, and set armed = FALSE
Then as soon as you see the pin go low AND armed = FALSE, set armed = TRUE

this is my part of my code now:

val = digitalRead(inPin);
if (val == 1 && armed == true)
{
enc_counter +=1;
armed = false;
}

val = digitalRead(inPin);
if (val == 0 && armed == false)
{
armed = true;
}

assuming my code is correct, and I got the revolutions now.
how can I get the RPM or RPS (per second). in another word, how can digitalRead(inPin) within certain TIME, say 5 seconds?

here's some code to help you out, this is from my program and it calculates RPM, speed, distance, max speed and average speed.

See how you can adapt your code to include mine

I can't see the code?

sry HERE's the code:

{
    revoloutions ++;  //add one to revoloutions - the wheel has turned round one more time
    endRotation = millis();  //keep track of the time that the rotation completed
    rotationTime = endRotation - startRotation;  //work out the time of the full rotation
    startRotation = endRotation;  //the next rotation starts when the previous one finished, so make them have both the same values
    RPM = (60000 / rotationTime);  //find out how many times you can get the rotation time inot one minute - hence working out the RPM
    distanceTravelled = revoloutions * wheelCircumference;  //the distance travelled will be the ammount of rotations * the distance travelled per rotation
    distanceTravelledPerSecond = RPM * wheelCircumference;  //speed = distance / time. The time for this is 1 second, the distance is worked out here
    distanceTravelledPerSecond = distanceTravelledPerSecond / 100;  //This gives the distance travelled per second in meters, not centimeters
    speeds = distanceTravelledPerSecond;  //The speed will be in m/s, and this is the ammount of meters travelled per second, or m/s, so it is the speed!
    if(speeds > maximumSpeed) 
      maximumSpeed = speeds;  //if the new speed is faster than the maximum speed, make the current speed the new maximum speed
    timeInSeconds = millis();  //This will give the ammount of milliseconds that the program has been running for
    timeInSeconds = timeInMilliseconds / 1000;  //This will turn the time in milliseconds into the time in seconds
    averageSpeed = (distanceTravelled / timeInSeconds);  //This will give the average speed
}

oh and I still need help on my problem if you guys can help :slight_smile:

KE7GKP:

I still need help on my problem if you guys can help

Bassam showed us the code in Reply #12. Did you not understand Bassam's code? Do you have a different question?

nono I understand the code perfectly and I have it implemented in my program but I have figured out that my problem all along was the debounce of my switch. Without debouncing the the reading goes from high to low a few times before it settles at high producing erratic results.

The help I need is in the debouncing through either software or hardware but I am stumped on how to debounce the input with MY program.

polishdude20:
sry HERE's the code:

{

revoloutions ++;  //add one to revoloutions - the wheel has turned round one more time
    endRotation = millis();  //keep track of the time that the rotation completed
    rotationTime = endRotation - startRotation;  //work out the time of the full rotation
    startRotation = endRotation;  //the next rotation starts when the previous one finished, so make them have both the same values
    RPM = (60000 / rotationTime);  //find out how many times you can get the rotation time inot one minute - hence working out the RPM
    distanceTravelled = revoloutions * wheelCircumference;  //the distance travelled will be the ammount of rotations * the distance travelled per rotation
    distanceTravelledPerSecond = RPM * wheelCircumference;  //speed = distance / time. The time for this is 1 second, the distance is worked out here
    distanceTravelledPerSecond = distanceTravelledPerSecond / 100;  //This gives the distance travelled per second in meters, not centimeters
    speeds = distanceTravelledPerSecond;  //The speed will be in m/s, and this is the ammount of meters travelled per second, or m/s, so it is the speed!
    if(speeds > maximumSpeed)
      maximumSpeed = speeds;  //if the new speed is faster than the maximum speed, make the current speed the new maximum speed
    timeInSeconds = millis();  //This will give the ammount of milliseconds that the program has been running for
    timeInSeconds = timeInMilliseconds / 1000;  //This will turn the time in milliseconds into the time in seconds
    averageSpeed = (distanceTravelled / timeInSeconds);  //This will give the average speed
}




oh and I still need help on my problem if you guys can help :)

sorry to bother you again but can I use unsigned long for all variables?

You realize that you lost decimals if you don't play with casting? I don't know if I use the right term here...

I think it would be a good think to use suitable variables, instead of long or unsigned long. Do you need negative values?

Cheers,
Kari

GaryP:
You realize that you lost decimals if you don't play with casting? I don't know if I use the right term here...

I think it would be a good think to use suitable variables, instead of long or unsigned long. Do you need negative values?

Cheers,
Kari

i don't need negative values. and i'd like to keep my decimals. what do you recommend ?
I want to use millis(); but in the example posted they 're using unsigned long.

example:

Thanks to polishdude's hijack, I've kind-of lost track of what it is you want to do - can you restate your problem?

To calculate RPM:

count the number of encoder pulses you get over some time interval (you used an example of 5 seconds).
Divide this number by the number of encoder pulses per revolution (this will be specific to your encoder).
This will give you revolutions per time interval (5 seconds).
Do the necessary math to convert this to revolutions per minute (for the 5 second interval, you have to multiple by 12 to get RPM)

jraskell:
To calculate RPM:

count the number of encoder pulses you get over some time interval (you used an example of 5 seconds).
Divide this number by the number of encoder pulses per revolution (this will be specific to your encoder).
This will give you revolutions per time interval (5 seconds).
Do the necessary math to convert this to revolutions per minute (for the 5 second interval, you have to multiple by 12 to get RPM)

yeah I showed him that in my code and showed how he can figure it out himself,

So technically I didn't take over the thread , I helped the original author whilst helping myself.