04/06/2016

PROJECT: Wedding Announcement Puddycats


Good news! The fiancée and I are getting married sometime in 2017 :D

To announce this awesome turn of events her and I decided to make a cool little gift for our family. In the end the trinket ended up being a couple of 3D printed cats that were lit up by an ever-changing rainbow from two RGB LED's. 

Circuit Design

Schematic wise the project is quite simple, just a single ATtiny25 microprocessor that "powers" some Red Green Blue (RGB) LED's. When I say power I really mean it provides a Pulse Width Modulated (PWM) sink for the LED's since they are common anode (notice how the anode of each LED is connected together), we can vary the brightness of each colour by setting the PWM duty cycle which in the end allows us to pretty much cycle though the colours of the rainbow (plus pink). Also all of this is powered by a single CR2032 battery as seen by the following schematic
Since the circuit is powered by a single coin cell battery I had to be somewhat efficient with the design, the end goal was to make the trinket last for at least a day. With that known I started looking for RGB LED's that:
  1. Were easy to solder by hand
  2. Had a good brightness at a forward current of ~2mA 
  3. Had a forward voltage drop of <2.9V for the Blue and Green LED, this is because a CR2032 battery has a nominal voltage of 3V
After a few orders from Element14 the best option seemed to be the ASMB-MTB1-0A3A2 

Next I picked the current limiting resistors (R1➛R6) such that the forward current through each LED (at max brightness) was ~2mA. As trivial as it sounds there is no simple solution to this problem, as the battery voltage is not constant throughout it's discharge cycle (it gets lower the more depleted it becomes) so finding a resistor that would limit the current to 2mA through the discharge process is impossible. After juggling factors like LED brightness, trinket lifetime, and average battery voltage I came up with an "optimal" resistance of 523Ω for the Red LED, and 75Ω for the Blue and Green LED.

Lastly when making any circuit that switches ON/OFF continuously (this is what the microprocessor does in this case) it's always a good idea to use some decoupling capacitors on the power rails. In my case since the ATtiny25 was output a bunch of PWM signals to be on the safe side I used two decoupling capacitors C1 & C2, both of which were the typical 100nF X7R ceramic type.


PCB Layout

Another goal was to have the trinket small in size, preferably as wide as the CR2032 battery holder. To achieve this I had to move to Surface Mount Technology (SMT/SMD), something that was quite new to me since all my previous projects utilized Through Hole components. With the packages specified I then designed the PCB in Altium, laying out the components in the following manner:
NOTE: I made all the footprints using Library Expert Lite, where as the 3D models were mostly simple body extrusions made in Altium. Come to think of it I should have used 3DContentCentral as they have all sorts of 3D models available at no cost.

Next step was getting the PCB's made, for this I went to PCBshopper to compare various fabrication houses. In the end I decided to go with OSHpark who are recognized for their quality and have the very distinctive purple/gold look. 

To get the boards made you need to supply the fab house with Gerber & Drill files for your design. Basically Gerber files define what each layer of the PCB contains, be it numbering/pictures on the top/bottom surface, tracks of copper, or solder mask. Whereas a Drill file tells the fabricator what drill size to use for each hole on the PCB. With OSHpark since I requested a simple two layer board the files I had to provide were thus:
  • Top overlay/silkscreen (GTO)
  • Top solder mask (GTS)
  • Top copper layer (GTL)
  • Board outline on mechanical layer (GM1)
  • Bottom copper layer (GBL)
  • Bottom solder mask (GBS)
  • Bottom overlay/silkscreen (GBO)
  • Drill location & size (TXT)
NOTE: Here I used the 1st Mechanical layer (GM1) to define the board outline. You can use any layer for this BUT make sure to not to use the same layer for other things like annotation, otherwise the fab house might get confused with the intended board shape... something that I found out the hard way.


Trinket Construction

To make soldering easier I decided to get the YIHUA 858D, a cheap hot air gun made specifically for soldering such small components. Here is a video of me soldering the "jelly-bean" parts with the hot air gun, something that would have taken much longer to had I used the soldering iron.


The rest of the components though small were easy enough to do by hand with the soldering iron.

Next up I printed the trinket body using my Prusa i3v 3D printer; the body consisted of a simple base which hid all the electrical components and two cats which got lit up by the RGB LED's. I should mention that the cat model is not mine and that you can grab it from the designer here. To make the cats hollow and the base filled I had to use two different print settings. For 0mm to 3mm the body (base) was printed with normal infill while for 3mm onwards the body (cats) was printed hollow; all of this was achieved by combining two different print parameters in Simplify3D. If you want the modified cat model you can grab it here.
Also to hold the PCB and 3D printed cats together I used countersunk M2x10mm bolts with M2 nylon lock nuts.


Trinket Programming

Programming the trinket would have been easier had I used a dedicated programming header like this, but since space was a priority I skimped on the header and instead used a SOIC chip clip. To give you an idea of how the programming went down have a look at the following video:


One of the interesting/unintended things I found was that an unprogrammed board would light the LED's red in colour, giving a neat way of checking the microprocessor status on each PCB.

The code for the above "rainbow scroll" effect can be seen below. If you plan to upload the code using an Arduino as the ISP (like myself) then make sure to grab this ATtiny library; if you want to know why then have a look at this post. To give you a summary the ATtiny easily supports two PWM outputs, if you want three/four (recall this project utilities three) then you need to jump through some hoops to get this functionality, using the above library does this for you and so makes programming a bit easier.

///////////////////////////////////////////////////////////////////////
// Wedding announcement LED's                                        //
//                                                                   //
// PARTY HARD & VapeNash Ya'll                                       //
// Use this atTiny lib: https://github.com/damellis/attiny/          //
//                                                                   //
// ANTALIFE - 20.04.16                                               //
///////////////////////////////////////////////////////////////////////

const int t_delay = 100; //100 seems best
const int pin_R   = 0;   //Red LED on PB0 (pin 5)
const int pin_G   = 1;   //Green LED on PB1 (pin 6)
const int pin_B   = 4;   //Blue LED on PB4 (pin 3)


void setup() 
{
  //Setting up muh e-peenz
  pinMode(pin_R, OUTPUT);
  pinMode(pin_G, OUTPUT);
  pinMode(pin_B, OUTPUT);
}

void loop() 
{
  //RED -> GREEN
  for (int rg = 0; rg <= 255; rg++)
  {
    analogWrite(pin_R, rg);
    analogWrite(pin_G, 255 - rg);
    analogWrite(pin_B, 255); //Blue LED not used so stays OFF
    delay(t_delay);
  }
  //GREEN -> BLUE
  for (int gb = 0; gb <= 255; gb++)
  {
    analogWrite(pin_R, 255); //Red LED not used so stays OFF
    analogWrite(pin_G, gb);
    analogWrite(pin_B, 255 - gb);
    delay(t_delay);
  }
  //BLUE -> RED
  for (int br = 0; br <= 255; br++)
  {
    analogWrite(pin_R, 255 - br);
    analogWrite(pin_G, 255); //Green LED not used so stays OFF
    analogWrite(pin_B, br);
    delay(t_delay);
  }
}

Trinket Testing

Doing a quick test with my uCurrent (red box in photo) showed that the average current draw was around 7mA [I_draw], meaning that on a 240mAh [capacity] CR2032 battery the trinket would last [t_on] for just under a day and a half:

t_on = capacity ÷ I_draw
t_on = 240mAhr ÷ 7mA
t_on ≈ 34hrs

Actual tests showed that on a cheap CR2032 battery the trinket would last for just over a day, mission success :D


Trinket Showcase

Finally here is a video of a bunch of trinkets doing their thing:



UPDATE: A much easier way to achieve something similar is to use a ring-oscillator, like this