Skip to content

Instantly share code, notes, and snippets.

@dsonck92
Last active November 21, 2015 12:17
Show Gist options
  • Save dsonck92/7973241bbf5eb5a327d5 to your computer and use it in GitHub Desktop.
Save dsonck92/7973241bbf5eb5a327d5 to your computer and use it in GitHub Desktop.
Shift register based keyboard reading sketch
#include <MIDI.h>
// STROBE : PA0
// OUT_CLK: PA1
// OUT_D : PA2
// IN_CLK : PA3
// IN_D : PA4
// Current key
byte k = 8;
// Pressed regions
byte pressed[8];
int c = 0;
char e = 0;
MIDI_CREATE_DEFAULT_INSTANCE();
// Execute one clock cycle out
inline void clock_out()
{
// toggle clock
PINA |= (1<<PA1);
//delayMicroseconds(10);
// toggle clock again
PINA |= (1<<PA1);
//delayMicroseconds(10);
}
// Execute one clock cycle in
inline void clock_in()
{
// toggle clock
PINA |= (1<<PA3);
//delayMicroseconds(10);
// toggle clock again
PINA |= (1<<PA3);
//delayMicroseconds(10);
}
// Execute one latch cycle
inline void latch()
{
// toggle latch
PORTA ^= (1<<PA0);
//delayMicroseconds(10);
// toggle latch again
PORTA ^= (1<<PA0);
//delayMicroseconds(10);
}
// Initialize shift register
void initialize_register()
{
// set data out to LOW
PORTA &= ~(1<<PA2);
// set clock out to LOW
PORTA &= ~(1<<PA1);
// Clock 8 times
for(char I=0;I<8;I++)
{
clock_out();
}
}
// Initialize controller
void setup()
{
MIDI.begin();
// Serial.begin(9600);
// Initialize port mode
// x x x D_IN CLK_IN D_OUT CLK_OUT STROBE
DDRA = B00001111;
DDRB |= (1<<PB7);
PORTA = B11110001;
// Let arduino initialize the PWM output, then we'll simply update OCR0A ourselves
analogWrite(13,1);
initialize_register();
}
void loop()
{
while(1)
{
// Read bit
byte val;
// Move to next key
k ++; // Increment our k state
clock_out(); // Push the bit along the shift register
// We need to reset our register
if(k > 7)
{
// Reset the register
k = 0; // Reset our k state
// Set OUT_D to HIGH
PORTA |= (1<<PA2);
// Clock the bit out
clock_out();
// Set OUT_D to LOW
PORTA &= ~(1<<PA2);
// Toggle pin 13 for debug
c+= e;
if(c == 0x0000)
{
e = 1;
}
if(c == 0x07FF)
{
e = -1;
}
OCR0A = c >> 4;
}
// Present the key bit and load the parallel matrix data
latch();
// Skip first bit
clock_in();
// Store previous value
byte pv = pressed[k];
// Loop over the 7 bits
for(int I = 0;I < 7;I++)
{
// Read from PA4
byte val = (PINA >> PA4);
// Check for toggle state
if((pv^val) & 0x1)
{
// Yes and check for new state
if(val&0x1)
{
// Note pressed
MIDI.sendNoteOn(((I)*8-k+31)&0x7F,127,1);
}
else
{
// Note released
MIDI.sendNoteOff(((I)*8-k+31)&0x7F,127,1);
}
// Store new state into the pressed arra
pressed[k] = (pressed[k] & ~(1<<I)) | ((val&0x1)<<I);
}
// Shift the previous value to match the next key
pv >>=1;
// Load the next bit
clock_in();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment