BlueLive: Livestream Studio switcher controller

Similar documents
Portable Apple Watch Charger

Feather Weather Lamp. Created by Ruiz Brothers. Last updated on :54:26 PM UTC

Adafruit TPL5110 Power Timer Breakout

Tent Lantern. Created by Timothy Reese. Last updated on :17:25 AM UTC

Trellis 3D Printed Enclosure

3D Printed Camera LED Ring

Celebration Spectacles

Adafruit TPL5111 Reset Enable Timer Breakout

Solar Boost Bag. Created by Becky Stern. Last updated on :44:55 PM UTC

NeoPixel LED Cortana Costume

LED Eyes. Created by Ruiz Brothers. Last updated on :50:55 AM UTC

Guardian Shield+ Zelda Breath of the Wild

Trinket NeoPixel LED Longboard

Neon LED Signs. Created by John Park. Last updated on :11:09 PM UTC

i2c/spi LCD Backpack Created by lady ada Last updated on :11:04 PM UTC

Adafruit MCP9808 Precision I2C Temperature Sensor Guide

Lie Ren's Stormflower Gun Blade

NeoPixel Ring Bangle Bracelet

7 Portable Multitouch Raspberry Pi Tablet

7" Portable HDMI Monitor

NeoPixel Bike Light. Created by Ruiz Brothers. Last updated on :43:46 PM UTC

3D Printed 20w Amplifier Box

3D Printed 20w Amplifier Box

3D Printed LED Buckle

Interior Purse Light. Created by Becky Stern. Last updated on :41:08 PM UTC

Infinity Mirror Valentine's Candy Box

Crickit Carnival Bumper Bot

Bluetooth Controlled NeoPixel Headphones

DIY Bluetooth Gamepad

Adafruit PowerBoost 500 Shield

Fiddy - the FTDI Clip

Light-Up Angler Fish Embroidery

Con Badge with Circuit Playground Express

3D Printed Daft Punk Helmet with Bluetooth

MCP Bit DAC Tutorial

NeoPixel Manicure. Created by Sophy Wong. Last updated on :50:38 PM UTC

Adafruit Capacitive Touch Sensor Breakouts

Jewel Hair Stick. Created by Leslie Birch. Last updated on :47:17 PM UTC

Adabot Operation Game

Circuit Playground Yoyo

MCP Bit DAC Tutorial

Adafruit DRV2605 Haptic Controller Breakout

Phone-Activated Talking Dog Collar

3D Printed LED Knuckle Jewelry

Mystical LED Halloween Hood

Circuit Playground Digital Input

RGB LCD Shield. Created by lady ada. Last updated on :48:40 PM UTC

Android GBoard Morse Code Control with Circuit Playground Express

Coffee Detonator: The TNT Plunger Grinder

Getting Started with FLORA

3D Printed Case for Adafruit Feather

FPV Mini Display. Created by Ruiz Brothers. Last updated on :00:18 PM UTC

Trinket-Powered Conference Room Occupancy Display

Adafruit VL53L0X Time of Flight Micro-LIDAR Distance Sensor Breakout

FLORA TV-B-Gone. Created by Becky Stern. Last updated on :32:57 PM UTC

Adafruit GPIO Expander Bonnet for Raspberry Pi Created by Kattni Rembor. Last updated on :12:47 PM UTC

Cup o' Sound. Created by Becky Stern. Last updated on :30:06 PM EST

3D Printed LED Goggles

Adafruit LED Sequins. Created by Becky Stern. Last updated on :02:00 AM UTC

NeoPixie Dust Bag with Circuit Playground Express

Bunny Ears with MakeCode

Adafruit DRV2605 Haptic Controller Breakout

Getting Started with FLORA

Adafruit APDS9960 breakout

NeoMatrix 8x8 Word Clock

ISS Pin. Created by Leslie Birch. Last updated on :27:30 PM UTC

Boomy The Boombox. Created by Ruiz Brothers. Last updated on :52:13 PM UTC

Fiddy - the FTDI Clip

Audio Prank Gift Box. Created by Becky Stern. Last updated on :46:15 PM UTC

3D Printed Google AIY Voice Kit

GPS Logging Dog Harness

Adafruit Si5351 Clock Generator Breakout

Introducing Adafruit Trellis

DIY Wireless DDR Dance Pad with Bluefruit EZ-Key

FLORA Pixel Brooch. Created by Becky Stern. Last updated on :19:07 PM EST

Pushrod Garage. Created by John Park. Last updated on :07:30 PM UTC

Crickit Powered Holiday Diorama

Clockwork Goggles. Created by John Park. Last updated on :03:10 PM UTC

Sword & Wand Prop Effects with Circuit Playground

CircuitPython Media Dial

Joy Featherwing. Created by Dean Miller. Last updated on :03:07 PM UTC

Adafruit 8x16 LED Matrix FeatherWing

Adafruit LED Sequins. Created by Becky Stern. Last updated on :00:06 PM EST

Mystery Box: NeoMatrix Mk I

Circuit Playground Express Head-Tilt Ears

Flora Brake Light Backpack

Magical Mistletoe. Created by Leslie Birch. Last updated on :45:29 PM UTC

Crickit Dancing Marionette Kit Created by Dano Wall. Last updated on :03:11 PM UTC

Camera LED Ring Light

NeoLoch. Inquisitor Core. Assembly Instructions (9/3/2015)

DIY Circuit Playground Shields

Adafruit Mini TFT " 160x80

Monochrome OLED Breakouts

Circuit Playground Combadge

PyPortal NeoPixel Color Picker Created by Kattni Rembor. Last updated on :42:41 PM UTC

Adafruit Prototyping Pi Plate. Created by Ladyada

NeoPixel Basketball Hoop

Introducing Circuit Playground

Mini Mac Pi. Created by Ruiz Brothers. Last updated on :43:27 PM UTC

Adafruit HUZZAH32 - ESP32 Feather

Transcription:

BlueLive: Livestream Studio switcher controller Created by Timothy Reese Last updated on 2015-11-30 11:10:12 AM EST

Guide Contents Guide Contents Overview Why Livestream Studio? But what if I don't use Livestream Studio? Tools You'll Need: Disclaimers: Let's get started! 3D Printing NeoPixel Arcade Button Hack Wiring Test! MCP Wiring Bluefruit Wiring Metro 328 (or Arduino Uno)/NeoPixel Wiring Powerboost 1000C Wiring Momentary Pushbuttons/Arcade Buttons to MCP Now Connect the I/Os to the Buttons Bakelite 5V and Ground Rails Code Pairing to Your Machine Assembly LiPo Battery Labeling Special Thanks 2 3 4 5 6 7 7 8 15 21 21 22 22 24 27 28 30 30 36 50 52 52 54 59 Adafruit Industries https://learn.adafruit.com/bluelive Page 2 of 59

Overview Sometimes you need one button for the job, and sometimes you need many. This project is a fully enclosed 3D-printed Bluetooth controller, powered by a METRO 328 (http://adafru.it/jfg) and LiPoly battery (http://adafru.it/dce), mapped to use with Livestream Studio. Using the serial input on the Bluefruit EZ-Key (http://adafru.it/jfh) and some MCP23017 i2c expanders (http://adafru.it/jfi), there's a whole load of buttons. Arcade buttons. Pushbuttons. Buttons and buttons and buttons! Adafruit Industries https://learn.adafruit.com/bluelive Page 3 of 59

Why Livestream Studio? Livestream Studio is a powerful, streamlined video streaming software designed for use with PCs and Livestream's own switcher boxes. While incredibly robust, there isn't MIDI support for using just any controller you'd like. Using the hotkey portion of the software, this bypasses the need to use a regular keyboard to get at specific functions. Adafruit Industries https://learn.adafruit.com/bluelive Page 4 of 59

But what if I don't use Livestream Studio? Map it to whatever you'd like! The code is pretty heavily documented, so feel free to modify it to your needs. Adafruit Industries https://learn.adafruit.com/bluelive Page 5 of 59

Tools You'll Need: Soldering iron of some sort. I use an Aoyue, but any good ones will work. Needle nose pliers. My favorites are on my Leatherman II multitool. Flush cutters. Always and forever. Third hand tool. The $6 one from Adafruit will do the job, the super fancy one will do the job even better. Optional: Blu-Tack for soldering the NeoPixel mini PCBs. Amazon. (http://adafru.it/jqa) 3D Printer. If you don't have one, you can always source the parts out to Shapeways, or a similar service. Ever upward, never fearing. Silicone cover wire. I'm reiterating this here from the side, because it's not optional. Without silicone cover wire, the arcade button hack won't work. Trust me. You can use regular hookup wire for the rest of the project, but honestly, the silicone stuff is incredible. If you've never used it, and especially if you do high temperature RoHS soldering (380* C), you will love it. If you ever have to do a lot of cable wrangling, you'll love it. This project switched me over entirely. 2x M2 6mm machine screws. 8x M3 8mm (or more, doesn't really matter) flat screws. 1x 1000uf 6.3V (or higher) capacitor 1x 300-500 Ohm resistor 25x 150 Ohm resistors Adafruit Industries https://learn.adafruit.com/bluelive Page 6 of 59

3x 10k Ohm resistors Charting tape. White paint pen. Bluetooth 2.1 Adapter (http://adafru.it/jqb) (if you don't have one.) A drill of some sort. A roughly 1/8" drillbit, or M3 to be specific. Scissors. Disclaimers: This is a Bluetooth Raw HID and ASCII input project, not MIDI. The casing for this project was 3D printed, and because of its size, you'll want to make sure your bed level is tightly calibrated. It was designed to work within the parameters of a Makerbot Replicator 2, but any 3D printer that has the right build volume will absolutely work. This is a very large project, and quite a bit of work. None of the steps are difficult for soldering, or require wave ovens or sensitive scopes. But it is a not insubstantial amount of effort, so bear that in mind. Let's get started! Adafruit Industries https://learn.adafruit.com/bluelive Page 7 of 59

3D Printing When it comes to printing, I usually like to break things into pieces. This way, if a part fails on a large print, it doesn't result in a lot of lost time or material. For the outer casing, the top, sides, and bottom have all been cut in half. You can get the.stl files below. While printing mine, I had problems with curling on the bottom of my prints due to the size of the printing jobs, and general thickness of the parts. I had only recently gotten a 3D printer, so instead of continuing to generate lots of scrap, I made adjustments to the sides to compensate. The STLs attached to the project are unadjusted, so if your printer is dialed in, and you use a large enough raft and go slowly, you'll be fine. Download the Files to 3D Print on Thingiverse http://adafru.it/jfj Adafruit Industries https://learn.adafruit.com/bluelive Page 8 of 59

I decided to use a white filament for the sides near the end of the project, so that explains the switch in the next images. Due to the curling along the bottom of the edges, I needed to get the sides to line up. Adafruit Industries https://learn.adafruit.com/bluelive Page 9 of 59

Use M3 screws to attach the bottom plates before hot-gluing in the stabilizers. You can use the extra rubber feet from the Metro 328 packaging as the rubber feet for the controller. Handy! Adafruit Industries https://learn.adafruit.com/bluelive Page 10 of 59

I printed three types of parts I call stabilizers, to keep the sides in alignment, and prevent gaps with the bottom case. Just use a healthy amount of hot glue, and hold into position. These are entirely optional, if you're able to print with minimal curling. When gluing PLA material together for a high strength bond, don't use cyanoacylate (...like I did.) Use E6000. It's vastly better, I just didn't have any on hand. If you're in a pinch and need to use cyanoacrylate, just know it'll discolor PLA prints. Adafruit Industries https://learn.adafruit.com/bluelive Page 11 of 59

I got around the discoloring by using a Sharpie to go over the whitened areas on the black PLA prints, and then wiped them down with a 1:1 mixture of 91% isopropyl alcohol and acetone. Similarly, I printed little stands (inspired by Noe and Pedro) to hold the PCBs. These I also mounted with cyanoacrylate, but it didn't matter if there was discoloration. Adafruit Industries https://learn.adafruit.com/bluelive Page 12 of 59

By printing these mounts and and affixing them later, I was able to get an idea of the internal spacing of the enclosure for fitting the PCBs, without getting lost in hypothetical designs and too much time spent modeling. All of the PCBs click into place on their mounts, except for the Powerboost 1000C. Because it'll have to handle a USB plug being inserted and pulled for charging, I affixed it with 6mm long M2 screws. The measurements for where go these aren't especially precise, except for the Powerboost 1000C. The Powerboost 1000C board must be oriented towards the right sidewall, and I glued it into place once I had the walls affixed by machine screws to the base. Adafruit Industries https://learn.adafruit.com/bluelive Page 13 of 59

Adafruit Industries https://learn.adafruit.com/bluelive Page 14 of 59

NeoPixel Arcade Button Hack Use silicone wire, or you'll have to cut up and resolder the chain like I did (above.) You Must Use Silicone Cover Wire For This Part Of The Project. Must. This idea by Noe and Pedro is fantastic, they explain the procedure in their tutorial below. Arcade Button Hack Project http://adafru.it/jfk The V2 connector for the current NeoPixel Mini PCB pack didn't fit mine once the leads were soldered, so I made an adjustment to their design. The V3 is below, and will fit in the caps with no problems. Click here to download the V3 mod of the Arcade Button Connector http://adafru.it/jfl Adafruit Industries https://learn.adafruit.com/bluelive Page 15 of 59

Adafruit Industries https://learn.adafruit.com/bluelive Page 16 of 59

Affix all of the bottom portions of the arcade buttons into the top panel, once you've removed the button and plunger. Adafruit Industries https://learn.adafruit.com/bluelive Page 17 of 59

For soldering to the NeoPixel PCBs, I used a bit of Blutack. It does get tackier when hot, so make sure you don't overheat the pads, or you'll have to use some Blutack to remove residue. But this is a huge time saver, instead of awkwardly using a third hand, or the overkill of a Panavise. Adafruit Industries https://learn.adafruit.com/bluelive Page 18 of 59

Applying a bit of solder to the pads make them much easier to solder wires to. Adafruit Industries https://learn.adafruit.com/bluelive Page 19 of 59

When feeding in the LEDs, start with the 6th LED in the bottom row, and then take your time feeing counter clockwise. It takes a bit of wrangling. Once all the LEDs are in and fed through, put in the top caps. Adafruit Industries https://learn.adafruit.com/bluelive Page 20 of 59

Wiring The wiring for this project isn't particularly complicated, but it is repetitive. It's important to strike a balance between using enough wire, but not too much wire. It starts to add up, and get in the way when you're trying to close the project. Above is the schematic for the MCP23017 i2c 16 input/output port expander. It's the heart of this project, since two pins on an Arduino (or, in my case a Metro 328) into 48 pins. Test! Always test your circuits before soldering. Always. Adafruit Industries https://learn.adafruit.com/bluelive Page 21 of 59

MCP Wiring We'll be using three of the MCP23017, so to start, we need to identify them amongst themselves on the i2c address bus. mcp0: A0 = ground, A1 = ground, A2 = ground mcp1: A0 = 5V, A1 = ground, A2 = ground mcp2: A0 = ground, A1 = 5V, A2 = ground For the three chips, use their rails to: Connect pin 9 to 5V. Connect pin 10 to ground. Connect pin 18 to 5V, via a 10k Ohm resistor. Connect pin 12 to Analog 5 (of an Arduino Uno, i2c clock) Connect pin 13 to Analog 4 (of an Arduino Uno, i2c data) Bluefruit Wiring Adafruit Industries https://learn.adafruit.com/bluelive Page 22 of 59

Connect Ground to ground rail. Connect Vin to 5v rail. Connect RX to pin 3 (of Arduino Uno or Metro 328.) Connect TX (not used in code) to pin 4 (of Arduino Uno or Metro 328.) Adafruit Industries https://learn.adafruit.com/bluelive Page 23 of 59

Metro 328 (or Arduino Uno)/NeoPixel Wiring Connect Ground to ground rail. Adafruit Industries https://learn.adafruit.com/bluelive Page 24 of 59

Connect 5V to 5v rail. Connect a 1000uf 6.3V (or higher) capacitor across the + and - terminals on the Ground and 5V rails of the first protoboard, immediately next to the wires coming in from the Metro 328. NeoPixel arrangement below: Connect pin 6 to free column on protoboard. Connect 300-500 Ohm resistor to free column. Connect free hole on other side of 500 Ohm resistor to Din on first NeoPixel PCB. Connect 5V rail to 5V on first NeoPixel PCB. Connect Ground rail to GND on first NeoPixel PCB. Adafruit Industries https://learn.adafruit.com/bluelive Page 25 of 59

Adafruit Industries https://learn.adafruit.com/bluelive Page 26 of 59

You then connect every button to the correct GPA (or GPB) pin in sequence, with the other lead connected to ground. When the button is pressed and the GPA (or GPB) of each MCP connects to ground, that input is translated on the Arduino into a serial command. Powerboost 1000C Wiring Connect GND to one of the outside pins on the slide switch. Connect EN to the inside pin on the slide switch. Solder the USB-B style jack into the Powerboost 1000C, and run the short USB cable to the METRO 328. (if you use an Arduino Uno with USB-A type plugs, you'll need to find one short enough to not take up unnecessary space.) Even though you see the battery attached here, do not attach the LiPo battery until the very end of assembly. Never, ever, ever solder a circuit with the battery attached. Adafruit Industries https://learn.adafruit.com/bluelive Page 27 of 59

I repeat, do not solder the circuit with the LiPo battery attached. Plug it in at final case assembly. Momentary Pushbuttons/Arcade Buttons to MCP Connect all of the I/O Ground pins to each other as a daisy chain. It's a much cleaner way to wire. You can also connect these to the arcade buttons. Then connect the final one to the Ground rail. Connect each of the other I/O pins to their respective GPA/GPB pins on the MCP23017. See diagram above. Connect the LED Ground (-) to a 150 Ohm resistor, then this resistor to the Bakelite Ground rail. Connect the LED Positive (+) to the Bakelite 5V rail. Adafruit Industries https://learn.adafruit.com/bluelive Page 28 of 59

Adafruit Industries https://learn.adafruit.com/bluelive Page 29 of 59

Now Connect the I/Os to the Buttons Bakelite 5V and Ground Rails To limit the amount of wiring mess in this project, I cut a length of Bakelite to secure to the top of the case by printed 6mm standoffs. When cutting Bakelite, use scissors, and cut through holes you won't need. It's very crumbly and unpredictable to cut, but also cuts with little force, so take your time and give yourself margin. Adafruit Industries https://learn.adafruit.com/bluelive Page 30 of 59

I then drilled two holes for the 6mm screws to secure to the standoffs. Do not glue the standoffs to the top of the case until you're finished soldering. Adafruit Industries https://learn.adafruit.com/bluelive Page 31 of 59

Solder a wire from the common Ground and 5V rails on the protoboards, and then connect each individual Ground wire and 5V wire from the pushbuttons to the Bakelite rail. Adafruit Industries https://learn.adafruit.com/bluelive Page 32 of 59

Once you've soldered each in a row, bridge the joints (this is so much fun to do!) A note about soldering to Bakelite: it isn't easy. The pads aren't very robust, so be deliberate with your iron placement, and patient if the solder doesn't immediately leach. Adafruit Industries https://learn.adafruit.com/bluelive Page 33 of 59

Now that you've finished, glue the 6mm standoffs (already screwed to the Bakelite rail) to the top of the case, inbetween the arcade buttons and pushbuttons. Adafruit Industries https://learn.adafruit.com/bluelive Page 34 of 59

Adafruit Industries https://learn.adafruit.com/bluelive Page 35 of 59

Code 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. Click here to get the code on GitHub http://adafru.it/jfm 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. Click here to get the MCP23017 Library from Adafruit http://adafru.it/jfn Click here to get the NeoPixel Library from Adafruit http://adafru.it/azu Click here to see the BlueFruit EZ-Key Keys/Mouse via Serial page http://adafru.it/jfo //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> Adafruit Industries https://learn.adafruit.com/bluelive Page 36 of 59

#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 gib 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 Adafruit Industries https://learn.adafruit.com/bluelive Page 37 of 59

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); Adafruit Industries https://learn.adafruit.com/bluelive Page 38 of 59

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 Adafruit Industries https://learn.adafruit.com/bluelive Page 39 of 59

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(); keycommand(0,0); //Preview 2 Adafruit Industries https://learn.adafruit.com/bluelive Page 40 of 59

if (mcp0.digitalread(1) == LOW) { Serial.println("Success Preview 2!"); keycommand(0,31); strip.setpixelcolor(7, 255, 255, 255); strip.show(); 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(); 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(); 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(); keycommand(0,0); //Preview 6 Adafruit Industries https://learn.adafruit.com/bluelive Page 41 of 59

//Preview 6 if (mcp0.digitalread(5) == LOW) { Serial.println("Success Preview 6!"); keycommand(0,35); strip.setpixelcolor(11, 255, 255, 255); strip.show(); 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(); 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(); //Prog 2 if (mcp0.digitalread(8) == LOW) { Serial.println("Success F2!"); BT.write(0x10); strip.setpixelcolor(4, 255, 255, 255); strip.show(); //Prog 3 if (mcp0.digitalread(9) == LOW) { Adafruit Industries https://learn.adafruit.com/bluelive Page 42 of 59

if (mcp0.digitalread(9) == LOW) { Serial.println("Success F3!"); BT.write(0x11); strip.setpixelcolor(3, 255, 255, 255); strip.show(); //Prog 4 if (mcp0.digitalread(10) == LOW) { Serial.println("Success F4!"); BT.write(0x12); strip.setpixelcolor(2, 255, 255, 255); strip.show(); //Prog 5 if (mcp0.digitalread(11) == LOW) { Serial.println("Success F5!"); BT.write(0x13); strip.setpixelcolor(1, 255, 255, 255); strip.show(); //Prog 6 if (mcp0.digitalread(12) == LOW) { Serial.println("Success F6!"); BT.write(0x14); strip.setpixelcolor(0, 255, 255, 255); strip.show(); //Cut (enter) if (mcp0.digitalread(13) == LOW) { Serial.println("Success Cut!"); BT.write(0x0A); strip.setpixelcolor(13, 255, 255, 255); strip.show(); Adafruit Industries https://learn.adafruit.com/bluelive Page 43 of 59

// Record (home) if (mcp0.digitalread(14) == LOW) { Serial.println("Success Record!"); BT.write(0x02); // Go Live (end) if (mcp0.digitalread(15) == LOW) { Serial.println("Success Go Live!"); BT.write(0x05); // Edit Media 1 (z) if (mcp1.digitalread(0) == LOW) { Serial.println("Success Edit Media 1!"); BT.write(0x7A); // Edit Graphic 1 (q) if (mcp1.digitalread(1) == LOW) { Serial.println("Success Edit Graphic 1!"); BT.write(0x71); // Edit Graphic 2 (w) if (mcp1.digitalread(2) == LOW) { Serial.println("Success Edit Graphic 2!"); BT.write(0x77); Adafruit Industries https://learn.adafruit.com/bluelive Page 44 of 59

// Edit Graphic 3 (e) if (mcp1.digitalread(3) == LOW) { Serial.println("Success Edit Graphic 3!"); BT.write(0x65); // Go to Start (g) if (mcp1.digitalread(4) == LOW) { Serial.println("Success Go to Start!"); BT.write(0x67); // Play/Pause (k) if (mcp1.digitalread(5) == LOW) { Serial.println("Success Play/Pause!"); BT.write(0x6b); // Go to End (') if (mcp1.digitalread(6) == LOW) { Serial.println("Success Go to End!"); BT.write(0x27); // Edit Media 2 (x) if (mcp1.digitalread(7) == LOW) { Serial.println("Success Edit Media 2!"); BT.write(0x78); // Edit Audio (a) if (mcp1.digitalread(8) == LOW) { Serial.println("Success Edit Audio!"); Adafruit Industries https://learn.adafruit.com/bluelive Page 45 of 59

Serial.println("Success Edit Audio!"); BT.write(0x61); // Edit Stream (s) if (mcp1.digitalread(9) == LOW) { Serial.println("Success Edit Stream!"); BT.write(0x73); // Edit Transition (d) if (mcp1.digitalread(10) == LOW) { Serial.println("Success Edit Transition!"); BT.write(0x64); // Go to In (u) if (mcp1.digitalread(11) == LOW) { Serial.println("Success Go to In!"); BT.write(0x75); // Set In (i) if (mcp1.digitalread(12) == LOW) { Serial.println("Success Set In!"); BT.write(0x69); // Set Out (o) if (mcp1.digitalread(13) == LOW) { Serial.println("Success Set Out!"); BT.write(0x6F); // Graphics 1 Preview (Numpad 1) if (mcp1.digitalread(14) == LOW) { Adafruit Industries https://learn.adafruit.com/bluelive Page 46 of 59

if (mcp1.digitalread(14) == LOW) { Serial.println("Success Graphics 1 Preview!"); keycommand(0,89); keycommand(0,0); // Graphics 2 Preview (Numpad 2) if (mcp1.digitalread(15) == LOW) { Serial.println("Success Graphics 2 Preview!"); keycommand(0,90); keycommand(0,0); // Graphics 3 Preview (Numpad 3) if (mcp2.digitalread(0) == LOW) { Serial.println("Success Graphics 3 Preview!"); keycommand(0,91); keycommand(0,0); // Graphics 1 Push (Numpad 4) if (mcp2.digitalread(1) == LOW) { Serial.println("Success Graphics 1 Push!"); keycommand(0,92); keycommand(0,0); // Graphics 2 Push (Numpad 5) if (mcp2.digitalread(2) == LOW) { Serial.println("Success Graphics 2 Push!"); keycommand(0,93); keycommand(0,0); Adafruit Industries https://learn.adafruit.com/bluelive Page 47 of 59

// Graphics 3 Push (Numpad 6) if (mcp2.digitalread(3) == LOW) { Serial.println("Success Graphics 3 Push!"); keycommand(0,94); keycommand(0,0); // Graphics 1 Pull (Numpad 7) if (mcp2.digitalread(4) == LOW) { Serial.println("Success Graphics 1 Pull!"); keycommand(0,95); keycommand(0,0); // Graphics 2 Pull (Numpad 8) if (mcp2.digitalread(5) == LOW) { Serial.println("Success Graphics 2 Pull!"); keycommand(0,96); keycommand(0,0); // Graphics 3 Pull (Numpad 9) if (mcp2.digitalread(6) == LOW) { Serial.println("Success Graphics 3 Pull!"); keycommand(0,97); 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 Adafruit Industries https://learn.adafruit.com/bluelive Page 48 of 59

//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/ Adafruit Industries https://learn.adafruit.com/bluelive Page 49 of 59

Pairing to Your Machine A note about pairing: The current line of Livestream Studio hardware (HD31, HD51, HD510, HD550, and HD1710) all ship with Windows 7. Windows 7 doesn't natively support Bluetooth 4.0, and in my experience, I could not get it to pair with the Bluetooth 4.0 adapter available in the Adafruit shop. If you are an advanced user, you might be able to get it to work. Maybe. I really tried! So as a result, I had to buy a Bluetooth 2.1 adapter, link here: AZIO BTD-V201 (http://adafru.it/jqb) I just plugged it in, and it worked. Adafruit Industries https://learn.adafruit.com/bluelive Page 50 of 59

For more detailed instructions, follow the thorough guide on the Bluefruit EZ-Key page. Click here to learn how to pair the Bluefruit EZ-Key to your machine http://adafru.it/dpy Adafruit Industries https://learn.adafruit.com/bluelive Page 51 of 59

Assembly LiPo Battery I like to wrap some kapton tape around LiPo batteries, before attaching velcro. This gives me peace of mind when removing the battery, that I'm not placing direct force onto the foil wrapping the battery. For final assembly, make sure none of the wiring is snagging between the top and bottom panels. Insert the M3 flat machine screws into the top 4 corners. Adafruit Industries https://learn.adafruit.com/bluelive Page 52 of 59

Because of some tolerance issues with curling on mine, there was a bulge in the front. I fixed this by affixing a facade plate with cyanoacrylate glue, and then sanding down any protrusions. This single fix saved an enormous amount of time. Adafruit Industries https://learn.adafruit.com/bluelive Page 53 of 59

Labeling Adafruit Industries https://learn.adafruit.com/bluelive Page 54 of 59

For the labeling, I used thin charting tape, 1/8" wide. It's available at craft stores. I chose black, because black is all that was available. I then used a white paint pen. For ease of reference, I labeled all of the buttons. It makes it much easier to remember some of the hot keys on the fly. Adafruit Industries https://learn.adafruit.com/bluelive Page 55 of 59

Charting tape does not have a strong adhesive, so I dabbed a small amount of cyanoacrylate on the ends of each strip to prevent it from curling up. Underneath the Cut arcade button, you'll see two lights visible on the frame. The blue light means that the circuit is on, and if plugged in, the amber light means that the LiPo battery is charging. Adafruit Industries https://learn.adafruit.com/bluelive Page 56 of 59

And just like that, you're done! Adafruit Industries https://learn.adafruit.com/bluelive Page 57 of 59

Adafruit Industries https://learn.adafruit.com/bluelive Page 58 of 59

Special Thanks My special thanks on this project go to an innumerable number of internet forums I had to research, and my 3D printer, that tolerated an unbelievable number of test prints. Also, to Alex of RasPi.TV, for an excellent breakdown (http://adafru.it/jgc) of the i2c pattern for the MCP23017 chips. Adafruit Industries Last Updated: 2015-11-30 11:10:13 AM EST Page 59 of 59