Overview

You can make your very own BMO with 3D Printing and DIY electronics. This guide will walk you through the steps of 3D printing the parts, soldering the components and assembling this delightful electronic companion.
The mini 8x8 LED matrix makes an awesome head for BMO, programed to display several fun and playful facial expressions. Program your own animation to make new faces, letters or totally mathematical expressions ;-)
This guide was written for the Gemma v2 board, but can be done with either the Gemma v2 or M0 Gemma. We recommend the Gemma M0 as it is easier to use and is more compatible with modern computers!

3D Printing

BMO's box enclosure, cover and limbs looks best printed in teal. A spool of teal colored ABS ranges from $30-50 depending on where you purchase it.

Below is a small list of places to get filament. Make sure your filaments diameter size matches your 3d printer. Most common size is 1.75mm and 3mm.

You can print BMO's buttons in different colored ABS or paint each piece. The buttons are rather small, so you will need to make sure your build plate is clean and nicely leveled. These parts are a bit difficult to print so make a few copies to make a batch of each. You can do this in MakerWare by copying and pasting them.

The tolerances in the holes are optimized for ABS but should work with PLA. You can use an x-acto knife in moderation to lose the tolerances to fit the components.

bmo-box.stl
bmo-cover.stl
bmo-limbs.stl
bmo-green.stl
bmo-yellow.stl
bmo-blue.stl
bmp-green.stl
ABS 230c/120c
No Raft/Support
%15 infill
2 shells
0.2 layer height
Takes around 2-3 hours to print all 10 pieces.

Painting BMO

If you 3D Print the buttons in different colored ABS, you only have to print BMO's letters on the sides.

Use a fine brush and even out the bristles by trimming them with sharp scissors.

Black acrylic paint works best on ABS prints. Apply small portions of paint and spread it on the surface of the raised letters on each side. Lightly dab on the edges to get a clean finished look. If you accidentally mark outside the letters, quickly rinse it down with water and try again. Let stand to dry for a few minutes.

Circuit Diagram

This diagram uses the Gemma v2 but you can also use the Gemma M0 with the exact same wiring!

Gemma + 8x8 LED Matrix

Using the GEMMA in this build allows us to plug in a rechargeable battery directly into the JST port is directly on the board. GEMMA can be powered by USB but will need to have a battery power source for portability.

  • VCC pin goes to VBAT
  • GND pin goes to GND
  • SCL pin goes to D2/A1
  • SDA pin goes to D0

Prototyping

If your new to working with GEMMA, be sure to use a breadboard and jumper wires to prototype. Use alligator clips to clip jumper wires to GEMMA. The 8x8 LED matrix w/backpack will need header + pins soldered to the breakouts. Check out the adafruits guide to LED backpacks for more details.

Arduino Code

The Arduino code presented below works well on GEMMA v2.. But if you have an M0 board you must use the CircuitPython code on the next page of this guide, no Arduino IDE required!
If this is your first time using Gemma, work through the Introducing Gemma guide first; you need to customize some settings in the Arduino IDE.

Be sure to check out Phil Burgess's space invader pendant guide for getting the source code on to GEMMA properly.
Once you have your GEMMA/Trinket profiles installed in your Adafruit Arduino IDE, copy this code into a new sketch in Arduino and save it as matrix.ino.
// Trinket/Gemma + LED matrix backpack jewelry.  Plays animated
// sequence on LED matrix.  Press reset button to display again,
// or add optional momentary button between pin #1 and +V.
// THERE IS NO ANIMATION DATA IN THIS SOURCE FILE, you should
// rarely need to change anything here.  EDIT anim.h INSTEAD.

#define BRIGHTNESS   12 // 0=min, 15=max
#define I2C_ADDR   0x70 // Edit if backpack A0/A1 jumpers set

#include <TinyWireM.h>
#include <avr/power.h>
#include <avr/sleep.h>
#include "bmo.h"       // Animation data is located here

static const uint8_t PROGMEM reorder[] = { // Column-reordering table
    0x00,0x40,0x20,0x60,0x10,0x50,0x30,0x70,0x08,0x48,0x28,0x68,0x18,0x58,0x38,0x78,
    0x04,0x44,0x24,0x64,0x14,0x54,0x34,0x74,0x0c,0x4c,0x2c,0x6c,0x1c,0x5c,0x3c,0x7c,
    0x02,0x42,0x22,0x62,0x12,0x52,0x32,0x72,0x0a,0x4a,0x2a,0x6a,0x1a,0x5a,0x3a,0x7a,
    0x06,0x46,0x26,0x66,0x16,0x56,0x36,0x76,0x0e,0x4e,0x2e,0x6e,0x1e,0x5e,0x3e,0x7e,
    0x01,0x41,0x21,0x61,0x11,0x51,0x31,0x71,0x09,0x49,0x29,0x69,0x19,0x59,0x39,0x79,
    0x05,0x45,0x25,0x65,0x15,0x55,0x35,0x75,0x0d,0x4d,0x2d,0x6d,0x1d,0x5d,0x3d,0x7d,
    0x03,0x43,0x23,0x63,0x13,0x53,0x33,0x73,0x0b,0x4b,0x2b,0x6b,0x1b,0x5b,0x3b,0x7b,
    0x07,0x47,0x27,0x67,0x17,0x57,0x37,0x77,0x0f,0x4f,0x2f,0x6f,0x1f,0x5f,0x3f,0x7f,
    0x80,0xc0,0xa0,0xe0,0x90,0xd0,0xb0,0xf0,0x88,0xc8,0xa8,0xe8,0x98,0xd8,0xb8,0xf8,
    0x84,0xc4,0xa4,0xe4,0x94,0xd4,0xb4,0xf4,0x8c,0xcc,0xac,0xec,0x9c,0xdc,0xbc,0xfc,
    0x82,0xc2,0xa2,0xe2,0x92,0xd2,0xb2,0xf2,0x8a,0xca,0xaa,0xea,0x9a,0xda,0xba,0xfa,
    0x86,0xc6,0xa6,0xe6,0x96,0xd6,0xb6,0xf6,0x8e,0xce,0xae,0xee,0x9e,0xde,0xbe,0xfe,
    0x81,0xc1,0xa1,0xe1,0x91,0xd1,0xb1,0xf1,0x89,0xc9,0xa9,0xe9,0x99,0xd9,0xb9,0xf9,
    0x85,0xc5,0xa5,0xe5,0x95,0xd5,0xb5,0xf5,0x8d,0xcd,0xad,0xed,0x9d,0xdd,0xbd,0xfd,
    0x83,0xc3,0xa3,0xe3,0x93,0xd3,0xb3,0xf3,0x8b,0xcb,0xab,0xeb,0x9b,0xdb,0xbb,0xfb,
    0x87,0xc7,0xa7,0xe7,0x97,0xd7,0xb7,0xf7,0x8f,0xcf,0xaf,0xef,0x9f,0xdf,0xbf,0xff };

void ledCmd(uint8_t x) { // Issue command to LED backback driver
  TinyWireM.beginTransmission(I2C_ADDR);
  TinyWireM.write(x);
  TinyWireM.endTransmission();
}

void clear(void) { // Clear display buffer
  TinyWireM.beginTransmission(I2C_ADDR);
  for(uint8_t i=0; i<17; i++) TinyWireM.write(0);
  TinyWireM.endTransmission();
}

void setup() {
  power_timer1_disable();    // Disable unused peripherals
  power_adc_disable();       // to save power
  PCMSK |= _BV(PCINT1);      // Set change mask for pin 1
  TinyWireM.begin();         // I2C init
  clear();                   // Blank display
  ledCmd(0x21);              // Turn on oscillator
  ledCmd(0xE0 | BRIGHTNESS); // Set brightness
  ledCmd(0x81);              // Display on, no blink
}

uint8_t rep = REPS;

void loop() {

  for(int i=0; i<sizeof(anim); i) { // For each frame...
    TinyWireM.beginTransmission(I2C_ADDR);
    TinyWireM.write(0);             // Start address
    for(uint8_t j=0; j<8; j++) {    // 8 rows...
      TinyWireM.write(pgm_read_byte(&reorder[pgm_read_byte(&anim[i++])]));
      TinyWireM.write(0);
    }
    TinyWireM.endTransmission();
    delay(pgm_read_byte(&anim[i++]) * 10);
  }

  if(!--rep) {             // If last cycle...
    ledCmd(0x20);          // LED matrix in standby mode
    GIMSK = _BV(PCIE);     // Enable pin change interrupt
    power_all_disable();   // All peripherals off
    set_sleep_mode(SLEEP_MODE_PWR_DOWN);
    sleep_enable();
    sei();                 // Keep interrupts disabled
    sleep_mode();          // Power down CPU (pin 1 will wake)
    // Execution resumes here on wake.
    GIMSK = 0;             // Disable pin change interrupt
    rep   = REPS;          // Reset animation counter
    power_timer0_enable(); // Re-enable timer
    power_usi_enable();    // Re-enable USI
    TinyWireM.begin();     // Re-init I2C
    clear();               // Blank display
    ledCmd(0x21);          // Re-enable matrix
  }
}

ISR(PCINT0_vect) {} // Button tap
Create a new window and paste in the BMO animation code and save it as bmo.h in the same directory as the matrix sketch.

You may have to remove the .ino extension that gets added to the bmo.h file making it bmo.h.ino, remove that last .ino appending to just .h. Close the IDE and reopen it. The matrix sketch should show the bmo.h file in a tab.

Goto the tools file menu and select the Adafruit Gemma 8MHz profile under the Board drop down menu. Select USBTinyISP under the Programer drop down in the tool file menu.

Plug in a mini USB cable to the Gemma and connect it to your computer. Wait until you see a red blinkling LED on the Gemma and then hit the left arrow icon button to upload the code.
If you get a message in the IDE "Done Uploading" the code successfully uploaded to the GEMMA!
      // Animation data for Trinket/Gemma + LED matrix backpack jewelry. 
#define REPS 255 // Number of times to repeat the animation loop (1-255)
const uint8_t PROGMEM anim[] = {
  
  B11111111, // 1 frame
  B10011001,
  B10011001,
  B11111111,
  B10000001,
  B11000011,
  B11100111,
  B11111111,
  25, // 0.25 second delay
  
  B11111111, // 2 frame
  B10011001,
  B10011001,
  B11111111,
  B10111101,
  B10111101,
  B11000011,
  B11111111,
  25, // 0.25 second delay
  
  B11111111, // 3 frame
  B10011001,
  B10011001,
  B11111111,
  B10000001,
  B11000011,
  B11100111,
  B11111111,
  25, // 0.25 second delay
  
  B11111111, // 4 frame
  B10011001,
  B10011001,
  B11111111,
  B10111101,
  B10111101,
  B11000011,
  B11111111,
  25, // 0.25 second delay
  
  B11111111, // 5 frame
  B10011001,
  B10011001,
  B11111111,
  B11111111,
  B11111111,
  B10000001,
  B11111111,
  25, // 0.25 second delay
  
  B11111111, // 6 frame
  B10011001,
  B10011001,
  B11111111,
  B11100111,
  B11011011,
  B11100111,
  B11111111,
  25, // 0.25 second delay
  
  B11111111, // 7 frame
  B10111101,
  B00011000,
  B10111101,
  B11100111,
  B11011011,
  B11100111,
  B11111111,
  25, // 0.25 second delay
  
  B11111111, // 8 frame
  B11111111,
  B00011000,
  B11111111,
  B11100111,
  B11011011,
  B11100111,
  B11111111,
  25, // 0.25 second delay
  
  B11111111, // 9 frame
  B10111101,
  B00011000,
  B10111101,
  B11100111,
  B11011011,
  B11100111,
  B11111111,
  25, // 0.25 second delay
};
    

Writing Custom LED Animations

Check out Phil Burgess's Space invader guide for a great break down on how to write your own LED animations.

Animation Tool for Adafruit 8x8 LED Matrix

Check out this awesome website for building letter based LED animations. You simply click on letters to build an animation which can then be out putted to animation data for the Trinket/Gemma. It's awesome!

Assembling Circuit

Setting up wires

You will need to cut and strip 6 strands of 30 guage wrapping wire for connecting the button and 8x8 LED matrix to GEMMA. Measure the length of the strips to about 90mm. You can optionally add labels to each wire with a piece of masking tape. If your new to working with GEMMA, check out the intro guide.

Mini 8x8 LED Matrix

The 0.8' led matrix comes with an I2c Backpack that will need to be soldered to the matrix. Carefully slide the matrix into the backpack and flip it over. Triple check that the text is on the same side as the From Adafruit text. Be sure to check out the 8x8 LED matrix intro guide

Solder all 16 pins. Apply the soldering iron to the pin and hold it there for a few seconds. Add small amount of solder to heated pin, not the tip of the iron! Clip and trim the pins when you're finished soldering.

Wiring 8x8 LED Matrix

Apply a small amount of solder to tin the 4 pins on the top of the 8x8 LED matrix backpack. Try to heat the back of the pin, and then applying the solder to the front of the pin.

Solder 4 strips of 30 gauge wrapping wire to the 4 pins on the backpack. Try heating the back and pushing the wire through once it's liquidy.

Connecting 8x8 LED Matrix to GEMMA

Use a third helping hand to hold your components in place while you solder. Tin the 6 pins on the GEMMA. Solder the 4 wires from the LED Matrix to the pins of the GEMMA. Below is a mini reference list for each pin.

  • SLC to D2/A1
  • SDA to D0
  • GND to GND
  • VCC to VBat
And here's the GEMMA + 8x8 LED matrix circuit! At this point, you can plug in a lipo battery to the JST to power it on and test if it works. The mini 8x8 LED Matrix should have enough slack to move freely from the GEMMA.

Switch/JST adapter

For conveniently powering our circuit, we recommend creating a switch/JST adapter. Using a JST extension cable, we can splice it onto a slide switch. The male end of the JST connects to the GEMMA, while the female port connects to your rechargeable battery.

Tin the middle and any outside pin of the slide switch with a small amount of solder. Be sure to apply rosin to each pin in order for the solder to stick properly. Use heat shrink tubing to secure our soldered connections.

Snip off the extra pin in the switch. It could cause a short in our circuit once it's mounted in the box enclosure.

3d_printing_switch-jst-solder.jpg

Use a third helping hand to assist you. Use each arm to hold onto the JST ports. Use diagonal tweezers to hold the stripped wire with one hand while using your other hand to hold the soldering iron.

Push Button

Use a tactile push button for replaying the LED animations.
Snip off any two diagonal pins and tin them.

Before soldering, be sure to add a piece of heat shrink tubing for securing the connection after you solder.

Solder one piece of wrapping wire to each pin.

With the wires securely soldered, put the heat shrink tubing over the connects and heat it up to seal the connections.

Once the button is wired up, solder the two wires to the GEMMA. Order of pins doesn't matter as long as one goes to 3V and the other to D1.

  • Pin A to 3V
  • Pin B to D1
Here's what the complete circuit looks like. The push button should also have enough slack for it to move around in the enclosure. Gemma acts as BMO's brains, while the LED matrix+backpack is his face. We can assume the battery is his heart ;-)

The next page shows you how to put these electro guts into BMO's boxy box.

Assembling BMO

Be careful when moving the cables around! Be super cautious not to over flex/bend any of the wires, it could totally break and that sucks! But if any of them do, you can re-solder your connections.

Adding the 8x8 LED Matrix

Before adding the LED matrix, add a black piece of tape to cover up the slot right below BMO's face. It's just for decoration, it doesn't actually do anything but adds a great finishing detail to make BMO look more like BMO.

Position the 8x8 LED matrix 'upright' by making sure the pin outs are at the top and adafruit logo at the bottom. Insert the LED Matrix into box with the top going in first, and then the bottom. The LED matrix should loosely fit into the BMO's box enclosure. Ensure the wiring in the pinout are positioned to the top.

3d_printing_bmo-pushbutton.jpg

Adding Push Button

Gently move the wiring of the LED matrix away from the top clips.

Slightly bend one of the pins of the push button inward, so it does not touch any part of the LED Matrix.

3d_printing_bmo-button-technique.jpg

Insert one side of the button into the clips near the top of the box.  Align up the push button with the hole in the top middle. Apply pressure to the opposite side of the button while pushing the top of the box inward. This will make a slight bend allowing the push button to snap into place.

3d_printing_bmo-gemma-cover2.jpg

Add Gemma

Place GEMMA over the back of the box cover with the USB port aligned up to the bottom opening. Lightly press GEMMA down into the cover so it stays put.

3d_printing_bmo-switch-gemma.jpg

Add the JST/Switch adapter to the GEMMA. Make sure two cables are not too long or else it won't fit inside the box!

Closing it Up

You will need to neatly fit the GEMMA, lipo battery and the JST/switch adapter into the box. For an easier build, try using a 110mAh lithium polymer battery (the 150mAh is a little more tricky to fit into the box, but it can be done!). Place the battery in between the Gemma and led matrix.

If the cover doesn't quite close, you may need to reduce the length of the battery cable and/or the JST/switch adapter. With patience, trial and error, you're box will nicely close shut with a little wiggle room.

Mounting JST/Switch adapter

Carefully adjust the cables and insert the switch through the cut out near the top of the box cover. If the wires are too long, you may need to cut off some slack so all the components fit inside the box.

Add the Finishing Details

If you have already, pop in the button pieces into the holes on the front of BMO's boxy box. If they don't fit, using an x-acto knife to loosen up the opening. Be careful, don't over loosen the holes or the limbs and buttons won't stay put! But if you do, you can super glue them into place. BMO's arms and legs should freely rotate.

Add a split ring to the cover and put it on a necklace to wear your new electronic pal for a 3d printed adventure time!
This guide was first published on Feb 20, 2014. It was last updated on Feb 20, 2014.