Feedback!

Shift Register Keyboard

Views: 11428 Difficulty: 3 Status: Development
Screen_shot_2012-12-21_at_7.15.06_pm

4 Daisy chained CD4021 shift registers gives us 32 inputs.

This shift register based keyboard is great way to add a ton of buttons to an Arduino project. You can grab one of the AlphaZed Keyboards at our store. It works by daisy chaining four CD4021 shift registers together so that using only 3 pins on the Atmega (data, latch, and clock) we get 32 inputs. (What are shift registers? Check out our introductory tutorial!) With 32 inputs we have more than enough for the English alphabet, with room left over for spacebar, enter, delete, shift, and some punctuation. This PCB uses surface mount components and comes ready-made. We also have a DIY Keyboard kit. It is easy to solder, because it uses only through-hole components. You can make one for yourself! Check out our other projects that use shift registers here. Plug this guy into an arduino Leonardo and you have yourself a handheld USB keyboard.

Big Keys

Big_key
We hope to offer this big through hole version of the keyboard as a DIY Kit soon!

Soldering The Keyboard

Time lapse video of the keyboard being soldered.

Video of Shift Keyboard working as a standard USB Keyboard w/ Leonardo

Hook up the shift register keyboard to an Arduino Leonardo and grab the code from below and you have yourself a little artisanal keyboard that works in regular computers!

Arduino Leonardo Code for Shift Register Keyboard as USB HID Keyboard

This code uses our AlphaZed keyboard connected to digital pins 3, 4, and 5 on an Arduino Leonardo. The heart of this code is the function:
void read_keyboard(){
  //set it to 0 to transmit data serially  
  digitalWrite(latchPin,LOW);
  //while the shift register is in serial mode
  //collect each shift register into a byte
  //the register attached to the chip comes in first 
  for (int i = 0; i < num_registers; i++){
    button_states[i] = shiftIn(dataPin, clockPin);
  }
  boolean something_in = false;
  for (int i = 0; i < num_registers; i++){    
    something_in = translate_buttons_2_keys(button_states[i], letters[i]);
    if (something_in) last_key_press = millis(); 
  }
  digitalWrite(latchPin,HIGH);
}
This code checks every shift register to see if any buttons are being pressed. If there is one being pressed then the something_in variable is set to true. The read_keyboard() function calls the translate_buttons_2_keys() function to read from each shift register. This function goes like this:
boolean translate_buttons_2_keys(byte buttons, char* keys){
  for(int i = 0 ; i < 8; i++){
     if ( (1 << i) & buttons ){
       cur_char = keys[i];
       Keyboard.print(keys[i]);
       char_index++;
       return true;
     }     
  }
 return false; 
}
This function iterates over each of the eight input pins on the CD4021 and checking its state in the line:
if ( (1  <<  i) & buttons )
This if statement is true when the ith button is being pressed. in that case we grab the character from the keys array and send it out to the USB keyboard in the line:
       Keyboard.print(keys[i]);
We use the shiftIn function defined at the end of this file but you could just as well use the Arduino ShiftIn function. Grab the code below!
/* LucidTronix AlphaZed Keyboard
 * works as standard USB keyboard
 * Tutorial and details at:
 * http://www.lucidtronix.com/tutorials/15
 *  AlphaZed connected to pins 3,4,5
 *  on Arduino Leonardo.
 *  This code requires Arduino Leonardo */ 


int dataPin = 3;
int clockPin = 4;
int latchPin = 5;

unsigned long last_press = 0;
unsigned long last_key_press = 0;

char* letters[] ={"_ zy--.!","tsrqxwvu","lkjiponm","dcbahgfe" };

int num_chars = 43;
int num_registers = 4;
byte button_states[] = {0x00,0x00,0x00,0x00};  //01001000
int cursor_index = 0;
int char_index = 0;
char cur_char = 'X';

void setup() {
  Serial.begin(9600);
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT); 
  pinMode(dataPin, INPUT);
  Keyboard.begin();

}

void loop() {
  if (millis() - last_key_press > 350) read_keyboard();
  delay(50);
}


void read_keyboard(){
  //set it to 0 to transmit data serially  
  digitalWrite(latchPin,LOW);
  //while the shift register is in serial mode
  //collect each shift register into a byte
  //the register attached to the chip comes in first 
  for (int i = 0; i < num_registers; i++){
    button_states[i] = shiftIn(dataPin, clockPin);
  }
  boolean something_in = false;
  for (int i = 0; i < num_registers; i++){    
    something_in = translate_buttons_2_keys(button_states[i], letters[i]);
    if (something_in) last_key_press = millis(); 
  }
  digitalWrite(latchPin,HIGH);
}

boolean translate_buttons_2_keys(byte buttons, char* keys){
  for(int i = 0 ; i < 8; i++){
     if ( (1 << i) & buttons ){
       cur_char = keys[i];
       Keyboard.print(keys[i]);
       char_index++;
       return true;
     }     
  }
 return false; 
}
byte shiftIn(int myDataPin, int myClockPin) { 
  int i;
  int temp = 0;
  int pinState;
  byte myDataIn = 0;

  pinMode(myClockPin, OUTPUT);
  pinMode(myDataPin, INPUT);

  for (i=7; i>=0; i--)
  {
    digitalWrite(myClockPin, 0);
    delayMicroseconds(20);
    temp = digitalRead(myDataPin);
    if (temp) {
      pinState = 1;
      myDataIn = myDataIn | (1 << i);
    }
    else {
      pinState = 0;
    }
    digitalWrite(myClockPin, 1);
  }
  return myDataIn;
}

Parts

Title Description # Cost Link Picture
SMD Keyboard PCB PCB holds 4 CD4021 shift registers and 30 buttons. 1 $8.0 Link Screen_shot_2013-02-15_at_6.34.59_pm
Shift Register IC STATIC SHFT REG 8STG 16-TSSOP Parallel or Serial to Serial 3 V ~ 18 V Value: Parallel to Serial 4 $0.45 Link Screen_shot_2012-12-28_at_7.33.47_pm
Resistor Array RES ARRAY 10K OHM 4 RES 1206 Value: 10k 8 $0.12 Link Vishay_-_cra06s-8
Button 6mm Through Hole Tactile Switch Through Hole SPST-NO 0.05A 12V Value: 0.05A @ 12VDC 32 $0.1 Link Screen_shot_2012-12-28_at_7.41.40_pm
Permalink: http://lucidtronix.com/tutorials/15
Keyboard kit using CD4021 shift registers and big through hole buttons....
32 buttons for a fully-functioning hand-held USB keyboard....
A QWERTY keyboard you build yourself....
Connect shift registers together to get more output and input pins from your microcontroller....
Shift Registers help you multiply your inputs and outputs....
Think of it like a shift register for Pulse Width Modulation (PWM)....
Build your own clock with the MCP79410 chip and 4 7-Segment LED modules....
Display 4 digits using only 3 MCU wires with the 4 x 7 Segment LED and shift register breakout board....