Posts tagged ·

leds

·...

Decorative LED light bulbs

Comments Off

In a quest to create a light-arrangement similar to the photo below, I’ve tried out a number of LED filament light bulbs. They are all European socket E27 220 volt, but with variations on imitations of old style Edison incandescent bulbs, using LED filaments. Some give a normal bright light, while others are warm and dim. But first, some specifications.

An alternative to these LED bulbs might be old fashioned actual Edison incandescent bulbs. Although they were banned for sale in Europe a few years ago, they are still offered from AliExpress, at reasonable prices. It might be worth trying out later. The downside is of course the energy use, at about ten times LEDs, and having to order your light bulbs from China by post.


 
 

Brightness

The brightness of a light source is expressed in lumen, or luminous flux, where 1 lumen is equivalent to a single candle, while 100 lumen is 100 candles. However, beyond a few candles, it’s difficult to have an intuition about what the numbers mean. Here’s a rule of thumb for typical light bulb ratings, including those discussed further down:

  • 150 lm: very dim and dark; nice for decoration, but impossible to read in this light.
  • 250 lm: still dark, OK for dim lamps.
  • 400 lm: typical living room light, but would need a handful to light a room.
  • 900 lm: excellent reading light, but typically too bright for decoration.
  • 1400 lm: excellent working light, bright bathroom light.
  • 4000 – 8000 lm: total light in a well lit kitchen or bathroom (depending on size of the room).

Lumen add up linearly from multiple light sources, and a typical kitchen or bathroom would use multiple high-powered bulbs which add up to 4000 – 5000 lumen in a concentrated arrangement. A cosy living-room could have something similar, but typically scattered about over more and lower powered sources.

A dimmer will influence the lumen of a bulb. If it is compatible with a dimmer, it can output less lumens than its normal rating. However, dimming LEDs is not trivial, and will often cause flicker. Even though it might not be visible to the human eye, it will quickly disturb a camera, webcam or mobile phone. The Ikea bulb in this test experienced this issue even without a dimmer involved.


 
 

Colour temperature

The colour of a light source is expressed in kelvin, and often more red colors is referred to as warm, while more blue is said to be cold, with standard white light somewhere in the middle. The chart below gives a brief overview, with further examples here.

Again, it’s not easy to have any intuition about the numbers, so here’s some guidelines based on the bulbs in this article. Also note that different manufactures apply these values differently, so 3000 K might not always give the same colour. In particular, cheaper china-modules will often lower the advertised temperature, to not come off as cheap neon-light products, but will sometimes disappoint when plugged in.

  • 1800 K: Very red, like a candle light; OK for decoration, but uncomfortable to read or focus.
  • 2000 K: Nice and decorative, but not good for reading.
  • 2200 K: Approaching normal living room light.
  • 2700 K: Almost normal white light, good for living room.
  • 3000 K: Typical normal white reading and working light.
  • 5000 K: Typical fluorescent white light, still for household use.
  • 7000 K: Blue hospital light.

Different colours from different light sources mix very poorly. One of the lamps will quickly feel out of place: Think for example of a cool bright fluorescent light suddenly being turned on at a cosy cafe; next you’ll expect to be thrown out. Or a red lamp in an otherwise bright office-lit room; is somebody growing weed in that corner? Worse than these scenarios yet, is putting cool and warm coloured bulbs next to each other in the same lamp. It simply looks as if somebody didn’t stock up on the right bulbs and had to take what was available, or maybe bought the wrong kind from AliExpress. Speaking from experience.
 
 

 
 

Shapes

There are lots of different types of bulbs, sizes and shapes. Courtesy of mapawatt, here’s an overview of different kinds. The A (normal) and G (globe) annotation you sometimes see used on products. The sizes in America are in 1/8 inches, while millimeters is used in Europe. E.g. an A19 is an A shape bulb which is 2.375 inches in diameter (19/8). The A19 size happens to be the standard light bulb size, for example as seen in the GO/ON and Osram 11 W bulbs below. 2.375 inches is 60 mm, which is the diameter of the those bulbs at its widest point, thus the European marking will be A60. Another common size is the G30, a globe of of 25 / 8 inches or 95 mm, which is the shape of the two large bulbs at the end of this test. Finally, the “oblong pear” is common, as ST64 (mm) or ST20 (1/8 inches).

Be ware, sometimes the size annotation is mixed up or combined; like in this offering, which is marked as both as G30 and G95, or this, where it’s called G40, but is in fact a small 40 mm or 1.5 inches bulb. Here is a really large G40, at 5 inches or 125 mm, also known as G125.

Different sizes and shapes go well together, as seen in the photos below.
 
 

 
 

Arrangement, wire and fixtures

When it comes to the arrangement of such a setup, there are many ways of creating an interesting look. Some go for an orderly symmetric shape, which makes it look like a chandelier, while others are intentionally disorganized and scattered at different heights and positions. In between, there’s the “plank” instillation below, which uses a dark wooden board as the mounting-point, but still has many different sizes and heights.

To go with the bulbs, the wire and fixtures also become very visible parts. The textilkabel-shop in Germany sells every kind of fabric coated lamp wire imaginable, in colours types, and by the meter. Then there’s fixtures, and these classic styled sets look nice, also pictured below.


 
 
 
 

Ikea Lunnom LED, 400 lm, 4.2W, 2200K

Price: €8.50
Watts: 4.2 W
Brightness: 400 lm; good light
Color: 2200 kelvin; yellow
Socket: E27
Size: 60mm x 118 mm
Shape: A; standard. A60 / A19
LED filaments: 4 x 4cm
Dimmable: yes
Camera flicker: yes
Cosy light: no
Reading light: yes, but dim
Working light: no

Ikea’s standard filament LED bulb an A60, but slightly longer than a normal sized light-bulb, however will still fit in most lamps. It gives good light, but too warm and yellow for reading more than a page. The glass is light yellow-tinted. Still, it is also too bright to look at directly, so as decoration it would have to be high in the ceiling to avoid accidental stares.
It is rated as dimmable, however, through the camera view-finder, it was the only bulb in this test which flickered even without any dimming socket.

  

GO ON!, 2x LED bulbs, 470 lm, 4.4W, 2700K

Price: €3 (2-pack for €6)
Watts: 4.4 W
Brightness: 470 lm; good light
Color: 2700 kelvin; normal
Socket: E27
Size: 60mm x 104 mm
Shape: A; standard. A60 / A19
LED filaments: 2 x 6cm
Dimmable: no
Camera flicker: no
Cosy light: no
Reading light: OK
Working light: no

A normal sized light-bulb for drop-in replacement in most lamps. The light is close to standard white, with a hint of yellow. At 470 lumen, it is bright enough for light reading. However, it is also too bright for decorative use, and its two filaments and standard shape is not too inspiring.
At €6 for a 2-pack, or only €3 each, it’s the cheapest bulb in this test. If it lives up to its 15.000 hours rating, it could be an excellent bulb to stock up on for living-room use, any maybe dim outdoor light.

  

Osram, pear, 470 lm, 4W, 2700K

Price: €10
Watts: 4 W
Brightness: 470 lm; good light
Color: 2700 kelvin; normal
Socket: E27
Size: 64mm x 143 mm
Shape: ST; oblong pear. ST64 / ST20
LED filaments: 4 x 4cm
Dimmable: no
Camera flicker: no
Cosy light: no
Reading light: OK
Working light: no

An oblong pear shaped large bulb ST64, so potentially decorative. However, the light is close to standard white, and at 470 lumen, it is bright enough for light reading. However, might also be too bright for decorative use. Maybe it could be nice inside a tinted glass enclosure, like a large bottle or vase.

  

Osram, bright, 1420 lm, 11W, 2700K

Price: €13
Watts: 11 W
Brightness: 1420 lm; very bright
Color: 2700 kelvin; normal
Socket: E27
Size: 60mm x 105 mm
Shape: A, normal. A60 / A19
LED filaments: 8 x 6cm
Dimmable: no
Camera flicker: no
Cosy light: no
Reading light: yes
Working light: maybe

At 1420 lumen, this bulb is extremely bright, and the packing claims the equivalent of a 94 W old style incandescent bulb, while this LED bulb uses only 11 W. It is so bright that looking directly at it for only a second will give black spots, so it has to be used with a lamp screen. It is not rated as compatible with dimmers. It is normal A60 sized, so will fit in any standard E27 socket lamp.
What’s odd, is that it’s only 2700 kelvin, which means it gives a warm light like the others. Thus, it will make pages of a book somewhat yellow, and is not well suited for a working light. (In comparison, the Osram Classic A Eco Pro 57 W halogen bulb is around 3000 kelvin, and gives excellent reading light). Maybe it could work as normal light in a large room, where it’s located high up in the ceiling. Alternatively, in a decorative screen, like the Arab perforated brass lamps.

  

Micasa Lines & Curves, decorative pear, 140 lm, 4W, 2000K

Price: €21
Watts: 4 W
Brightness: 140 lm; dim
Color: 2000 kelvin; warm
Socket: E27
Size: 64mm x 138 mm
Shape: ST; oblong pear. ST64 / ST20
LED filaments: 2 x 10cm curved
Dimmable: yes
Camera flicker: no
Cosy light: yes
Reading light: no
Working light: no

Moving on to the cosy and decorative bulbs, this is an oblong pear shaped large bulb, with a warm dim light. Its two long filaments are shaped in curves, and creates a nice pattern. The smaller “threads” in the center of the bulb in the picture to the right are reflections of the filaments. With its tinted glass, it looks interesting also when turned off.
At only 140 lumen, it is the darkest bulb in this test, and is far to dark for reading. However, it is slightly cooler than the Star Trading bulbs below, so could work well in a living-room or bedroom setting. It is dimmable, if an even fainter light is required, but will probably induce camera flicker (not tested).

  

Star Trading, red dark pear, 240 lm, 3.8W, 1800K

Price: €21
Watts: 3.8 W
Brightness: 240 lm; dim
Color: 1800 kelvin; red
Socket: E27
Size: 64mm x 142 mm
Shape: ST; oblong pear. ST64 / ST20
LED filaments: 6 x 6cm
Dimmable: yes
Camera flicker: no
Cosy light: yes
Reading light: no
Working light: no

At only 1800 kelvin, the Star Trading bulbs are the warmest of this test. In fact, it is so red, it is almost uncomfortable to try to focus on anything in this light. Reading is almost impossible. It should work well as in a cosy setting, as bar light, windows light. And it is dimmable if an even dark setting is required. With its tinted glass and oblong pear shape, it is decorative also when turned off.
However, at €21 it’s a very expensive bulb, so you’d probably only get a few. Then again, it claims a 15.000 hours service life, and if used at home for a couple of hours each day, that would mean at least 13 years of use. In a bar or cafe setting, or as a decorative window light, with some 10 hours daily use, it would go down to about four years.
It is also available in a 140 lumen version, with the same 1800 kelvin, and similar price.

  

Star Trading, red dark globe, 240 lm, 3.8W, 1800K

Price: €21
Watts: 3.8 W
Brightness: 240 lm; dim
Color: 1800 kelvin; red
Socket: E27
Size: 95mm x 137 mm
Shape: G, globe. G95 / G30
LED filaments: 6 x 6cm
Dimmable: yes
Camera flicker: no
Cosy light: yes
Reading light: no
Working light: no

This is bulb has the same technical specs as the pear above, and in fact the only difference is the large globe shape of its outer tinted glass. It is as dark and red, and would work in a similar cosy setting. The price is the same and the service life is the same.
What really sets it apart is the large globe. It looks fun when lit, and interesting when off. Like the pear above, it is meant to be used without a lamp or cover, unless it’s a clear glass lamp, maybe. It is the right design for its purpose. The only problem I could see, is that with its large upper surface, it will get dusty, so might need to be cleaned regularly.
This one is also available in a 140 lumen version, with the same 1800 kelvin, and similar price. In addition, there’s an even larger version, G125 I believe, with otherwise similar specification. However, it’s almost €30.

  

YWXLight, LED string globe, 200 lm, 2W, 3000K

Price: €6
Watts: 2 W
Brightness: 200 lm; dim
Color: 3000 kelvin; somewhat cool
Socket: E27
Size: 95mm x 137 mm
Shape: G, globe. G95 / G30
LEDs: string of 15 – 20 small LEDs
Dimmable: no
Camera flicker: no
Cosy light: decorative
Reading light: no
Working light: no

This bulb stands out in that it does not use LED filaments, but instead has packed a string of about 15 LEDs inside a globe bulb, of the same size as the Trading Star above, to create a Christmas-like decoration. It’s an innovative “China” LED decoration from DealExtreme, and even comes in a colored version for even more party atmosphere.
At 3000 kelvin, it is slightly cool, but the decorative presentation makes up for it. It does not make for any good reading light, but as a window lamp it would be fun. At only 2W it can run all night. The LEDs are likely to work for years; often it’s the electronic of the driver board which wears out first.

Comments Off

DIY Arduino Debug Shield

Comments Off

Debugging with LEDs; it’s probably even more primitive than debugging with printf statements. However, to get a very immediate feedback on what’s happening, or which pins are in use, it can be useful. So what better way then than a ~$2 homemade shield to pop on top of your existing project.

DealExtreme supplies all the parts needed: A versatile prototyping shield board with holes and wires in sensible locations; a bag of assorted LEDs; resistors; and header pins. (The board and headers in this project used 6x and 8x header pins, to fit with the older Duemilanove. The Uno another other boards have slightly different pin layouts, so plan ahead).

Now, I’m not an expert at soldering, nor product design, but this shield does the job, and already helped in programming my next project. Lesson learnt: Lay out the components all the way before heading off with the iron. I should have gone with the 3mm LEDs all the way. Or, maybe surface mount could have worked. Next time.

Comments Off

3x3x3 LED cube with fewer wires

Comments Off

A few weeks ago, I mentioned that it would be possible to optimize the number of wires and components needed for a 3x3x3 single colour LED cube by using “the 9th bit” (the output pin, intended for daisy chaining) on a 8 bit serial in / parallel out shift register. Other examples of the 33 cube I’ve seen are simply pulling 12 wires (9 LEDs on each layer, and 3 layers) back to the Arudino. At that scale, it is of course feasible, but still, when it’s possible to get by with half, why not? So I put together a small 33 cube doing just that.

Previously, I made the claim that the 8 bit shift register retains 17 bits of data. I’ll have to revise that down, to 16.5 bit. It is possible, as already mentioned, to use the output pin as a 9th visible output, as seen in the images and code below. However, the value of the output pin is shared with the 8th element of internal register, thus 17 distinct bits are not realised. It becomes more clear when considering the timing diagram of the of 595. Below is an extract and cut-out from the Texas Instruments data sheet [PDF].

The diagram above is truncated both in the horizontal and vertical axis, to highlight the last cycles, when the output pin, denoted QH’ in the digram, gets its value. As can be seen, when the 7th pin, or QG, is shifted up one (the first red line, when RCLK goes from high to low), QH’ gets that bit set as well. Note that the internal states of the shift register is not shown here. In the next cycle, SRCLK is latched, and the internal value of the 8th pin is made visible on QH, on the yellow line. The result is, that either QG + QH’ are on at the same time, or QH + QH’. This was frustratingly easy to reproduce in code, but not what I wanted.

To control all the nine LEDs of a layer independently, I had to set the output pin after the other eight pins were latched. However, if cycling quickly, it would then not get enough time on, and thus would look very dim. The final trick was to insert a short delay after all pins were set correctly, as seen in the code and discussion on timing below.

For the construction of the cube, I used LEDs from a 100-pack for $4.30 from DealExtreme, soldered onto a small 4x6cm (14×20 points) PCB. Following “fruitkid101″ video instructions, I drilled holes for a template in a piece of wood. As it was all by hand, it turned out a bit skewed, but for this small project I found it didn’t matter so much. Next time I’ll be a bit more precise. Soldering the legs together turned out be easy. I made the spacing between the LEDs small enough for one cathode leg to reach across its two neighbours, which meant that I only had to bend the ones in the corner. I soldered the corners first, and then the ones in between, finishing off with the centre LED. Positioning the anode legs between the layers was a bit more tricky, but with a double bend, as seen in the picture below, it was easy to make the leg from the layer beneath stay close enough to solder to its upstairs neighbour. Since the joints were for both the electrical contact, as well as the structural, I applied quite a bit of solder.

The interface to the Arduino is through the three direct pins which controls the sinks for each layer, and three pins for data, clock and latch of the shift register. The overview can be seen in this picture, and below. The small breadboard with the shift register also contains a 100 Ohm resistor for each pin, including the output pin.


As mentioned above, part of the motivation for this project was to control the cube with fewer pins, and use the output pin of a shift register for the 9th LED. That led to another interesting revelation in the code, and how to control brightness. As seen in the snippet below, which includes the display() method and the external fields used, the first inner for-loop for the shift register is all normal. It shifts the first 8 bits, with Most Significant Bit in the 8th element (index 7) of the display buffer buf[]. Surrounding that for-loop is the latch, however, notice that on the first line of the outer for-loop, the layer pin is set HIGH, which means, it is turned off. Before the layer we operate is turned on, the output pin is set to the value of buf[8] (and equivalent for higher layers). This is done within the second inner for-loop, inside the if-block. Strictly speaking, the if was not necessary; it would have been fine to shift out the extra bits every time.

Only after every pin is set to its correct state, is the layer turned on and the LEDs lit. However, if doing this without a delay, the LEDs would seem very dim, or almost off. Even if running the display() method only takes 400 micro seconds without the delay, for a good 2500 iterations per seconds, the problem would be that the LEDs would be turned off most of the time. To fix that, the delay is inserted, which holds the LEDs for a little while per iteration over a layer. With a one millisecond delay, the full method takes 3.4 ms, and can be executed ~300 times per second or a 300 Hz refresh rate of full cube.

However, with a delay of only 1 millisecond the LEDs are still somewhat dim. The fraction of time where the LEDs are off is still significant: For each layer 400/3 = 133 µs off vs. 1000 µs on, or about 12% of the time. If the delay is increased to 2 milliseconds, that ratio goes down to 6%, and the LEDs are noticeable brighter. The refresh rate goes down to ~150 Hz, but we are still far from the 50 Hz limit which is required to avoid flickering. In fact, we can go all the way up to a 6 ms delay before the limit is near (1000 ms / 50 / 3 = ~6 ms). However, it is hard to notice a difference between 3 and 6 ms delay. It would have to be measured. The lesson learnt then, is that it is not the refresh rate which matters the most when multiplexing LEDs, but rather the ratio of time the LEDs are on. Furthermore, with a 16 MHz MCU like the ATmega328, there is plenty of room for doing other stuff, and little need for premature optimization of code.

Future work will include utilizing the Arduino timer library for controlling the display buffer. Currently, that bit of the code is rather clunky. I would also like to experiment with fading and controlled blinking. Again, the timer library will be useful, but I’d probably also use the buffer to hold an intensity value, rather than just on/off. Also, I would like to measure the brightness with the different delays discussed above. One way would be using an LDR (light dependent resistor), but I might also look at the cheap $30 lux meters from DealExtreme. Finally, I’ll of course have to make some interesting patterns and animations, which should lead to an API for some level of abstraction. There’s lots to do!


Extract from code. See the full file for further details and GPL 3 license.

// Digital output pins

const int data =  5;
const int latch = 6;
const int clock = 7;

const int layer0 =  9;
const int layer1 = 10;
const int layer2 = 11;

const int layers[3] = {layer0, layer1, layer2};

const int outputPinCount = 6;
int outputPins[outputPinCount] = {
  data, clock, latch, layer0, layer1, layer2};

// Frame buffer
const int lights = 27;
int buf[lights];


void display() {
  for(int l = 0; l < 3; l++) {
     // Turns the layer off
     digitalWrite(layers[l], HIGH);
 
     // Shifts out the first 8 bits
     digitalWrite(latch, LOW);
     for(int i = 0; i <= 7; i++) {
       digitalWrite(clock, LOW);
       int bit = buf[l*9 + 7-i];
       digitalWrite(data, bit);
       digitalWrite(clock, HIGH);
     }
     digitalWrite(latch, HIGH);
 
     // Shifts 9 more bits to set the output pin
     if (buf[l*9 + 7] != buf[l*9 + 8]) {
       digitalWrite(data, buf[l*9 + 8]);
       for(int i = 0; i <= 8; i++) {
 	digitalWrite(clock, LOW);
 	digitalWrite(clock, HIGH);
       }
     }
 
     // Turns the layer on, and hold for 3 ms
     digitalWrite(layers[l], LOW);
     delay(3);
     // Turns the layer off again
     digitalWrite(layers[l], HIGH);
   }
 }
 


Comments Off

Simple multiplexing with two shift registers

Comments Off

There are many ways to drive multiple LEDs, which in sum would require more IO pins and more current than is available on the control chip. The simplest way is perhaps multiplexing, and in this example I’ve used two 8 bits serial-in/parallel-out shift registers to achieve that. I’ll skip the theory for now, but I think the structure and layout of the LED matrix is worth highlighting.

Below the 64 LEDs are shown in a grid of 8 columns and 8 rows. To light a specific LED, there has to be a potential difference between its two pins, thus the pin connected to a column should be set HIGH, and the other row pin to LOW. To individually control all the LEDs, the active row is cycled very quickly. For each step of the cycle, the specific LEDs of that row is set, and then changed for the next row. If done quickly enough (typically at least 50 times per second; 50 Hz), it will appear as if all the LEDs are always on.

The example in the figure shows register A set to 0000 0011, for the two right-most LEDs. Register B is set to 1011 1111, thus activating the second row from the top. In theory, the settings of the two registers could have been reversed, and then the two bottom LEDs of the second column had been lit. However, since LEDs are directional, and does not let current through when the polarity is reversed, this is not possible (at least not with the simple diagram shown below).

Please note that the drawing glosses over a few details: First, the pin-placements of the chips are not as per specification; the right most pin, in case of register A and top for B, are in fact ground. Pin 0, for the first bit of the register is actually on the opposite side (which is always rather annoying and confusing). See this post for details.. Secondly, there should be an array of resistors: one between each column line and chip A (see this picture as an example). Finally, although it is possible to drive the LEDs from the Arduino, as seen in the pictures further down, external power will improve brightness, thus a set of resistors would also be required.

8x8 LED matrix with two shift registers

Once the LED side of the registers are hooked up, there are a few wires to connect to the Arudino: Each shift register needs at least its data-in, clock and latch pins connected (plus pins which need high or ground). The data pin sets the next bit to be pushed onto the register. The clock pin does one shift on its transition to HIGH. Finally, the latch pin copies the content of the internal shift register onto the externally visible storage register. See Mike Szczys’s video for details on how this works.

There are a few ways these three wires from each register can be hooked up. One way, as seen in the pictures and code below, is to connect each data, clock, and latch pin separately, for a total of six IO pins on the Arduino. It is also possible to sync the latch of both registers, thus combining both of these pins onto a single IO pin. The code below could have benefited from this optimization (see the comments in the code). Secondly, it is possible to sync both latch and clock pins of both registers, and shift out two bits in parallel. In code, this would thus only required a single for-loop, however, an extra call to digitalWrite() (for the second data bit) would be required. I’ve not measured what difference this makes, so any insight here is welcome. Finally, it would be possible to daisy chain the two shift registers together. This would only require three IO pins, however would waste a lot of time shifting redundant bits onto the second shift register.

// Code under GPL; please see full file for details.

// Digital pins for two independent shift registers.
const int dataA =  5;
const int latchA = 6;
const int clockA = 7;

const int dataB =  8;
const int latchB = 9;
const int clockB = 10;

const int outputPinCount = 6;
const int outputPins[outputPinCount] = {
  dataA, clockA, latchA, dataB, clockB, latchB};

// Frame buffer
const int lights = 64;
int buf[lights];

void setupPins() {
  for (int i = 0; i < outputPinCount; i++) {
    pinMode(outputPins[i], OUTPUT);
  }
  clearAll();
}

void setup() {
  Serial.begin(9600);
  Serial.println("reset");

  setupPins();
  setAll(1);
}

void loop() {
  display();
}

void clearAll() {
  setAll(0);
}

void setAll(int v) {
  for (int i = 0; i < lights; i++) {
    buf[i] = v;
  }
}

void display() {
  for(int grp = 0; grp < 8; grp++) {
    digitalWrite(latchB, LOW);

    // Writes a single bit to the B register.
    // 0 means that group is active / on, 1 means off.
    // At the beginning of the loop, one 0 is shifted
    // onto the first bit, and later shifted upwards
    // as 1s turn the previous groups off.
    digitalWrite(clockB, LOW);
    digitalWrite(dataB, grp == 0 ? 0 : 1);
    digitalWrite(clockB, HIGH);
    digitalWrite(latchA, LOW);

    // Depending on the arrangement of the LEDs, and which
    // bits are conceptually most/least significant, shift in
    // increasing or reverse order.
    for(int i = 7; i > -1; i--) {
      digitalWrite(clockA, LOW);

      int bit = buf[grp * 8 + i];
      digitalWrite(dataA, bit);

      digitalWrite(clockA, HIGH);
    }

    // Here and above, both latches are set to the same
    // value at the same time, this could have been combined
    // onto the same IO pin.
    digitalWrite(latchA, HIGH);
    digitalWrite(latchB, HIGH);
  }
}

In the pictures below, the LEDs are on a single line, rather than in a grid, however, the grouping seen above still applies. Furthermore, each LED in my project is dual colour, so there only 32 of them, but still 64 pins to control. On my LED "breakout board" I've added a double set of headers for each pin on each LED, so I can easily connect them in any combination. The 8 pin jumper-wires from this post really came in handy.

For my custom dual shift register breakout board, I used this 4 x 6 cm PCB, and made the pins I needed available through headers. Please note that I made a mistake when placing the output headers, and for some reason assumed the pin on the opposite side was Q8 or QH, rather than 0 / A. On the shift register without resistors, I was able to correct this because there was room, however the other one was flush with the side, so it had to be corrected in the wiring (which makes some of the pictures below misleading). This board is somewhat similar to what you can buy pre-made from DealExtrme, however their version is using two daisy chained shift registers, and as mentioned, this will waste time when cycling the groups of LEDs.

Finally, note again that although it is possible to drive all this from the Arduino, even when powered over USB, better performance will be achieved with a higher powered external brick. Also, note that it is possible to mess up the code, so that all LEDs are turned on at the same time, and potentially draws more than 1 A. I shall not be held liable for what ever damage that might cause to hardware or people. Please see the license in the code for details.

First, some "making of" pictures, soldering all the LED pins and headers.

And here's the final product, well at least for now.

Comments Off

Large bright 10 mm LED

1 comment

Earlier this year, I found some uncommon LEDs at Clas Ohlson: Large bright 10mm LEDs (note that the link takes you to selection of different kinds; I got the “ultra white”). As seen from the pictures below, it is unusually large, compared to the 5mm LEDs which are most common. At 5000 mcd it is also very bright, and can easily be used as a flash light. Its forward voltage is 3.2 V, so with three AA batteries and a ~68 Ohm resistor, you’re all set.

I used a macro lens to take some of the pictures, and I found this one particularly interesting (make sure you zoom in 1:1). You can very clearly see the wire bond between the anvil and post. With most LEDs, this is usually too small to get a glimpse of. In this picture, you can get an idea of its cone. Like most LEDs, it is very directional, and thus flash-light idea.

How to make an LED Cube

2 comments

User “fruitkid101″ has a short and to-the-point video up on YouTube on how to construct a 3x3x3 LED cube, and drive it with an Arudino. What distinguishes his video from the hundreds of other LED cube videos out there, is that he explains step by step how to arrange the LEDs and route the wiring. Secondly, as it’s only three layers and nine columns, he needs no other components (save for resistors and three transistors), and all twelve wires are hooked directly up to the Arudino.

Another interesting and instructive video is Kevin Darrah’s on a 8x8x8 RGB cube. (Unfortunately, it wont show in HTML5 yet, but can be downloaded with the Video DownloadHelper Firefox plugin). He explains how to construct the towers which make up the cube, and also goes into detail on testing the LED and connections along the way. Much more work, of course, but also looks very cool.

Interacting with the Button Pad Controller SPI

4 comments

By popular request, here’s an update to the first code for the Button Pad Controller SPI. This sketch now includes interactive feedback, in the form of changing colours based on key-presses.

Click view full size image.

Click to view full size image.

Click to play video.

Click to play video.

Download the sketch here.

// The wires
#define CS 10
#define MISO 11
#define MOSI 12
#define SCK  13

// Frame buffer for lights
int lights = 16;
int depth = 3;
byte buf[16][3];

boolean wait = false;
boolean ready = true;

void setup() {
  pinMode(CS, OUTPUT);
  pinMode(MISO, OUTPUT);
  pinMode(MOSI, INPUT);
  pinMode(SCK, OUTPUT);

  digitalWrite(CS, LOW);
  delay(100);

  blank();

  Serial.begin(9600);
  Serial.println("Starting");
}

void blank() {
  // init frame buffer
  for(int l = 0; l < lights; l++) {
    for(int d = 0; d < depth; d++) {
      buf[l][d] = 0;
    }
  }
}

void loop() {
  digitalWrite(SCK, HIGH);
  digitalWrite(CS, HIGH);
  delayMicroseconds(15);

  // Set lights: 3 x 16 bytes
  for(int d = 0; d < depth; d++) {
      for(int l = 0; l < lights; l++) {
        writeByte(buf[l][d]);
      }
  }

  if(!ready) {
    wait = true;
    ready = true;
  }

  // Read the buttons: 16 bytes.
  for(int l = 0; l < lights; l++) {
    // readByte returns a non-zero value when a button is pressed.
    byte b = readByte();

    // If a button is pressed, change the colour.
    if (b > 0 && ready && !wait) {
      if      (buf[l][2] > 0) { buf[l][2] = 0; }
      else if (buf[l][1] > 0) { buf[l][1] = 0; buf[l][2] = 255; }
      else if (buf[l][0] > 0) { buf[l][0] = 0; buf[l][1] = 255; }
      else {                                   buf[l][0] = 255; }

      Serial.print("Button ");
      Serial.print(l);
      Serial.print(": ");
      Serial.print((int)b);
      Serial.println();

      // Change colours slowly.
      ready = false;
    }
  }

  digitalWrite(CS, LOW);

  // After the second cycle, get ready to read new button clicks.
  if(wait) {
    delay(500);
    wait = false;
    ready = true;
  }

  delayMicroseconds(400);
}

// Write out a byte.
// This is for a single colour channel, for a single button.
void writeByte(byte data) {
  for(int i = 0; i < 8; i++) {
    digitalWrite(SCK, LOW);
    delayMicroseconds(5);

    digitalWrite(MISO, (data & (1 << i)) >> i);
    delayMicroseconds(5);

    digitalWrite(SCK, HIGH);
    delayMicroseconds(10);
  }
}

// Read a byte.
// Returns the value for a single button.
// Non-zero if it is pressed, or 0 otherwise.
byte readByte() {
  byte result = 0;
  for(int i = 0; i < 8; i++) {
    digitalWrite(SCK, LOW);
    delayMicroseconds(5);

    result += (!digitalRead(MOSI)) * i;
    delayMicroseconds(5);

    digitalWrite(SCK, HIGH);
    delayMicroseconds(10);
  }

  return result;
}

First code for the Button Pad Controller SPI

4 comments

I recently got the Button Pad Controller SPI from SparkFun. Today I had some time to play around with the code, and got it working. Currently, it is only blinking all the lights, however the code should demonstrate the basics. The user guide from SparkFun documented the details of the interface. Add a few delayMicroseconds() calls, and it’s up and running.

Download the sketch here.

// The wires
#define CS 10
#define MISO 11
#define SCK  13

void setup() {
  Serial.begin(9600);
  Serial.println("setup");
  
  pinMode(CS, OUTPUT);
  pinMode(MISO, OUTPUT);
  pinMode(SCK, OUTPUT);
  
  digitalWrite(CS, LOW);
  delay(1);
}

int lights = 0;

void loop() {
  Serial.println("loop");
  
  // "The Button Pad Controller SPI will begin listening
  //  for a data set once the CS input has been brought high."
  
  // "(HINT: It's best if the SCK signal is set high before
  //  setting the CS pin high)."
  digitalWrite(SCK, HIGH);
  digitalWrite(CS, HIGH);
  delayMicroseconds(15);

  // Blink the lights.  
  lights = !lights;
  
  // Four frames (3 for lights input, 1 for button output)
  // (Here, it is writing to output on the 4th as well, which
  // is wrong, but seems not to cause any issues).
  for(int f = 0; f < 4; f++) {
     
       // Each frame has 16 * 8 = 128 bits of data.
       for(int i = 0; i < 128; i++) {
         
           // "The data on the MISO line should be set while the
           //  clock is low. When the SCK signal goes high the
           //  Button Pad Controller locks in the data currently
           //  on the MISO line."
           digitalWrite(SCK, LOW);
           delayMicroseconds(5);
           
           digitalWrite(MISO, lights);
           delayMicroseconds(5);
           
           digitalWrite(SCK, HIGH);
           delayMicroseconds(10);
       }
   }
   
   digitalWrite(CS, LOW);
  
   Serial.println("end");
   
   // "The CS signal should remain high for the duration of the
   //  data set, at which point it should be brought low for a
   //  minimum of 400 μs before sending the next set of data."
   
   //delayMicroseconds(400);
   delay(500);
 }