Go Down

Topic: project help (Read 625 times) previous topic - next topic

cadi2002

Hello I am new to Arduino but not new to electronics I have over 30 years electronics engineering experience. This is the 2nd controller I have purchased the first was a basic stamp and I hated it. With my Arduino I have figured out more in 5 days than I have with my stamp in a year. My issue is i did a setup that each time a switch or reed is closed it increments a counter by one. The reed is on a 22" wheel for my wheelchair I am trying to calculate distance i wheel when i go out to exercise. It all works great does the math and on my LCD 16x2 display it shows feet traveled and miles. Issue I have is I cant figure out how to get it to count once then wait for the switch to change states. the micro is faster than the switch so some times I get multiple counts. I put in a delay of a few milliseconds that fixed the multiple counts but now it some times misses counts. I did a setup using a cap and 2 resistors and a diode to give about a 2 millisecond pulse low. I looked at the low pulse on my DSO scope and am not seeing a bounce. I need a way to execute the program one time once the switch goes low then wait till it sees the switch go high again before it can do it all over again. Currently if i just put a switch in with out the cap, resistor and diode and press it the counter will count until i let the switch go. Any help would be greatly appreciated.

HazardsMind

Look at the button state change example.
My GitHub:
https://github.com/AndrewMascolo?tab=repositories

Nick Gammon

Quote

Issue I have is I cant figure out how to get it to count once then wait for the switch to change states.


Find the state. Has it changed from the old state? If so, count, and remember this as the old state.
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

afremont

If you eliminated the noise from your trigger pulse, then you can simply "watch" the pin by doing digitalRead() inside an empty while loop.  Once you see the pin go low, you just sit on it with something like:

looper:
    while(digitalRead(PIN) == HIGH);  // wait for pulse
    while(digitalRead(PIN) == LOW);   // wait for end
    revcounter++;        // one more revolution occurred
    any other code you want to do;
    goto looper;         // wait for the next one

I like to use interrupts for this kind of thing.

Experience, it's what you get when you were expecting something else.

Nick Gammon

Don't use goto.

Why use 2 x while and then throw in a goto?
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

afremont


Don't use goto.

Why use 2 x while and then throw in a goto?


It was just an example.  I thought it would be more clear to the OP to show it that way.
Experience, it's what you get when you were expecting something else.

cadi2002

OK I tried various versions of what you suggested and came up with one that works only problem is i have no idea why it works can you take a look at the following and tell me why this works, but it works perfect?
/* 1st attempt to make a distance counter for a wheelchair.
   Switch is a momentary switch on right wheel that is 22" diamater.
   Axel has a cam that pushes switch each single rotation. */
#include <LiquidCrystal.h>

/*
LCD Connections:
rs (LCD pin 4) to Arduino pin 12
rw (LCD pin 5) to Arduino pin 11
enable (LCD pin 6) to Arduino pin 10
LCD pin 15 to Arduino pin 13
LCD pins d4, d5, d6, d7 to Arduino pins 5, 4, 3, 2
*/

LiquidCrystal lcd(12, 11, 10, 5, 4, 3, 2);
int led = 13;    // pin 13 shows button activity
int x;
float y;
float z;
int d;
long m;
const int Button1 =7 ; // assigns input 7

void setup() {
  pinMode(led, OUTPUT);
  digitalWrite(Button1, HIGH); //turn on internal pull up
  x=0;                         //rotation button
  y=5.759;                     //circumfrence of wheel in feet
  z=0;                         //feet traveled so far
  m=5280;                      // feet per mile
  lcd.begin(16, 2);            // rows, columns.  use 16,2 for a 16x2 LCD, etc.
  lcd.clear();                 // start with a blank screen
  lcd.setCursor(0,0);          // set cursor to column 0 row 0
 
}

void loop(){
   
   if(digitalRead(Button1) == LOW)
   {
   while(digitalRead(Button1)== LOW);
   
   x++;}                       //Increments x by one if Button 1 is Low

 
digitalWrite(led, LOW); //Sets Pin 13 low Led is off.

{

digitalWrite(led, HIGH);} //Sets Pin 13 high if button is not pushed
z=x*y;                    //Rotations times distance per rotation= feet traveled
d=z/m;                    //Feet traveled / 5280(feet per mile)
lcd.print("Feet: ");
lcd.print(z);             //Prints numeric amount of feet
lcd.setCursor(0,1);
lcd.print("Miles:");
lcd.print(d);             //Prints numeric amount of feet
lcd.setCursor(0,0);       //Resets dispay.

}

AWOL

#7
Feb 25, 2013, 09:27 am Last Edit: Feb 25, 2013, 09:28 am by AWOL Reason: 1
Code: [Select]
  //Increments x by one if Button 1 is Low
The comment is incorrect; x is incremented when the pin transitions from LOW to HIGH because of the while loop.

Please use code tags when posting code.

Code: [Select]
  y=5.759;                     //circumfrence of wheel in feet
  z=0;                         //feet traveled so far
  m=5280;                      // feet per mile

Unless you're planning on changing these values, 
Code: [Select]
const float  y=5.759;                 //circumfrence of wheel in feet
const float  m=5280;                      // feet per mile
when they're declared would be clearer.
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Go Up