This is sample code to read the analog keypad I describe in this article. Simply clone the ATtiny85 template library and replace the main.c file with the one contained here.
Created
April 24, 2014 23:19
-
-
Save thegaragelab/11272851 to your computer and use it in GitHub Desktop.
Reading an analog keypad on the ATtiny85
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*--------------------------------------------------------------------------* | |
* 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