Feb 10, 2016

S2 Spa Soother

Nowadays, the go-to tools for signaling a change or alerting us to a condition are lights and noises. This is a project that explores the softer, calming side of electronics. The S2 in the title refers to "sights and sounds". But here the sights are mellow, colorful patterns and the sounds are relaxing nature and environmental tracks. You can have four different sound tracks, all switchable at the press of a button, for whatever your mood. Just imagine yourself chillin' in a warm bath, or daydreaming under blankets to peaceful sounds and slowly changing patterns of light.

Difficult: Although the finished project is physically small, there's a lot going on here. There's both a RainbowDuino AND a Raspberry Pi Zero in the build. You'll need to either laser-cut a box (plans supplied on github), or find a suitable pre-made box. Just the laser-cut box is covered in this post. Sound will require soldering components or using a small breadboard. Alternative to the sound build given here is an HDMI to VGA/3.5mm Audio adapter such as this one, $11.99 on Amazon. I did not test this out because I thought the cable and adapter would take up too much space in the small box I made. However, it "should" work...

The laser-cut box is small in order to have a nice little box. That means that space is very limited inside for mounting components and routing wires. Plan your build and think about what you are doing, even using this post as a guide.

You'll have to cut the pre-made box for the diffusion lens and various buttons and speaker. A pre-made box needs to be an appropriate depth for your set-up, so you see soft patterns and not individual LEDs. There's a post by Gilad Dayagi about a  plasma system (no sound) using an 8x8 RGB LED Matrix, which was an inspiration for this build. If you don't need sound and want an easy build, stop here and go to the excellent  instructable by giladaya.

Gilad says about the diffusion:
I picked the length of the standoffs to be 15 mm after some experimentation.
According to your specific diffuser material, you may need a different distance - experiment to get the best results."

If you use a box of different dimensions from either giladaya's version or mine, or perhaps a different diffusion material, you'll have to test for desired results.


  • Laser Cutting and/or craft work cut/glue etc.)
  • Soldering
  • Able to read schematics and translate them to circuits
  • Optional: Cutting circuit board (perma-pronto); makes assembly easier
  • A RainbowDuino from seeedstudio  $21.95 from Amazon
  • RGB LED Matrix like the Geeetech available for $6.95 from Amazon
    • Common Anode 8x8 Matrix
    • Note - the LEDs in this build are not reacting to or changing with the sounds, they are changing patterns independently.
  • Raspberry Pi Zero for Sound Output $5.00, but supply is limited at the moment
  • Breadboard/1/2 sized Adafruit PermaProto Board
    • will be used as a base for buttons, and optionally other component mounts
  • Components for PWM Sound
    • Caps: 2x 0.01uf and 2x 10uf
    • Resistors: 2x 270 Ohm and 2x 150 Ohm
  • LM386-based audio amplifier: build your own from Dean's instructions like I did, or buy a cheap pre-made amplifier like this one: $4.14 on Amazon
    • Dean has a full list of components in his post
    • I added components to filter out noise:
      • (1) 1N4001 Diode
      • (1) 470uF Capacitor
  • Visaton 2in K50 8 Ohm Speaker was plenty loud! Parts Express $2.52
  • Wooden Box from craft store         < $6.00  *NOTE: Depth is critical for diffusion effect!
  • Cut your own box with a laser - 12in x 12in x 1/8in craft plywood    < $6.00 (plans supplied)
  • I used a light diffuser plastic from TAP Plastics, under $6.00/sq ft
  • 12mm x12mm momentary switches from Adafruit  $5.95
  • 4x 12mm/0.5in stand offs (length could change dependent on your box depth) for RainbowDuino
  • 4x 12mm/0.5in stand offs for Raspberry Pi Zero
  • 8x 4/40 0.25in/6mm screws for holding Rainbowduno to standoffs
  • 8x 4/40 0.25in/6mm screws for holding Raspberry Pi Zero to standoffs
  • Titebond II Wood Glue - 8 oz        < $3.00, Amazon/Ace Harware/etc. 
  • Clamp(s)
  • Super Glue
  • Optional Right-Angle Header for RainbowDuino connections
  • Optional (2) 6in length Male to Female jumpers for Right-Angle Headers
  • 40 ct female header for the Raspberry Pi Zero
  • Optional: 40 ct female header, makes it easy to connect all the wires to various components 
  • 22 AWG hook-up wire, solid core; various colors help differentiate connections
  • 2.5mm Panel power jack
  • Optional on/off momentary switch (as built uses this) plus 1 current limiting resistor (mine was 100 Ohms) for the LED in the switch
    • Requires (2 pieces) 3-pin Right Angle Header
    • (2) Female-to-Female Jumpers to connect to pin D3 and GND Right Angle Header on RainbowDuino
    •  (2) Female-to-Male Jumpers to connect to Pololu (below)
  • Optional pusbutton power switch (controller) from Pololu  $3.95 (as built uses this)
  • 9V Power Supply from Adafruit,$6.95
Available on github:
  • My github has the following -
    • Python script for controlling sound clips
    • Laser Cut wooden box files CorelDraw/SVG/PDF
    • My version (with a few changes) of giladaya's Particle system sketch: S2_Spa_Soother_Spin.ino
  • Sketch for original Particle System (aka plasma) LED effect - giladaya's github
Other Resources
  • MakerCase generator for box laser cut files
  • Epilog Helix 60 watt laser or Universal Laser, TechShop San Francisco (Priceless! JK...)

S2 Spa Soother - Build the Box Part 1

You'll need access to a laser cutter or send out to a fab service. I used an Epilog 60W Laser and a Universal Laser Systems model at TechShop San Francisco. The settings I used for the Epilog were:

For 1/8"/3mm  Revell Brand Birch Plywood
Vector: S=20, P=80, F=500
Raster: S=95, P=90
For raised letters on the buttons, S=70 and perhaps two passes. Do a test run to see preferred result.

The different parts of the box are all named in the CorelDraw document: Top Shim, Buttons, etc. There are six sides to the box:

  • Top, with buttons
  • Bottom, same size as top
  • Two vertical sides
  • Front, with opening for diffuser and on-off momentary switch
  • Back, with opening for speaker and screw holes
So, why the shims? The buttons have a little bit of slop, sideways rotation, when glued onto the switch activator. The shims help reduce that. The buttons fit into the top-plus-shim so sideways motion is restricted.

Breadboard Spacing:
We're going to be soldering our sound buttons to a piece of perma-proto breadboard in a later step, to make the final assembly easier. Fritzing diagram I used is HERE.To get proper alignment of the buttons to the 0.1in/2.54mm pitch of the breadboard:

  • make a quick layout in Fritzing of your 12mm momentary switches at the spacing you'd like
  • Export the Fritzing layout as a PDF document
  • Import the PDF into CorelDraw/AI/Inkscape
  • Adjust and repeat as needed
  • To Center your switches in another object in CorelDraw, like the box top in this case:
    • Group the switches
    • Select the box top outline, then shift-click the Group of switches
      • TIP: All selected objects will align to the last selected object. In this case the switches  will move relative to the box top
    • Arrange/Align and Distribute/Align Objects Vertically (or Horizontally depending on your situation)
Aligning Button Outlines to Breadboard Spacing in CorelDraw

Custom Buttons
Already included in the CorelDraw document are custom raised letter button tops. You can use these or the stock plastic tops. If you don't want custom buttons, skip down to Prepare the Lens.

Here's a quick tip for creating the raised letter/relief letter effect. This can be especially useful for buttons on bespoke electronics. The raised area not only identifies the function of a button, but can also give a tactile clue on which button you are pressing. I found Black fill works fine on an Epilog laser. For the Universal Laser, use a vector etch (BLUE fill).

Using CorelDraw, create your text with the Artistic Text tool as normal, sized to fit in a round or square button.  Use Convert to Curve on the text.

In the screenshot below, the text ("Ocean") has been converted to NoFill inside a square-shaped button object. Because it's NoFill, you can't see it in the screenshot.

Next, select the surrounding object and use Uniform Fill/Black, as shown in the following screenshot.

When you send these objects to an Epilog laser (from CorelDraw) with proper raster settings, the black area surrounding the text will be etched, leaving the text slightly raised above the background.

To attach the custom buttons to the momentary switch:

  • glue the top (raised letter portion) to a base (hole cut in center); allow to set overnight
  • DON'T GLUE the button to the momentary switch yet! We'll do that in a later step, Wire Up the Circuit and Test

Glue the shim to the inside of the top/button cutout. You can use the buttons themselves to hold the shim in place while the glue sets. Just be careful not to get any glue onto the buttons themselves, at this point.

In a later step, we will be soldering the buttons to a cut-down piece of perma-prototyping board (from Adafruit) to make assembly easier.

You'll want to glue some interior components before assembling the box.

Prepare the Lens

The diffusion lens plastic is a little tricky to work with. First, score the width of the material about 30 strokes with a box cutter against a straight edge.

With the scored side up, place the scored line over the edge of a table or other sharp surface. Place the straight edge right next to the scored line and press down firmly on the straight edge to hold it in place. Finally, quickly snap down. With luck, you'll have a nice clean edge:

Finish up by repeating the process in the other dimension for the lens.

Now, glue the lens to the inside front opening of the box, smooth side of the material facing out.

The CA glue I was using allows extra time to position your glued piece. However, it still sets up fairly quickly.

Using TiteBond II or similar wood glue, glue the two ascending sides, bottom and front of the box. Put the top (button cutout) in place but DO NOT GLUE the top in place yet!  Use a clamp to hold the sides tight. I applied the glue to one side of the finger joints with a cotton swap ("Q-Tip"), finishing with a line of glue on the inside. Better still would be a fine brush, but the swabs were all I had available. If you get glue where it doesn't belong, clean up with a damp cloth.

OK, let's stop here and let that set for awhile. We will come back to the box in Final Assembly.

Get Some Sounds, Next

S2 Spa Soother - Get Some Sounds

If you don't have Audacity, download it for Windows/Mac/Linux.

I like repeated environmental sounds like crickets, ocean waves, rain or streams. A quick google yields lots of sources for free-to-use, downloadable clips. Ones I used include:
Most of the time, the sound effects will be in *.mp3/*.m4a audio format. We'll use Audacity to convert this to a mono *.wav file for the Spa Soother, since it only has one (rather lo-fi) speaker.

Start with file/open for a downloaded sound effect.

Convert to Mono:

The sound effect may be too soft in volume, you may need to Amplify it (different file from previous screenshot):

Finally, if the clip is too short, use Repeat to extend the time. This works well for environmental sounds because, given a long enough starter clip like 30-60 seconds,  it's difficult to tell when the sounds are being repeated.

File/Export your sound file as WAV (Microsoft) signed 16 bit PCM file format and copy it over to your /home/pi directory for testing.

We'll be copying over the music when we get to the code section. Next, Wire up the Circuit

S2 Spa Soother - Wire up the Circuit and Test

Before we proceed,  we need to load up our OS.

I used Raspbian Jessie for this build.

For the next steps, we will be working directly on the raspberry pi zero via SSH and wireless. I rarely use the GUI for Raspberry Pi, so can't help you using that. I used this great post from David Maitland on how to set up the Pi Zero "headless". Warning! This requires linux to edit the SD card.

Sound testing is coming up next. To prepare for this, solder on female headers to the Raspberry Pi Zero like so:

We're using the Raspberry Pi Zero for sound. Too bad it doesn't have a line output!

Fortunately, Adafruit has a nice tutorial on this: Adding Basic Audio Output to  Raspberry Pi Zero. LadyAda shows us some sweet reverse engineering on how to get PWM audio out of the Pi Zero.

Read the post on learn.adafruit.com for some capacitor substitutions LadyAda made to this circuit.

I followed along with the fairly simple schematic and got some low-volume sound:

To get louder mono sound out, I grafted on an LM386-based amplifier to the output. You can buy these cheap on Amazon, or make your own fairly quickly. I used the post at hackaweek, the web site of Dean Segovis, on how to make a simple LM386 amp.

Here's Dean's schematic:

It took about 90 minutes to put the PWM LM386 circuits together on a breadboard (I work slow).

Once I had it working, I made a soldered version on a perma-proto board.

You can test and debug your circuit using double-ended alligator clips, one end to plus/minus on a small speaker, the other to plus/minus from the LM386 amplifier. You can test the speaker by SSH-ing to the Pi Zero in a terminal; then, from a command line by enter "speaker-test". If successful, this will produce "pink noise" (similar to "white noise") that will at least let you know sound is coming out.

I found out much later that I was picking up significant noise. I googled for a solution and found one that worked. I added a 1N4001 Diode in-line on the 5V rail anywhere before the LM386; the "banded" side/cathode of the Diode faces toward the LM386. Also added a 470uF Capacitor across the rails, positive to 5V, negative to GND, soldered before the LM386. This eliminated the noise.

Hard to see, but there's a 1N4001 Diode in there, as well as the 470uF Capacitor

For testing the code in the next step, we'll need to solder up the buttons. The buttons for sound choices will be soldered to a cut-down piece of 1/2 breadboard sized perma-proto board. This actually makes it easier for final assembly - not so many wires, and don't have to solder directly to the tiny switch pins. Cut the perma-proto board in half, length-wise down the middle. Use a full half for the buttons. The other half you will cut a piece out 3 columns x 5 rows wide. This will be used later for the power button on the front of the box.

Optional: I later cut another small piece of perma-proto to hold screw terminals. These are not required, but made it easier to attach the speaker wires to the LM386: speaker wires to one side of cut perma-proto, then LM386 GND/Audio Input to the screw terminals.

Warning: FR4-based circuit boards are not intended to be cut by the consumer and pose a health risk from the dust particles. Wear eye protection, gloves and a fiberglass-rated dust mask!

Piece of other half of perma-proto board will be used for power switch in final assembly

One leg of the momentary pin will be soldered to the +V rail. Clip the other leg where it meets the 5V rail so it doesn't touch the rail - this leg will be connected to the Pi Zero pin. Connect the +V rail to a 5V output on the Pi Zero; I used Board Pin 4. The Pi Zero-connected leg of each button will be soldered to a PTH (Plated Thru-Hole) column. Then, solder a jumper wire to the pin on the leg NOT connected to +5V. Connect Button1 to Board pin 11, and so on as shown in the following diagram:

Button Connections to Pi Zero Board Pins

Tip: Snip tabs off  bottom of switch 
to make it lay flat against the board

This was an earlier prototype - shows the wiring to pins; 
Hot glue the soldered board to the shim with the
momentary switches aligned with holes
(Click to embiggen)

As a final step for preparing the Button Board, use Loctite (CA) to glue the Button tops to the actuators of the momentary switches:
Momentary Switches in place and Button Tops being added

We'll need some more software packages installed to fully test our circuit, coming up in Install Code and Test

S2 Spa Soother - Install Code and Test

If you followed along with the Adafruit tutorial  on getting Pi Zero PWM audio, you should already have sound tested and working out from your circuit by this point.

Again, we are using SSH to our Pi Zero.

Now, on the Pi Zero install mpd, the music player daemon and its client, mpc:

 sudo apt-get install mpd mpc  

MPD (the Music Player Daemon) is a good choice to play sound files - it handles a lot for you. Another choice would have been pygame.

To add the sound files to the mpd system, I copied them over like so, from the linux computer I had created them on, where Music is on another computer where I stored the sound files in my source home directory:
 sudo scp username@192.168.0.nnn:Music/sound1.wav /var/lib/mpd/music/sound1.wav  

After you have copied over your sound files, be sure to do:
 mpc update  
This will add the sound files to the mpd database.

To make a playlist:
 sudo nano /var/lib/mpd/playlists/mylist.m3u  

Then add your sound files in the order you expect them to be associated with the buttons:

Note: these will be the actual names used by mpc to play the files, so they have to match the code in the spa_soother.py script!

Save the file with CTRL-O, CTRL-X.

To test out your rig, wire up the PWM/LM386 to the Pi Zero, attach a speaker and do:
 mpc clear  
 mpc load sound1.wav  
 mpc play 1  

The volume may be too high/too low. Adjust with:
 mpc volume 75  
Where the number after volume is the new volume setting.

If that works, you can move on to installing the python script for sound from the github repository.

From the pi user home directory:
 mkdir scripts  

 cd scripts  

 mkdir python  

and download the python script spa_soother.py there.

What's Going On in the Code:

How the songs are played with a button press:

You can set the volume globally for all the sound files with the potentiometer on the LM386 output. To fine tune the volume for each sound, you can use the command:
exec_command("mpc play 1") 
exec_command("mpc volume nn")  

Once you are satisfied the software is working, you can set the python script to start at boot time.

Note: Raspbian Jessie uses "systemd". If you are used to using "systemv", the start-up procedure has changed.

How To Autorun A Python Script On Boot Using systemd

Edit a new file:

sudo nano /lib/systemd/system/spa_soother.service

Inside the file add the following contents:

Description=S2 Spa Soother

ExecStart=/usr/bin/python /home/pi/scripts/python/s2_spa_soother.py


Change permissions:
sudo chmod644 /lib/systemd/system/spa_soother.service

Reload and enable:
sudo systemctl daemon-reload
 sudo systemctl enable spa_soother.service

Check the status of the service:
sudo systemctl status spa_soother.service

For wiring this up, I used a +5V from the Button Power Rail (explained previously) and  GND  (any of 4 possible) from the Pi Zero to the PWM/LM386 board rail. The Speaker input from the Pi Zero comes from Board Pin 33. Instead, you could use Board Pin 12. It won't matter, our sound file is mono only.

Here's a pinout guide to the Pi Zero:

Shutdown Process

  • Timer expires on Pi Zero; you can change this to any interval you like but it defaults to 20 minutes
  • Pi Zero sends Serial message to RainbowDuino, "Shutdown"
    • Pi Zero issues a "sudo shutdown -h now" for itself
  • RainbowDuino listens for "Shutdown" message
    • When received, RainbowDuino checks for 30 seconds of elapsed time, enough for the Pi Zero to safely shutdown
  • RainbowDuino issues a HIGH via pin A2 connected to the OFF section of the Pololu switch
    • Pololu switch kills power for the RainbowDuino (and the Pi Zero attached to it) and goes into very low quiescent mode

The TX0 (Board Pin 8) from Pi Zero goes to the RXD pin on the RainbowDuino, on the "5V ONLY" Area shown below. The Pi Zero will use this to tell the RainbowDuino it is shutting down, and that the RainbowDuino should wait 30 seconds, then turn Power OFF at the Pololu switch. The RainbowDuino will do this by writing HIGH to its own A2 pin. A2 is connected to "OFF" on the Pololu switch. A voltage > 1V to OFF on the switch kills the power to both the Pi Zero and the RainbowDuino.

Tip: Add a right-angle header to the pin connections at location J8 (pins A0 to D3) for easy connection with female jumper wires.

RainbowDuino Pin Connections

RainbowDuino Connections:
From the 5V ONLY Area, to power the Pi Zero:

  • 5V RainbowDuino to pin 2 of Pi Zero
  • GND RainbowDuino to pin 6/9/14/25 of Pi Zero

To upload the S2_Spa_Soother_Spin.ino file to the RainbowDuino:

  • Make sure the USB/HOST switch is set to USB
  • In the Arduino Board description, use "Arduino Duemilanova or Diecemila" 
  • Make sure the TX0 from Pi Zero is not connected during upload, then reconnect to run the sketch
  • Tip: Insert the Geeetech LED matrix with writing on the side toward the RED/BLUE silk screen, same side as green screw terminal power blocks
Power Connections
I used a 9V/1A power supply from Adafruit wired directly to the Pololu VIN through a 2.5mm power jack. The VOUT connection is wired to the 6.5V-9V power terminal block on the RainbowDuino. 

5V power and GND is daisy-chained from the 5V ONLY Area on the RainbowDuino to the Pi Zero.
Thus, when the RainbowDuino issues an OFF to the Pololu switch, both devices are powered down.

DO NOT attach ANY 5V connected devices to 6.5V-9V power. You will emit the Magic Blue Smoke! 

When you're satisfied everything is working properly, move on to the Final Assembly...

S2 Spa Soother - Final Assembly: Build the Box, Part 2

We're now ready to finish the box assembly that started in Build the Box Part 1. We need to build from the back (speaker) panel up:

Option: I glued the Top of the box to the Back/Speaker Plate, don't know if that was a good idea or not. It makes assembly easy but taking the box apart, not so much. You may find that the Top and Back fit tightly enough to the Front of the Box that you don't need to glue them together. I leave it to the individual maker to decide that.
  • Screw in 0.25in 4/40 standoffs to the Pi Zero and then screw into the back panel. 
  • Connect the Button Board to the pin locations on the Pi Zero. 
  • Connect Sound Output, Gnd and 5V from the Button Board to the LM386:

  • Glue in the Speaker and Connect to LM386
  • Solder the Power Plug
  • Glue Pololu Switch down and Connect to Power Plug
    • +V INPUT is at the TOP of the Pololu in this photo
    • I used Female headers on Pololu Switch for easy connection

Pololu Switch Layout - Reverse/Back Shown Here

  • Add 0.25in 4/40 Standoffs to the RainbowDuino
  • Cut 22AWG to length for RX/5V/GND Connections OUT from 5V Area
  • Connect 9V/GND VOUT from Pololu Switch to 6.5-9V Area on RainbowDuino
RainbowDuino Connections to Pi Zero Pins
  • Screw Down RainbowDuino to Back thru Standoffs
  • Pi Zero Wires Connected
  • RainbowDuino pin A2 to Front momentary LED: 
    • Solder on 100 Ohm Resistor
  • RainbowDuino pin D3 to Pololu switch OFF
  • Power IN from Pololu to 6.5-9V Area

Installing the Geeetech LED Matrix

  • Glue Front momentary switch into its hole: CA
  • Connect Jumpers as shown
Jumper Connections for Front Combo LED/On-Switch

After you have all the jumpers connected, it's a good idea to do a final test to see that everything is working, all jumpers are solidly connected and that there aren't any space conflicts. 

When you've got it all put together in the box, relax and enjoy the Spa Soother....

Feb 1, 2016

Heartbeat LED

Here's a quick and easy Valentine for someone special, or a gift for a loved one anytime. This is  a small desktop stand for a heart-shaped acrylic piece. The heart is laser-etched with your choice of sentiment  and lit with an LED that simulates a heartbeat. You'll need access to a laser cutter for cutting and etching the project, or send out to a laser-cutting service such as Ponoko. Some soldering is also required.


  • laser cutting (or know how to spend money to buy laser cutting)
  • crafting/gluing
  • heat bending
  • very minimal soldering


  • 12in x 12in x 1/8 in sheet of acrylic, any color - but fluorescent red really shows off the etching; $8.00 at TAP Plastics
  • an Arduino-compatible microcontroller; almost any will do: I prototyped on an Adafruit Pro Trinket 3.3v but did the final build on a DigiSpark (ATTINY) board; Adafruit also makes an inexpensive ATTINY-based line of Trinkets
  • 1 Lego small "box" piece (with "pipe" column in center) color-matched to your acrylic, as a light baffle for the LED. Or anything you can rig that will block the light from direct view and focus it on the heart point.
  • 1 Super-Bright White LED; mine was 30,000 mcd (yikes!); Warning- these can cause eye damage it you look directly into them
  • 1 resistor matched to your LED to limit current; mine was 560 or 620 Ohms. Follow the spec sheet for the LED.
  • 22 AWG wire, a piece of 4in solid core will do
  • Loctite Extra Time Superglue (I also used sugru)
  • Optional - a USB extension so you're not plugging and unplugging the device, possibly breaking it
To make the stand for the heart cutout, you'll need some way to heat-bend the acrylic. Alternatively, you can find some other mount like a small shadow box frame, or make the heart into a pin/brooch. Wear your heart on your sleeve!

Software on github:
  • Arduino sketch to blink the LED timed like a heart; original by Paul Badger of Modern Device
  • Drawing file for cutting the acrylic
  • Download click HERE
To get the best refracted light from your heart, etch the BACK side of the acrylic. Mirror your text on the etching so that, when it's turned the right way around, it will read correctly.

Formech Heat Bender with Heartbeat LED Base below heat strip 

After you cut your acrylic, you'll need to heat the base/stand and bend "legs" at a 90 degree angle. There are lines etched on the base to help guide you where to heat the plastic and bend it. I used a Formech Heat Bender and an angle jig at TechShop SF to make the bends. On the Formech, heat the acrylic for about 2.5 - 3 minutes after the Formech reaches working temperature. The acrylic will be ready to bend when you can flick the end (closest to the heated etch) up easily with your finger.

Acrylic will move up easily with gentle finger pressure when ready for bending

Immediately place in the forming jig. Press the end of the acrylic up while firmly holding the body in the jig. Keep pressing/holding while the plastic becomes merely warm  to the touch, about 3 minutes or so. Repeat heat/bend on the other end of the base.
Base in Bending Jig

Load up the sketch on your target platform and test it. You can experiment with changing a couple of parameters to get the heartbeat rhythm you like.

Use a 1/8in drill bit to drill out the bottom of the Lego piece. I used a rotary tool (similar to a Dremel) at low speed and the Lego piece cut very easily. Play around with the placement of the point of the heart through the base slot into the Lego piece, with the LED inserted into the Lego from the bottom and lit. You can hold the Lego in place temporarily with a piece of Scotch tape.  I saw best results with about a 20-30 degree tilt backwards in the base, with the the text facing me. Now use superglue to attach the Lego with the drilled side down. Make sure the LED hole in the Lego lines up well with the heart slit in the base. Allow the glue to cure overnight for best strength.  

Once set, redo the placement of the heart into the Lego with the LED to confirm - you're going to be gluing this. When you get the desired results, fix at that angle by applying glue where the heart meets the base. In my case, even when fully cured, this didn't feel too stable. So, I added some infill of sugru in the spaces and allowed to cure overnight.

Bend the LED leads to face where you're attaching the microcontroller

Insert the LED into the glued Lego once cured. Bend the leads of the LED about half-way down so that they can face the place where you're going to put the microcontroller. You can solder the limiting resister directly to the PWM pin you are using on your microcontroller, covering with heat shrink or sugru for insulation. Solder other end to the positive (long) lead of the LED. Then, solder a short piece of wire to GND on your microcontroller and the other end to the remaining (negative/short) LED lead. Test it out again before final attachment of the microcontroller and LED.

LED soldered to Digispark before final assembly

When you're happy that everything works, glue or sugru the micro to the base so it can be attached with a USB cable easily. Fasten the LED in place with glue or sugru. Again, let cure overnight.

Now, enjoy your new beating heart...