Last active
November 21, 2015 12:17
-
-
Save dsonck92/7973241bbf5eb5a327d5 to your computer and use it in GitHub Desktop.
Shift register based keyboard reading sketch
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
#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