04 June 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


10 March 2016

PROJECT: Workbench Upgrade

As expected all good things come to an end, and my once large workbench (or desk) had started to become smaller and smaller the more parts and equipment I gathered; this became very apparent with the addition of a Tektronix 2235 oscilloscope.

Thus I began a month long journey to upgrade my workbench to something more usable, the progress for this is below:





13 December 2015

PROJECT: Solar House

This year my partner and I managed to score some cheap solar powered lanterns along with some flickering LED candles at a garage sale, and with New Years being just around the corner I decided to convert them into a solar powered house with a nifty fireplace.

3D Models can be obtained from here, and build instructions can be found here.

Before I get into the nitty-gritty of things, below is the schematic for this project.


Solar Cells

Prior to actually using any solar cells it always a good idea to characterise them to see how well they perform. To do this I used your typical rheostat to place a variable load across the cell and then measured the developed current and voltage. The circuit for this can be seen below:
Once I had recorded a decent number of point I then plotted the measured current against the developed voltage and this gave me the well known I-V curve:
It should be noted that I excited the solar cells with a 7W LED light bulb and not a calibrated 1sun source, hence what you see is not an indicator of their true performance. Still the curves show that both cells are closely matched in performance (same Voc & Jsc) and so can be easily use in series or parallel configurations. 

Solar LED Lamp Controller, CL0116

It turns out that most cheap solar powered lanterns use a specialised IC (U1, CL0116) to control the charging/discharging cycle of a rechargeable battery (BT1) which is usually a single NiMH cell. From my understanding this IC is basically a switching converter which uses and inductor (L1) to efficiently boost up the voltage and in-turn power an LED; the anode of which would be connected to the LX pin and the cathode to GND. When the IC senses the solar cell is illuminated (can produce power) it enables the charging cycle of the battery, but as soon as light is removed then it starts to discharge the battery by powering the LED.

For some reason this IC is kinda hard to source as I've only seen it available on Alibaba.
EDIT: QX5252 is an alternative part that has the same functions and is much easier to find.

Candle/Flickering LED

If you happen dine out you might have seen LED powered candles which have this neat flickering effect to imitate flame. Well the interesting thing with these candles is that they are usually composed of a single CR2032 battery and what seems to be a single LED, but if you look closer at the LED package you would notice that it also houses a separate IC which controls the flickering effect (here is a really good breakdown of how these work).

These LED's are a bit easier to find and can be sourced from your local 2$ shop or eBay.

Combining It All Together

Now putting it all together sounds like a simple task: connect the two solar cells in parallel to SBAT(1), hook up a NiMH battery to BAT(2), and replace the simple LED with a flickering one.

Sadly trying this proved to be fruitless as it appeared that the output ripple voltage of CL0116 was too great for the LED IC to handle and instead the "flickering" LED stayed a solid colour.
To solve this I tried adding a smoothing capacitor (C1) to reduce the ripple voltage but soon found that using large values (>0.5uF) would completely turn the LED off; I believe this is due to a large inrush current during start-up which in turn causes the output voltage of the converter to collapse (kinda like some switching converter IC's have a maximum output capacitance).
After much trial and error I found that a value between 10-22nF gave the best result. Interestingly choosing C1 as 10nF resulted in a lower drawn current but also increased the chance of the circuit not working when trying a different flickering LED, hence to stay on the safe side 22nF should be chosen.

By simply having D1 in parallel with C1 resulted in a drawn current of around 70mA, a bit too high for my liking as most eBay auctions state that the forward current is 20-30mA. I found that a 10Ω current limiting resistor (R1) does the trick quite well and reduces the drawn current to ~30mA at very little cost to LED brightness. Also strangely enough placing R1 after D1/C1 gave the best results in terms of current draw; I'm in the process of getting an old school analog oscilloscope so hopefully will be able to give a better answer as to why.

Finally placing it all into a 3D printed house gives you something like this:



21 November 2015

PROJECT: Glowing Minecraft Cube

A while back it was my little brothers birthday, and since he is an avid fan of Minecraft I decided to print him a little cube from the game. The only difference with this cube was that it's internal layer was made out of glow in the dark PLA which once energised by and light source would give off a cool glow like so:


Experimenting with different coloured LED's (as the light source) I found that a blue LED gave the best results in terms of resultant glow. Thinking back to my physics classes this makes sense, as the energy (E) of any given wavelength (λ) of light is governed by the equation:


E = h⋅f 

or similarly

E = (hc)/λ


Where h is the planck constant, f is the frequency of light, c is the speed of light in vacuum, and λ is the wavelength of light.
Now if you have a look at the datasheets of a red, green, and blue LED's you would see that the wavelength of each would be roughly 625nm, 525nm, and 465nm respectively. Applying the second equation (with hc being constant) you would see that a light emitted by the blue LED has the greatest energy out of the three, and hence would be preferred choice for energising the luminescent PLA material.

With all that said I made a simple current limiting circuit to drive a blue LED at a forward current of ~220mA from x3 AA batteries, the schematic for this is below:

NOTE: The above circuit is not the best way to limit current flowing thought the LED as any variation in the supply voltage will have a relatively big effect on the forward current. Here is a much more stable current limiter, but you would need to make sure that your Rsense resistor sufficiently rated (think P=(I^2)⋅R).


All of this was then placed into a 3D printed case (which you can get here), in the end giving you something like this:





19 November 2015

PROJECT: 3D Printed Lithophanes


UPDATE: Turns out there is a cool website that can do all the hard-work for you, PrusaPrinters did a very good tutorial on how to use it

So a while back I found out that you could easily use a 3D printer to make a lithophane. For those not familiar with the term think of a solid object that varies in thickness in a particular way that it forms a picture when light in shined though it, giving you something like:


It turned out that my partners birthday was also coming up, so I decided to make a cube which held a number of pictures that would also be illuminated by an RGB LED (see previous post).

The thing that I soon found was that calibrating the printer for making these is quite a project in itself, as it must have taken me at least 20 prints (at various settings) before I could get a reproducible and working piece. But with that said here is how I did it, so that you don't have to suffer as much as I did:
  1. The very first step I'd recommend you do is calibrating your 3D printer, particularly making sure that your steps (X,Y,Z,E) and hotend temperature is within reasonable values. Thomas has a few awesome videos for this.
  2. Once you are happy with your printer download BMP2IGES, a super handy program used to make lithophane STL's.
  3. Before using BMP2IGES know this, the higher the resolution of your picture (pixels wise) the more difficult it will be to print it successfully. For example say I have a 0.4mm nozzle (use a 0.5mm extrusion width) and I want to print a 100mm by 100mm lithophane, what is the maximum resolution image that I can use? Well I found that setting the maximum "pixel" size of the lithophane at half your extrusion width gives good results. So with the 100mm by 100mm example the maximum resolution image I'd use is 400 x 400 pixels [100÷(0.5÷2)].
  4. Next grab the image you want to use and resize it appropriately. Once you've done that open up BMP2IGES and import the image by clicking File -> Open. The picture below shows the parameters that I found to work quite well. Feel free to play around with these though to see what they do.
  5. Having set all that up next create the STL by clicking File -> Save&Calculate -> Save as STL. BUT before using the STL there is a high chance that it has some errors, so use a program like netfabb to repair it (here is a good video of how to repair STL's).
  6. Now that you have your good STL file import it into your favourite slicing software (I use Simplify3D myself). First major change you need to do is make the infill solid, as we don't want your fancy infill pattern interfering with the picture. I find that with my printer making the infill rectangular with a fill percentage of 85% does the job well. Also some people say that printing your infill at a lower angle (<30°) gives better results, but I found that 45° works just fine. Lastly the slower you print the better lithophane will come out to be, for me 50mm/s gave good results. Here is pictures of my printing settings, but since optimal values differ from printer to printer it's up to you to have a play around. 
  7. Finally hit print and hope for the best ( ͡° ͜ʖ ͡°)


If you want to take this lithophane business one step further you could also make an enclosure box and place an LED in the centre to light it all up, kinda like the picture below:


You can get the model for the enclosure from here. I've also included the circuit schematic and code below. For my project I decided to use the cheap and plentiful ATtiny13 (which I programmed via my Arduino UNO with the help of this tutorial), but you can use any AVR micro you want as long as it has x3 PWM outputs, x1 analog input, and x1 digital input.

NOTE: I found that limiting the forward current to ~220mA gives the best compromise between brightness and heat produced. 


/////////////////////////////////////////////////////////////////////////////////////////////
// RGB LED control - v1.2                                                                  //
//                                                                                         //
// A simple program for controlling an RGB led with a single potentiometer.                //
// As per I/O pins below, the RED pin of the RGB LED is connected to pin #9 of the Arduino //
// GREEN pin to pin #10, and BLUE pin to pin #11. Also the output of the potentiomenter is //
// located on pin #A0.                                                                     //
//                                                                                         //
// ANTALIFE - 16.08.15                                                                     //
/////////////////////////////////////////////////////////////////////////////////////////////

//MUH I/O PINS
int R_pin       = 1;  //9  on Arduino
int G_pin       = 0;  //10 on Arduino
int B_pin       = 4;  //11 on Arduino
int RGB_pot_pin = 3;  //A0 on Arduino
int Rainbow_pin = 2;  //8  on Arduino


//MUH VARIABLES
float theta       = 0;
int colour        = 0;
int rainbow_delay = 0;

void setup()
{
  //MUH OUTPUTS
  pinMode(R_pin, OUTPUT);
  pinMode(G_pin, OUTPUT);
  pinMode(B_pin, OUTPUT);
  pinMode(Rainbow_pin, INPUT);
}


void loop()
{
  //If rainbow mode enabled scroll through the rainbow ;^)
  while (digitalRead(Rainbow_pin) == LOW)
  {
    for (float RAINBOW = 0; RAINBOW < 256; RAINBOW = RAINBOW + 0.5)
    {
      //If rainbow mode disabled stop animation
      if (digitalRead(Rainbow_pin) == HIGH)
      {
        break;
      }
      MUH_colour(RAINBOW);
      delay(analogRead(RGB_pot_pin) + rainbow_delay);
    }
  }
  
  //If rainbow mode not enabled simply display the set colour
  theta = analogRead(RGB_pot_pin) / 4;
  MUH_colour(theta);
}

void MUH_colour(int angle)
{
  //This fucntion converts the given angle to a visible colour on the colour wheel
  //with RED being 0deg, GREEN being 120deg, and BLUE being 240deg
  //RED TO GREEN [0deg -> 120deg OR 0 -> 85]
  colour = (6 * angle) % 255;
  if (angle <= 42.5)
  {
    RGB_write(255, colour, 0);
  }
  else if ((angle > 42.5) && (angle < 85))
  {
    RGB_write((255 - colour), 255, 0);
  }
  //GREEN TO BLUE [120deg -> 240deg OR 85 -> 170]
  else if ((angle > 85) && (angle < 127.5))
  {
    RGB_write(0, 255, colour);
  }
  else if ((angle > 127.5) && (angle < 170))
  {
    RGB_write(0, (255 - colour), 255);
  }
  //BLUE TO RED [240deg -> 360deg(or 0deg) OR 170 -> 255(or 0)]
  else if ((angle > 170) && (angle < 212.5))
  {
    RGB_write(colour, 0, 255);
  }
  else if ((angle > 212.5) && (angle < 255))
  {
    RGB_write(255, 0, (255 - colour));
  }
}

void RGB_write(int R_val, int G_val, int B_val)
{
  //A simple function that displays the desired LED colour by setting the duty of the
  //PWM on each RGB LED
  analogWrite(R_pin, R_val);
  analogWrite(G_pin, G_val);
  analogWrite(B_pin, B_val);
}

And finally here is a video of it all working :D




09 August 2015

RESEARCH: Controlling an RGB LED with a potentiometer


One of my upcoming projects will require me to control an RGB LED with a single potentiometer.
Scouting the internet for relevant code came out a tad fruitless as most code had poor transitions between each RGB value, as you could see each LED momentarily turning OFF between major transitions.


/////////////////////////////////////////////////////////////////////////////////////////////
// RGB LED control - v1.1                                                                  //
//                                                                                         //
// A simple program for controlling an RGB led with a single potentiometer.                //
// As per I/O pins below, the RED pin of the RGB LED is connected to pin #9 of the Arduino //
// GREEN pin to pin #10, and BLUE pin to pin #11. Also the output of the potentiomenter is //
// located on pin #A0.                                                                     //
//                                                                                         //
// ANTALIFE - 09.08.15                                                                     //
/////////////////////////////////////////////////////////////////////////////////////////////          

//MUH I/O PINS
int R_pin       = 9;
int G_pin       = 10; 
int B_pin       = 11;
int RGB_pot_pin = 0;

//MUH VARIABLES
int anal_val    = 0; // ;^)
int theta       = 0; 
int colour      = 0;

void setup()
{
  //MUH OUTPUTS
  pinMode(R_pin, OUTPUT);
  pinMode(G_pin, OUTPUT);   
  pinMode(B_pin, OUTPUT); 
}


void loop()
{
  //Using an RGB circle with RED being 0deg, GREEN being 120deg, and BLUE being 240deg
  //Here we map the 360deg circle to a value between 0 and 255 (aka the duty of the PWM)
  theta           = analogRead(RGB_pot_pin)/4;
  colour          = (6*theta)%255;
  
  //RED TO GREEN [0deg -> 120deg OR 0 -> 85]
  if (theta <= 42.5)
  {
    RGB_write(255,colour,0);
  }
  else if ((theta > 42.5) && (theta < 85))
  {
    RGB_write((255-colour),255,0);
  }
  //GREEN TO BLUE [120deg -> 240deg OR 85 -> 170]
  else if ((theta > 85) && (theta < 127.5))
  {
    RGB_write(0,255,colour);
  }
  else if ((theta > 127.5) && (theta < 170))
  {
    RGB_write(0,(255-colour),255);
  }
  //BLUE TO RED [240deg -> 360deg(or 0deg) OR 170 -> 255(or 0)]
  else if ((theta > 170) && (theta < 212.5))
  {
    RGB_write(colour,0,255);
  }
  else if ((theta > 212.5) && (theta < 255))
  {
    RGB_write(255,0,(255-colour));
  }
}


void RGB_write(int R_val, int G_val, int B_val)
{
  //A simple function that displays the desired LED colour by setting the duty of the
  //PWM on each RGB LED
  analogWrite(R_pin, R_val); 
  analogWrite(G_pin, G_val);
  analogWrite(B_pin, B_val);
}


So after having a look how an RGB colour wheel works (http://www.colorspire.com/rgb-color-wheel/) I decided to write a simple function myself, thus giving the code below:
To give a quick explanation of the code look at the picture below. You see how as you move around the colour wheel (or change the theta angle) the R G B values of the LED change accordingly giving you a certain colour. One other thing to note is that only two values are being changed at any given point, that is from 0deg to 120deg only the R and G values change while B stays constant (you can witness this by playing around with the colour wheel link above).
Knowing all this the above code maps the angle theta to a certain mixture of PWM duty on each LED, in the end giving you a pretty display of colours.


EDIT: Turns out humans see the brightness of colours differently, here is a good post about how this would have to be accounted for in software.

Just a simple blog for somewhat simple projects of mine.