Trying to use a rotation counter switch

I am making a vehicle and I am trying to stop it after a certain number of axle rotations, so I rigged up a rotation counter using a protrusion on the axle and a roller microswitch and I am trying to program it. As it stands, when the switch is open, no current flows to analog input 0, but when the protrusion comes around and hits the switch closed, current temporarily flows to input 0 and I add to the revolutions whenever the voltage is deemed high enough. I used an if statement to see if the previous voltage was also high and did not increment the revolutions if it did. I couldn’t figure out how to use the digital input so I used analog 0 and used this code to run the thing:

void setup(
{
  analog.setMode(MODE_8_BIT);
  
  motors.setSpeeds(-255,-255);
  
  analog.startConversion(0);
  
  unsigned int currentV = 0;
  unsigned int previousV = 0;
  
  // manual loop
  unsigned int revs = 0;
  unsigned int FINAL = 8; // numbers of revs
  while(revs < FINAL)
  {
    // if previous voltage > 50 out of 255, do NOT add to the count
     currentV = analog.readAverage(0,10); // read channel 0 for 10 values
     
     // aka add to the count ONLY IF 
     // prevVoltage < 50 AND current V > 100
     if(previousV < 160 && currentV > 180) 
     {
          revs++;
     }
     
     previousV = currentV;
  }
  
  motors.setSpeeds(0,0);
}

For a while (messing with the voltage settings, I think it was in the 150-180 range for both of the values I got it to be 90% consistent i.e. it stopped after 8 rotations 90% of the time, and after 9 rotations 10% of the time. However, I managed to get Arduino to crash and not only lost those numbers, but when I tested again, I couldn’t get it to be consistent again i.e. it went for 8 rotations maybe half the time, then 10, then 9, etc. I originally started with previousV < 50 && currentV > 150 and changed it from there. I also tried changing the number of samples from 10 to 25 and 50 but that seemed to make it worse.

I’m not sure how to best program a rotation counter like this, should I be using the analog input with a voltage tester like the above? The microswitch doesn’t close for very long. I think it depends a bit on alignment how long the switch is closed i.e. right now the axle protrusion seems to push the microswitch lever a bit, then momentarily close it, then open it again, etc. I’m not sure whether a longer or shorter ‘switch closed’ time is best, or if I should be using the other output of the microswitch (it is SPDT) and test when the voltage goes down (i.e. switch being trigged) and the voltage would be high when the switch is open? (I am worrying about double counting one rotation… which has happened and resulted in the vehicle stopping after 4 or 5 rotations instead of 8).

Hello,

Are you using an Orangutan? Which one?

Anyway, your problem mainly comes from treating the switch as an analog input, when it should be used digitally. There are plenty of examples on the web for how to use digital inputs with Arduino, for example this one:

itp.nyu.edu/physcomp/Labs/DigitalInOut#toc5

One thing in particular to watch out for is that you need to either have your own pull-down/pull-up resistor or use the built-in pull-ups of the AVR, or else your port will not have a predictable value when the swtich is open. If you are still confused about digital inputs after giving them another try, I suggest that you take a picture of your current setup, tell us exactly how everything is connected, and ask how to get it working digitally.

-Paul

Hi, I am using the LV-168. The thing is I want to increment a variable every time the switch closes. Assuming I use a digital input for the switch will this code work?

motors.setSpeeds(100,100);
unsigned int i = 0;
final unsigned int DIST = 10;

int switchState = 0;
int pSwitchState = 1;
while(i<10)
{
if(switchState == 1 && pSwitchState == 0)
    i++;
pSwitchState = switchState;

motors.setSpeeds(0,0);
}

What I wanted to avoid was a small bit of electrical noise blipping the switch off temporarily and thus causing the program to double-count one closing of the switch. I will try this tomorrow when I have more time. Also, is there a section in the LV-168 documentation about use of (the built-in) pull-up resistor? I was not able to find it. Thank you for your help.

That code doesn’t actually check any sensors. However, if you get switchState to be equal to 1 when the switch is closed, then something like that should work. The problem you are worried about avoiding is called “bouncing”, and you can avoid that with a timer. For example, ignore additional switch presses for the first 10 ms after the switch closes. You’ll also need to watch out for bouncing when the switch is opened!

By the way, your example code also sets the motor speed to zero inside of the loop, which doesn’t look right. You should probably move that to a position outside of the loop.

-Paul

Hello.

Please take a look at the AVR Studio demo project #1 for the Orangutan LV-168. This is located under the resources section of the Orangutan LV-168 product page. This example program gives a brief overview of digital I/O fundamentals on the ATmega168, including using internal pull-ups. The comments should make it clear what’s going on, but please ask if you don’t understand something.

You also might find the other demo projects helpful. For example, project #2 makes use of the Orangutan’s pushbuttons and shows one way to debounce them so that you can avoid registering a signal press as multiple presses. Please note that these demo projects were written before we released the Pololu AVR library, so they do not use the Pololu AVR library functions.

- Ben