Interacting with the Button Pad Controller SPI
By popular request, here's an update to the first code for the Button Pad Controller SPI. This sketch now includes interactive feedback, in the form of changing colours based on key-presses.
[caption id="" align="alignnone" width="267" caption="Click to view full size image."][/caption] [caption id="" align="alignnone" width="267" caption="Click to play video."][/caption]
// The wires #define CS 10 #define MISO 11 #define MOSI 12 #define SCK 13 // Frame buffer for lights int lights = 16; int depth = 3; byte buf[16][3]; boolean wait = false; boolean ready = true; void setup() { pinMode(CS, OUTPUT); pinMode(MISO, OUTPUT); pinMode(MOSI, INPUT); pinMode(SCK, OUTPUT); digitalWrite(CS, LOW); delay(100); blank(); Serial.begin(9600); Serial.println("Starting"); } void blank() { // init frame buffer for(int l = 0; l < lights; l++) { for(int d = 0; d < depth; d++) { buf[l][d] = 0; } } } void loop() { digitalWrite(SCK, HIGH); digitalWrite(CS, HIGH); delayMicroseconds(15); // Set lights: 3 x 16 bytes for(int d = 0; d < depth; d++) { for(int l = 0; l < lights; l++) { writeByte(buf[l][d]); } } if(!ready) { wait = true; ready = true; } // Read the buttons: 16 bytes. for(int l = 0; l < lights; l++) { // readByte returns a non-zero value when a button is pressed. byte b = readByte(); // If a button is pressed, change the colour. if (b > 0 && ready && !wait) { if (buf[l][2] > 0) { buf[l][2] = 0; } else if (buf[l][1] > 0) { buf[l][1] = 0; buf[l][2] = 255; } else if (buf[l][0] > 0) { buf[l][0] = 0; buf[l][1] = 255; } else { buf[l][0] = 255; } Serial.print("Button "); Serial.print(l); Serial.print(": "); Serial.print((int)b); Serial.println(); // Change colours slowly. ready = false; } } digitalWrite(CS, LOW); // After the second cycle, get ready to read new button clicks. if(wait) { delay(500); wait = false; ready = true; } delayMicroseconds(400); } // Write out a byte. // This is for a single colour channel, for a single button. void writeByte(byte data) { for(int i = 0; i < 8; i++) { digitalWrite(SCK, LOW); delayMicroseconds(5); digitalWrite(MISO, (data & (1 << i)) >> i); delayMicroseconds(5); digitalWrite(SCK, HIGH); delayMicroseconds(10); } } // Read a byte. // Returns the value for a single button. // Non-zero if it is pressed, or 0 otherwise. byte readByte() { byte result = 0; for(int i = 0; i < 8; i++) { digitalWrite(SCK, LOW); delayMicroseconds(5); result += (!digitalRead(MOSI)) * i; delayMicroseconds(5); digitalWrite(SCK, HIGH); delayMicroseconds(10); } return result; }