5-way switch programming

Hey,

I recently bought a 128x128 screen and i am trying to develop a way to navigate it using a 5-way tactile switch from sparkfun, it consists of 1 switch for each direction (left, right, up, down and center) with a pull-up resistor on each. This is the code i'm using:

void trackball(int &x, int &y)
{
  while(digitalRead(rightpin) == LOW)
  {
    x++; //increases x to move right
    //if(x > uoled.x_res) x = uoled.x_res;  
  }
  while(digitalRead(leftpin) == LOW)
  {
    x--; //decrease x to move left
    if(x < 0) x = 0;      
  }
  while(digitalRead(uppin) == LOW)
  {
    y++; //increase y to move up
  }
  while(digitalRead(downpin) == LOW)
  {
    y--; //decrease y to move down
    if(y < 0) y = 0;
  }
   
   
}

Now when i try to move the "cursor", it jumps in about 20px increments over the screen. Anybody know what i did wrong?

The sketch polls the switches quickly. So, control, slow down, the switch sampling rate. If the switches are checked a lot in a given time there's more movement than there is if the switches are checked much less often over the same period.

You are using while(pin==LOW) count; which will count as quickly as it can for as long as the button is down.

Try changing 'while' to 'if' so it only count one per function call.

@johnwasser

Aha! Now i get it, will try the if loop.

Thank you so much John! You've solved my problem.

Now i have another difficulty:

My 'mode' button is hooked up to an interrupt with this code:

void click()
{
  mode++;
  if(mode > 4)
  {
    mode = 0;
  }
}

Now when i click on my mode button, it sometimes skips a mode, i think because the switch bounces. How do i effectively debounce in an interrupt?

add timeframe?

if ( (millis() - lastmillis) > 500 ) {mode++; lastmillis = millis();}

replace 500 for time delay in ms you want between recognizing pushes

One of many possible approaches

Dont forget: unsigned long lastmillis;

Thank you, it works.

buracek:
add timeframe?

if ( (lastmillis - millis() ) > 500 ) {mode++; lastmillis = millis();}

replace 500 for time delay you want between recognizing pushes

One of many possible approaches

Dont forget: unsigned long lastmillis;

You probably want (millis() - lastmillis) since the current time is likely to be greater than some previous time.

The 500 value might be overkill... It will prevent the button from activating more than every half second. 100 might be more reasonable, allowing 10 presses per second.

Thanks again John, really appreciate it.