The three main sections of this code are for controlling the NeoPixels, using the MCP23017's, and sending serial commands to the Bluefruit EZ-Key.
You can find all of the code documented below.
To reference the tables I used for the serial commands, should you want to adapt the code for some other use, go to the wonderfully table-y page below.
//Written by Timothy Reese, October 11th, 2015. //This code is a mix of Adafruit examples and my own customization. // Connect pin #12 of the expander to Analog 5 (i2c clock) // Connect pin #13 of the expander to Analog 4 (i2c data) // Connect pins #15, 16 and 17 of the expander to ground (address selection) // Connect pin #9 of the expander to 5V (power) // Connect pin #10 of the expander to ground (common ground) // Connect pin #18 through a ~10kohm resistor to 5V (reset pin, active low) // Input #0 is on pin 21 so connect a button or switch from there to ground #include <Wire.h> #include "Adafruit_MCP23017.h" #include <SoftwareSerial.h> #include <Adafruit_NeoPixel.h> #ifdef __AVR__ #include <avr/power.h> #endif Adafruit_MCP23017 mcp0; Adafruit_MCP23017 mcp1; Adafruit_MCP23017 mcp2; #define PIN 6 // for the NeoPixel data line. Adafruit_NeoPixel strip = Adafruit_NeoPixel(14, PIN, NEO_GRB + NEO_KHZ800); SoftwareSerial BT(4,3); //RX, and then TX. These are not your hardware serials, don't get them confused or gibberish will ensue on boot. void setup() { Serial.begin(9600); BT.begin(9600); mcp0.begin(0); // use default address 0 mcp1.begin(1); // use address 1 mcp2.begin(2); // use address 2 strip.begin(); strip.show(); // Initialize all pixels to 'off' // This could probably be an array mcp0.pinMode(0, INPUT); mcp0.pullUp(0, HIGH); // turn on a 100K pullup internally mcp0.pinMode(1, INPUT); mcp0.pullUp(1, HIGH); // turn on a 100K pullup internally mcp0.pinMode(2, INPUT); mcp0.pullUp(2, HIGH); // turn on a 100K pullup internally mcp0.pinMode(3, INPUT); mcp0.pullUp(3, HIGH); // turn on a 100K pullup internally mcp0.pinMode(4, INPUT); mcp0.pullUp(4, HIGH); // turn on a 100K pullup internally mcp0.pinMode(5, INPUT); mcp0.pullUp(5, HIGH); // turn on a 100K pullup internally mcp0.pinMode(6, INPUT); mcp0.pullUp(6, HIGH); // turn on a 100K pullup internally mcp0.pinMode(7, INPUT); mcp0.pullUp(7, HIGH); // turn on a 100K pullup internally mcp0.pinMode(8, INPUT); mcp0.pullUp(8, HIGH); // turn on a 100K pullup internally mcp0.pinMode(9, INPUT); mcp0.pullUp(9, HIGH); // turn on a 100K pullup internally mcp0.pinMode(10, INPUT); mcp0.pullUp(10, HIGH); // turn on a 100K pullup internally mcp0.pinMode(11, INPUT); mcp0.pullUp(11, HIGH); // turn on a 100K pullup internally mcp0.pinMode(12, INPUT); mcp0.pullUp(12, HIGH); // turn on a 100K pullup internally mcp0.pinMode(13, INPUT); mcp0.pullUp(13, HIGH); // turn on a 100K pullup internally mcp0.pinMode(14, INPUT); mcp0.pullUp(14, HIGH); // turn on a 100K pullup internally mcp0.pinMode(15, INPUT); mcp0.pullUp(15, HIGH); // turn on a 100K pullup internally mcp1.pinMode(0, INPUT); mcp1.pullUp(0, HIGH); // turn on a 100K pullup internally mcp1.pinMode(1, INPUT); mcp1.pullUp(1, HIGH); // turn on a 100K pullup internally mcp1.pinMode(2, INPUT); mcp1.pullUp(2, HIGH); // turn on a 100K pullup internally mcp1.pinMode(3, INPUT); mcp1.pullUp(3, HIGH); // turn on a 100K pullup internally mcp1.pinMode(4, INPUT); mcp1.pullUp(4, HIGH); // turn on a 100K pullup internally mcp1.pinMode(5, INPUT); mcp1.pullUp(5, HIGH); // turn on a 100K pullup internally mcp1.pinMode(6, INPUT); mcp1.pullUp(6, HIGH); // turn on a 100K pullup internally mcp1.pinMode(7, INPUT); mcp1.pullUp(7, HIGH); // turn on a 100K pullup internally mcp1.pinMode(8, INPUT); mcp1.pullUp(8, HIGH); // turn on a 100K pullup internally mcp1.pinMode(9, INPUT); mcp1.pullUp(9, HIGH); // turn on a 100K pullup internally mcp1.pinMode(10, INPUT); mcp1.pullUp(10, HIGH); // turn on a 100K pullup internally mcp1.pinMode(11, INPUT); mcp1.pullUp(11, HIGH); // turn on a 100K pullup internally mcp1.pinMode(12, INPUT); mcp1.pullUp(12, HIGH); // turn on a 100K pullup internally mcp1.pinMode(13, INPUT); mcp1.pullUp(13, HIGH); // turn on a 100K pullup internally mcp1.pinMode(14, INPUT); mcp1.pullUp(14, HIGH); // turn on a 100K pullup internally mcp1.pinMode(15, INPUT); mcp1.pullUp(15, HIGH); // turn on a 100K pullup internally mcp2.pinMode(0, INPUT); mcp2.pullUp(0, HIGH); // turn on a 100K pullup internally mcp2.pinMode(1, INPUT); mcp2.pullUp(1, HIGH); // turn on a 100K pullup internally mcp2.pinMode(2, INPUT); mcp2.pullUp(2, HIGH); // turn on a 100K pullup internally mcp2.pinMode(3, INPUT); mcp2.pullUp(3, HIGH); // turn on a 100K pullup internally mcp2.pinMode(4, INPUT); mcp2.pullUp(4, HIGH); // turn on a 100K pullup internally mcp2.pinMode(5, INPUT); mcp2.pullUp(5, HIGH); // turn on a 100K pullup internally mcp2.pinMode(6, INPUT); mcp2.pullUp(6, HIGH); // turn on a 100K pullup internally mcp2.pinMode(7, INPUT); mcp2.pullUp(7, HIGH); // turn on a 100K pullup internally mcp2.pinMode(8, INPUT); mcp2.pullUp(8, HIGH); // turn on a 100K pullup internally mcp2.pinMode(9, INPUT); mcp2.pullUp(9, HIGH); // turn on a 100K pullup internally mcp2.pinMode(10, INPUT); mcp2.pullUp(10, HIGH); // turn on a 100K pullup internally mcp2.pinMode(11, INPUT); mcp2.pullUp(11, HIGH); // turn on a 100K pullup internally mcp2.pinMode(12, INPUT); mcp2.pullUp(12, HIGH); // turn on a 100K pullup internally mcp2.pinMode(13, INPUT); mcp2.pullUp(13, HIGH); // turn on a 100K pullup internally mcp2.pinMode(14, INPUT); mcp2.pullUp(14, HIGH); // turn on a 100K pullup internally mcp2.pinMode(15, INPUT); mcp2.pullUp(15, HIGH); // turn on a 100K pullup internally // pinMode(13, OUTPUT); // use the p13 LED as debugging } // For the Raw HID commands, here's the function. void keyCommand(uint8_t modifiers, uint8_t keycode1, uint8_t keycode2 = 0, uint8_t keycode3 = 0, uint8_t keycode4 = 0, uint8_t keycode5 = 0, uint8_t keycode6 = 0) { BT.write(0xFD); // our command BT.write(modifiers); // modifier! BT.write((byte)0x00); // 0x00 BT.write(keycode1); // key code #1 BT.write(keycode2); // key code #2 BT.write(keycode3); // key code #3 BT.write(keycode4); // key code #4 BT.write(keycode5); // key code #5 BT.write(keycode6); // key code #6 } void loop() { // The LED will 'echo' the button - used for debugging. // digitalWrite(13, mcp0.digitalRead(0)); //NeoPixel Arcade Button Colors strip.setPixelColor(0, 255, 165, 0); strip.setPixelColor(1, 255, 165, 0); strip.setPixelColor(2, 255, 165, 0); strip.setPixelColor(3, 255, 165, 0); strip.setPixelColor(4, 255, 165, 0); strip.setPixelColor(5, 255, 165, 0); strip.setPixelColor(6, 255, 0, 0); strip.setPixelColor(7, 255, 0, 0); strip.setPixelColor(8, 255, 0, 0); strip.setPixelColor(9, 255, 0, 0); strip.setPixelColor(10, 255, 0, 0); strip.setPixelColor(11, 255, 0, 0); strip.setPixelColor(12, 255, 0, 0); strip.setPixelColor(13, 255, 165, 0); strip.show(); // All keyCommands are from the Raw HID Keyboard Reports section, and you just count up from 4, //starting at 4 on the list. So "B" would be a 5. // Likewise "I" would be a 12. // The BT.write commands are using the Hex values for ASCII. // I've included both because I used both while writing the original code, and also so you can //pick and choose if you wish to use it for another project. //Preview 1 if (mcp0.digitalRead(0) == LOW) { Serial.println("Success Preview 1!"); keyCommand(0,30); strip.setPixelColor(6, 255, 255, 255); strip.show(); delay(250); keyCommand(0,0); } //Preview 2 if (mcp0.digitalRead(1) == LOW) { Serial.println("Success Preview 2!"); keyCommand(0,31); strip.setPixelColor(7, 255, 255, 255); strip.show(); delay(250); keyCommand(0,0); } //Preview 3 if (mcp0.digitalRead(2) == LOW) { Serial.println("Success Preview 3!"); keyCommand(0,32); strip.setPixelColor(8, 255, 255, 255); strip.show(); delay(250); keyCommand(0,0); } //Preview 4 if (mcp0.digitalRead(3) == LOW) { Serial.println("Success Preview 4!"); keyCommand(0,33); strip.setPixelColor(9, 255, 255, 255); strip.show(); delay(250); keyCommand(0,0); } //Preview 5 if (mcp0.digitalRead(4) == LOW) { Serial.println("Success Preview 5!"); keyCommand(0,34); strip.setPixelColor(10, 255, 255, 255); strip.show(); delay(250); keyCommand(0,0); } //Preview 6 if (mcp0.digitalRead(5) == LOW) { Serial.println("Success Preview 6!"); keyCommand(0,35); strip.setPixelColor(11, 255, 255, 255); strip.show(); delay(250); keyCommand(0,0); } //Auto Transition (Space) if (mcp0.digitalRead(6) == LOW) { Serial.println("Success Auto Transition!"); keyCommand(0,44); strip.setPixelColor(12, 255, 255, 255); strip.show(); delay(250); keyCommand(0,0); } //Prog 1 if (mcp0.digitalRead(7) == LOW) { Serial.println("Success F1!"); BT.write(0x0F); strip.setPixelColor(5, 255, 255, 255); strip.show(); delay(250); } //Prog 2 if (mcp0.digitalRead(8) == LOW) { Serial.println("Success F2!"); BT.write(0x10); strip.setPixelColor(4, 255, 255, 255); strip.show(); delay(250); } //Prog 3 if (mcp0.digitalRead(9) == LOW) { Serial.println("Success F3!"); BT.write(0x11); strip.setPixelColor(3, 255, 255, 255); strip.show(); delay(250); } //Prog 4 if (mcp0.digitalRead(10) == LOW) { Serial.println("Success F4!"); BT.write(0x12); strip.setPixelColor(2, 255, 255, 255); strip.show(); delay(250); } //Prog 5 if (mcp0.digitalRead(11) == LOW) { Serial.println("Success F5!"); BT.write(0x13); strip.setPixelColor(1, 255, 255, 255); strip.show(); delay(250); } //Prog 6 if (mcp0.digitalRead(12) == LOW) { Serial.println("Success F6!"); BT.write(0x14); strip.setPixelColor(0, 255, 255, 255); strip.show(); delay(250); } //Cut (enter) if (mcp0.digitalRead(13) == LOW) { Serial.println("Success Cut!"); BT.write(0x0A); strip.setPixelColor(13, 255, 255, 255); strip.show(); delay(250); } // Record (home) if (mcp0.digitalRead(14) == LOW) { Serial.println("Success Record!"); BT.write(0x02); delay(250); } // Go Live (end) if (mcp0.digitalRead(15) == LOW) { Serial.println("Success Go Live!"); BT.write(0x05); delay(250); } // Edit Media 1 (z) if (mcp1.digitalRead(0) == LOW) { Serial.println("Success Edit Media 1!"); BT.write(0x7A); delay(250); } // Edit Graphic 1 (q) if (mcp1.digitalRead(1) == LOW) { Serial.println("Success Edit Graphic 1!"); BT.write(0x71); delay(250); } // Edit Graphic 2 (w) if (mcp1.digitalRead(2) == LOW) { Serial.println("Success Edit Graphic 2!"); BT.write(0x77); delay(250); } // Edit Graphic 3 (e) if (mcp1.digitalRead(3) == LOW) { Serial.println("Success Edit Graphic 3!"); BT.write(0x65); delay(250); } // Go to Start (g) if (mcp1.digitalRead(4) == LOW) { Serial.println("Success Go to Start!"); BT.write(0x67); delay(250); } // Play/Pause (k) if (mcp1.digitalRead(5) == LOW) { Serial.println("Success Play/Pause!"); BT.write(0x6b); delay(250); } // Go to End (') if (mcp1.digitalRead(6) == LOW) { Serial.println("Success Go to End!"); BT.write(0x27); delay(250); } // Edit Media 2 (x) if (mcp1.digitalRead(7) == LOW) { Serial.println("Success Edit Media 2!"); BT.write(0x78); delay(250); } // Edit Audio (a) if (mcp1.digitalRead(8) == LOW) { Serial.println("Success Edit Audio!"); BT.write(0x61); delay(250); } // Edit Stream (s) if (mcp1.digitalRead(9) == LOW) { Serial.println("Success Edit Stream!"); BT.write(0x73); delay(250); } // Edit Transition (d) if (mcp1.digitalRead(10) == LOW) { Serial.println("Success Edit Transition!"); BT.write(0x64); delay(250); } // Go to In (u) if (mcp1.digitalRead(11) == LOW) { Serial.println("Success Go to In!"); BT.write(0x75); delay(250); } // Set In (i) if (mcp1.digitalRead(12) == LOW) { Serial.println("Success Set In!"); BT.write(0x69); delay(250); } // Set Out (o) if (mcp1.digitalRead(13) == LOW) { Serial.println("Success Set Out!"); BT.write(0x6F); delay(250); } // Graphics 1 Preview (Numpad 1) if (mcp1.digitalRead(14) == LOW) { Serial.println("Success Graphics 1 Preview!"); keyCommand(0,89); delay(250); keyCommand(0,0); } // Graphics 2 Preview (Numpad 2) if (mcp1.digitalRead(15) == LOW) { Serial.println("Success Graphics 2 Preview!"); keyCommand(0,90); delay(250); keyCommand(0,0); } // Graphics 3 Preview (Numpad 3) if (mcp2.digitalRead(0) == LOW) { Serial.println("Success Graphics 3 Preview!"); keyCommand(0,91); delay(250); keyCommand(0,0); } // Graphics 1 Push (Numpad 4) if (mcp2.digitalRead(1) == LOW) { Serial.println("Success Graphics 1 Push!"); keyCommand(0,92); delay(250); keyCommand(0,0); } // Graphics 2 Push (Numpad 5) if (mcp2.digitalRead(2) == LOW) { Serial.println("Success Graphics 2 Push!"); keyCommand(0,93); delay(250); keyCommand(0,0); } // Graphics 3 Push (Numpad 6) if (mcp2.digitalRead(3) == LOW) { Serial.println("Success Graphics 3 Push!"); keyCommand(0,94); delay(250); keyCommand(0,0); } // Graphics 1 Pull (Numpad 7) if (mcp2.digitalRead(4) == LOW) { Serial.println("Success Graphics 1 Pull!"); keyCommand(0,95); delay(250); keyCommand(0,0); } // Graphics 2 Pull (Numpad 8) if (mcp2.digitalRead(5) == LOW) { Serial.println("Success Graphics 2 Pull!"); keyCommand(0,96); delay(250); keyCommand(0,0); } // Graphics 3 Pull (Numpad 9) if (mcp2.digitalRead(6) == LOW) { Serial.println("Success Graphics 3 Pull!"); keyCommand(0,97); delay(250); keyCommand(0,0); } } //This is a breakdown of the Function Commands via Hex, //since they're not spelled out on the Bluefruit guide. //0x0F = F1 //0x10 = F2 //0x11 = F3 //0x12 = F4 //0x13 = F5 //0x14 = F6 //0x15 = F7 //0x16 = F8 //0x17 = F9 //0x18 = F10 //0x19 = F11 //0x1A = F12 // https://learn.adafruit.com/introducing-bluefruit-ez-key-diy-bluetooth-hid-keyboard/sending-keys-via-serial // http://www.instructables.com/id/different-ways-to-count/
Text editor powered by tinymce.