chebe: (AsciiC)
[personal profile] chebe
I admit I can be a bit of a sucker when it comes to electro-textile stuff. I see the word 'wearable' in front of any traditional electronic component and I have to investigate. Which is how I came to possess the Wearable Keypad from SparkFun. I finally got around to using it recently, so here's the low-down.

It's a thick piece of rubber, glued together and sealed with silicon gel type stuff. It has six wires (about a metre long) coming from it. One wire is not connected (NC), one is ground (GND), one is for setting the brightness of the red LEDs behind the keypad (LEDR), and the other three (p5.1, p5.2, p5.3) are for the button presses. And as mentioned in the comments (of the product page) the order of the wires is backwards to that as shown in the datasheet.

Wait, you say, three wires for five buttons? What's going on? Seems to be a bit of fancy multiplexing, although the details are beyond me. I have however, managed to get it all to work for me, and have edited the Example Code provided by SparkFun to, shall we say, neaten up things a bit? Basically, I found that in the provided code I was getting spurious results; when I'd press 'down' I'd often get a 'left' or 'right' for no apparent reason. So I've added a few extra checks, that while they may slow the code down a bit, ensure clean detection of button presses. All the extra stuff to do with the LEDs I've stripped out. You may not need it, but here it is in case you do. (Also, your millage may vary, and as such you may need to edit this code to work just right for you.)

But give the SparkFun example code a go too. It's oddly satisfying to play with the LEDs.

Physical set-up of this experiment;
Arduino (Uno in my case), plugged into the USB of a laptop.
Some jump wires as needed
LEDR wire, going to digital pin 3 on Arduino.
GND wire, going to GND on Arduino.
P5.1 to digital pin 5.
P5.2 to digital pin 6.
P5.3 to digital pin 7.

/* SparkFun Keypad Example Code
  by: Jim Lindblom
  SparkFun Electronics
  date: 4/26/11
  license: Creative Commons Share-Alike attribution v3.0

  This example code will quickly get you up and running with the 
  SparkFun U/D/L/R/Flame Keypad. Pressing the flame button will
  turn on/off the red LED. Up and down adjust the brightness of
  the LED. And left and right are just there to look pretty will
  output their status via the serial monitor.
  
  Multiple touches are not supported in this code.
  
  edited by: chebe
  chebe.dreamwidth.org
  date: 9/29/11
  
  Stripped down code to just read what button is pushed,
  for testing purposes. Also added some extra checks to 
  cut out false left/right presses when pressing down.
  
  The circuit:
  SparkFun Keypad                Arduino
  -----------------------------------------
    Wire 1 (NC) ------------- No connection
   Wire 2 (LEDR) ----------------- D3
    Wire 3 (GND) ------------------GND
   Wire 4 (P5.1) ----------------- D5
   Wire 5 (P5.3) ----------------- D6
   Wire 6 (P5.2) ----------------- D7
*/

// Pin definitions
int LEDpin = 3;
int p51 = 5;
int p53 = 6;
int p52 = 7;

// Global variables
int button = 0;

void setup()
{
  // Initially set up the pins
  pinMode(LEDpin, OUTPUT);
  pinMode(p51, INPUT);
  pinMode(p53, INPUT);
  pinMode(p52, INPUT);
  digitalWrite(p51, HIGH);
  digitalWrite(p52, HIGH);
  digitalWrite(p53, HIGH);
  
  Serial.begin(9600);
}

void loop()
{
  button = getButtonState();  // Get button status
  if (button == 0x04)  // FLAME
  {
    Serial.println("centre");
  }
  else if (button == 0x02)  // UP
  {
    Serial.println("up");
  }
  else if (button == 0x01)  // DOWN
  {
    Serial.println("down");
  }
  else if (button == 0x08 && getButtonState() == 0x08)  // RIGHT
  {
    Serial.println("right");
  }
  else if (button == 0x10 && getButtonState() == 0x10)  // LEFT
  {
    Serial.println("left");
  }
}

/* getButtonState() will return a uint8_t representing the status
  of the SparkFun button pad. The meaning of the return value is:
  0x01: Down
  0x02: Up
  0x04: Flame
  0x08: Right
  0x10: Left
*/
uint8_t getButtonState()
{
  // Initially set all buttons as inputs, and pull them up
  pinMode(p52, INPUT);
  digitalWrite(p52, HIGH);
  pinMode(p51, INPUT);
  digitalWrite(p51, HIGH);
  pinMode(p53, INPUT);
  digitalWrite(p53, HIGH);
 
  // Read the d/u/flame buttons
  // When not pressed, reads 1
  // When pressed, reads 0
  if (!digitalRead(p53))
    return 0x01;  // Down
  if (!digitalRead(p52))
    return 0x02;  // Up
  if (!digitalRead(p51))
    return 0x04;  // Flame
  
  // Read right button
  pinMode(p52, OUTPUT);  // set p52 to output, set low
  digitalWrite(p52, LOW);
  delay(1); //debounce
  if (!digitalRead(p53) && digitalRead(p51))
    return 0x08;  // Right
  pinMode(p52, INPUT);  // set p52 back to input and pull-up
  digitalWrite(p52, HIGH);
  
  // Read left button
  pinMode(p51, OUTPUT);  // Set p51 to output and low
  digitalWrite(p51, LOW);
  delay(1); //debounce
  if (!digitalRead(p53) && digitalRead(p52))
    return 0x10;  // Left
  pinMode(p51, INPUT);  // Set p51 back to input and pull-up
  pinMode(p51, HIGH);
  
  return 0;
}


I have to say though, I was a bit surprised that the keypad came with such long wires, and unfinished ones at that. While it works well with an Arduino Uno, it doesn't do so well with the Arduino Lilypad. I'm going to have to come up with a suitable interface to get the two to play well together. (And yes, this is part of a larger project...)

Date: 2012-06-18 08:16 pm (UTC)
From: (Anonymous)
Awesome! Will definitely be using this. Thanks for posting! :)

Date: 2013-01-06 03:14 pm (UTC)
From: (Anonymous)
Thanks a lot you save me a lot of time with this version which is far better than the original code.
Page generated 2017-May-28, Sunday 08:42 am
Powered by Dreamwidth Studios