Skip to content

Instantly share code, notes, and snippets.

@thegaragelab
Created April 24, 2014 23:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save thegaragelab/11272851 to your computer and use it in GitHub Desktop.
Save thegaragelab/11272851 to your computer and use it in GitHub Desktop.
Reading an analog keypad on the ATtiny85
/*--------------------------------------------------------------------------*
* Main program
*---------------------------------------------------------------------------*
* 14-Apr-2014 ShaneG
*
* Template program for ATtiny85 C/asm projects.
*--------------------------------------------------------------------------*/
#include <stdint.h>
#include <stdbool.h>
#include <avr/io.h>
#include "softuart.h"
#include "utility.h"
#include "iohelp.h"
// Forward declaration with 'noreturn' attribute
void main() __attribute__ ((noreturn));
//! ADC input for the keyboard
#define ADC_KEYBOARD 1
/* Key values
*/
#define KEYVAL_UP 170
#define KEYVAL_RIGHT 342
#define KEYVAL_DOWN 512
#define KEYVAL_LEFT 682
#define KEYVAL_CENTER 852
/* Error range
*
* A key is considered pressed if the ADC reading is withing +/- this amount
* from the 'ideal' value described above.
*/
#define KEYVAL_RANGE 16
/** Key codes
*
* Defined as bit masks so they can be combined easily.
*/
typedef enum _KEYCODE {
KEYCODE_UP = 0x01,
KEYCODE_RIGHT = 0x02,
KEYCODE_DOWN = 0x04,
KEYCODE_LEFT = 0x08,
KEYCODE_CENTER = 0x10,
} KEYCODE;
/** Determine which (if any) key is pressed
*
* @return a bit mask representing the key pressed or 0 if no key.
*/
uint8_t keyRead() {
uint8_t result = 0xFF;
for(uint8_t count=0; count<4; count++) {
uint16_t keyval = adcRead(ADC_KEYBOARD, 1, 1);
if((keyval>=(KEYVAL_UP - KEYVAL_RANGE))&&(keyval<=(KEYVAL_UP + KEYVAL_RANGE)))
result &= KEYCODE_UP;
else if((keyval>=(KEYVAL_RIGHT - KEYVAL_RANGE))&&(keyval<=(KEYVAL_RIGHT + KEYVAL_RANGE)))
result &= KEYCODE_RIGHT;
else if((keyval>=(KEYVAL_DOWN - KEYVAL_RANGE))&&(keyval<=(KEYVAL_DOWN + KEYVAL_RANGE)))
result &= KEYCODE_DOWN;
else if((keyval>=(KEYVAL_LEFT - KEYVAL_RANGE))&&(keyval<=(KEYVAL_LEFT + KEYVAL_RANGE)))
result &= KEYCODE_LEFT;
else if((keyval>=(KEYVAL_CENTER - KEYVAL_RANGE))&&(keyval<=(KEYVAL_CENTER + KEYVAL_RANGE)))
result &= KEYCODE_CENTER;
}
// All done, a consistant keypress will have a valid bit code now
return result;
}
/** Program entry point
*/
void main() {
uartInit();
adcInit(ADC_KEYBOARD);
// Keep showing when the key changes
uint8_t key, last = 0;
while(true) {
key = keyRead();
if(key!=last) {
if(key==KEYCODE_UP)
uartPrintP(PSTR("UP\n"));
else if(key==KEYCODE_RIGHT)
uartPrintP(PSTR("RIGHT\n"));
else if(key==KEYCODE_DOWN)
uartPrintP(PSTR("DOWN\n"));
else if(key==KEYCODE_LEFT)
uartPrintP(PSTR("LEFT\n"));
else if(key==KEYCODE_CENTER)
uartPrintP(PSTR("CENTER\n"));
}
last = key;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment