Using a Navigation Switch (Digital Joystick)

A navigation switch has five internal pushbuttons on a stick. Moving the stick activates one or two of four direction pushbuttons (up,down,left,right). Forcing the stick into a diagonal corner can activate two direction switches at a time. Pressing down on the stick activates a center (or fire) pushbutton. It can be used as a joystick, but it has digital and not analog outputs. They are available as bare switches or on breakout boards. They may not need debouncing, if the application samples them and how long they are activated is all that matters. The Sparkfun breakout board has pullups on the switch, and the bare switch from Adafruit does not have pullups. The bare switch can be a bit iffy in a breadboard as the pins are not exactly .1inch spacing, but it will fit if a pin is skipped between one of the end pins. There are also a number of new lower-cost clones of the Sparkfun breakout board that should work the same - even the PCB looks the same (search for "5-way tactile breakout").

SN
Sparkfun's 5-way Tactile Navigation Switch Breakout board

AN
Through hole 5-way Tactile Navigation Switch from Adafruit

Hello World Example

The Navigation switch hello world examples set up a Nav_Switch class which can read all five switches or one at a time using names or indexing. It also turns on the internal pullups for the switches. The larger R value internal pullups will likely save some power and it saves a jumper wire. The main program reads in the direction switches and sends them to the four built-in LEDs on the mbed. If the fire (center) switch is pressed, all 4 LEDs turn on.

Wiring

mbed LPC1768Sparkfun Nav Switch Breakout
gnd-
p9U - up
p8C - center or fire
p7L - left
p6D - down
p5R - right
nc - using internal pullups+

Example Code

#include "mbed.h"

BusOut mbedleds(LED1,LED2,LED3,LED4);
//BusOut/In is faster than multiple DigitalOut/Ins

class Nav_Switch
{
public:
    Nav_Switch(PinName up,PinName down,PinName left,PinName right,PinName fire);
    int read();
//boolean functions to test each switch
    bool up();
    bool down();
    bool left();
    bool right();
    bool fire();
//automatic read on RHS
    operator int ();
//index to any switch array style
    bool operator[](int index) {
        return _pins[index];
    };
private:
    BusIn _pins;

};
Nav_Switch::Nav_Switch (PinName up,PinName down,PinName left,PinName right,PinName fire):
    _pins(up, down, left, right, fire)
{
    _pins.mode(PullUp); //needed if pullups not on board or a bare nav switch is used - delete otherwise
    wait(0.001); //delays just a bit for pullups to pull inputs high
}
inline bool Nav_Switch::up()
{
    return !(_pins[0]);
}
inline bool Nav_Switch::down()
{
    return !(_pins[1]);
}
inline bool Nav_Switch::left()
{
    return !(_pins[2]);
}
inline bool Nav_Switch::right()
{
    return !(_pins[3]);
}
inline bool Nav_Switch::fire()
{
    return !(_pins[4]);
}
inline int Nav_Switch::read()
{
    return _pins.read();
}
inline Nav_Switch::operator int ()
{
    return _pins.read();
}

Nav_Switch myNav( p9, p6, p7, p5, p8); //pin order on Sparkfun breakout

int main()
{
    while(1) {
        //with pullups a button hit is a "0" - "~" inverts data to leds
        mbedleds = ~(myNav & 0x0F); //update leds with nav switch direction inputs
        if(myNav.fire()) mbedleds = 0x0F; //special all leds on case for fire (center button)
        //or use - if(myNav[4]==0) mbedleds = 0x0F; //can index a switch bit like this
        wait(0.02);
    }
}


Import programNav_Switch_Hello_World

ver 1.0


On the Sparkfun breakout board, a small vinyl stick on foot or bumper about the same thickness as the plastic part of the header pin can help stabilize the board on a breadboard. A small stick-on mini vibration motor could be used instead and it would also add the option of haptic feedback to the user. These are also available at Sparkfun or Adafruit. A driver circuit will also be needed for the vibration motor.

The BusIn mbed API was used in the code example since it is faster than several DigitalIns. The new PortIn would work faster than BusIn, but the pins used would need to be on the same GPIO port. This would require checking the schematic or additional pin use information for each mbed platform.


Please log in to post comments.