Introduction: Half Square Triangles LED Art

The idea for this project came to me during the construction of my previous project “Half Square Triangles Kinetic Art”. The project was quite difficult to complete, I succeeded, it's true, but I wanted to completely remake the project on other bases. That's how this concept of "HST LED Art" was born, meaning I used LEDs to display half square triangles models. Interestingly, during the design, I discovered that the LED arrangement I used can have other purposes: it can be a matrix display of 8x16 LEDs, it can be a display of 8x8 LEDs with 2 LEDs each in every cell... And there are a lot of projects based on matrix displays, my way of arranging LEDs can be applied to many of these projects, bringing a new approach... Some examples are here on instructables:

For example, in my Verbis WordClock project, a blend is made between two colors to emphasize the words of the hour. The blend is made with a single LED, but with this project it could be done with two LEDs, one LED for one color, another LED for the other color and the ‘blend’ could be much more natural.

So in the end, the Half Square Triangles Kinetic Art becomes the Half Square Triangles LED Art :)

Step 1: Designing the LED Matrix

In order to make a display as close as possible to the real one, as in my initial project, I was not satisfied to make only a direct display of the HST models, one after the other, I wanted to make an animation that would appear between these displays.

I started by superimposing the four possible positions of the triangles, and I came up with image,

and for some intermediate positions I divided the resulting square in two. That's how I came up with this image.

This will be one of the 16 cells of the simulation. I need 8 LEDs and the animation to be the representation of a gradual change from a color of a LED to another color from a "slice" at the end of the triangle and the same color change (but vice versa) right next to the 'slice' at the other end of the triangle. I know it doesn't sound too clear but a picture of this animation will show everything better, so I added a gif below.

After this, I tried to see how I can position the LEDs using the LED strip.

I do not want to bore you with all the iterations I imagined, the best solution in my opinion is in the picture below:

You can also see how the LEDs positions are related to the LEDs separation grid.

There are a total of 128 LEDs, which I grouped into four groups of 32 LEDs that I would connect to four digital outputs of an Arduino Nano. But more about the LED groups in the next steps.

Step 2: Components, Materials

I used the following for this project:

  • WS2812 LED strip, 60 leds/meter, 128 pieces;
  • Arduino Nano Microcontroller 1 pc;
  • Wooden photo frame 1pc;
  • Smoked Plexiglass 200mmx200mm, 3mm thick
  • White colored paper,
  • 5.5x2.5mm DC Female Plug with Cable;
  • 5V/2A power supply with 5.5x2.5mm DC Male Plug;
  • Wood screws 10x2.5mm;
  • Wires for connections,
  • 3D printed parts: LED support, LED divider grid, support legs, grid locking parts, fixing parts, alternative divider grids.

You can download the STL files for the 3D printed parts from Tinkercad.

I ordered the wooden frame online from a company that are specialized in photo framing, and other framing accessories. The dimensions of the frame section are those in the figure below.

As always, although I specified in the order the internal size I wanted (as close as possible to 200mm), the frame that was delivered to me had an internal size of about 204mmx203mm, that's why I needed some 1.5 - 1.6 mm thick plates to lock the grid.

I also designed two other divider grids, a simpler version of the divider above and an 8x8 cell grid for a standard LED matrix. You can find them on Tinkercad.

I printed them and used them in the videos, which you can watch in the step 6 "how is it working".

As for the rest of the materials, everything is standard, you can see them in the pictures above.

Step 3: Schematics

It is a very simple schematic and consists only of the Arduino Nano module, LEDs and the 5V/2A power supply. I don't have much to add :)

Step 4: Construction

After printing on the 3D printer the LED support and the LEDs separation grid, I moved on to perhaps the most important phase of the construction: fixing the pieces of LED strip to the support. I started by cutting the necessary lengths from the LED strip, there are the longest pieces that contains 14 LEDs and the shortest one with two LEDs. Then, I unfolded the protective paper of the self-adhesive support in the middle of the strip and I fixed the middle piece with some LEDs, taking care to match the position of the LEDs as well as possible with the guide lines on the support. Gradually, I removed the protective paper to the edges of the pieces of strip and at the same time I fixed the LED strip carefully. When I was close to the ends, I completely removed the protective paper, folded the ends of the strip and inserted them into the slots in the support. I thus fixed the pieces of LED strip from layer I (blue color) then layer II (green color) according to the figure (see also photos above).

Tip: Avoid having soldered parts like this

in the LED strip pieces as much as possible. In the case of such soldering, the distance between the LEDs is never the required one. In my case, it should be 1000/60 = 16.667mm (60 leds/m). Many times, even in the factory, this distance is not respected, I had 60 leds/m strips where the distance between the LEDs was 16.4 - 16.2 mm, over long distances (many LEDs) this error accumulates progressively. It is useful to measure the strip you are working with before, ie to measure if the distance between the LEDs is correct and choose a strip accordingly.

Also be very careful when orienting the LED strips, Data OUT (DO) always connects to Data IN (DI).

I then made the connections according to the electronic scheme. I strengthened the ties with a little hot glue. I put the Arduino Nano in a slim 3D printed case, I took the model from Thingiverse, I changed the dimensions a bit to fit the Nano clone I used. I also made changes to the size of the gap in which the connections entered. If you want to download my version, it's here on Tinkercad but you can of course use any Nano enclosure you like. The complete LEDs + electronics + support assembly can be seen in the photos above.

I then put in the frame the piece of plexiglass, the white paper cut to the size of 200mmx200mm and the separation grid. After adjusting the LED support, I marked the place where I will put the fixing pieces. I drilled 2mm holes in the frame and screwed the pieces to the frame by pressing lightly on the LED support. I also marked the place for my supporting feet, which I attached to the frame with wooden screws.

Check the photos above.

The construction is finished!

Step 5: Software

The only library I used is the FastLED library!

Before I introduce you to the software part for the Half Square Triangles LED Art, I would like to show you some small demonstration codes so that you can see how versatile this LED array can be.

Palette Demo

The code is based on Mark Kriegsman's code here which displays several color palettes from cpt-city, with a gradual transition from one color palette to another. The difference from the original code is that I used several color palettes just like in the code, from this youtube video. Of course, the definition of LED strips is different, I used the definition of multiple strips, as in the FastLED documentation here, and it appears in the initialization code like this:

FastLED.addLeds<CHIPSET, 2, COLOR_ORDER>(leds, 0, 32).setCorrection( TypicalLEDStrip );
FastLED.addLeds<CHIPSET, 3, COLOR_ORDER>(leds, 32, 32).setCorrection( TypicalLEDStrip );
FastLED.addLeds<CHIPSET, 4, COLOR_ORDER>(leds, 64, 32).setCorrection( TypicalLEDStrip );
FastLED.addLeds<CHIPSET, 5, COLOR_ORDER>(leds, 96, 32).setCorrection( TypicalLEDStrip );

CHIPSET being WS2811 and COLOR_ORDER GRB

There are four groups of 32 LEDs each connected to the digital outputs 2,3,4,5 of the Arduino Nano Otherwise, everything is as in the original code, you can download it on github and watch how it looks in action in the video from the next step.

Fire Demo

I adapted Stefan Petrick's code from github. Here I used LED mapping to a LED array that is easier to manage in code. You saw that I used four groups of 32 LEDs that are fixed to the support in the order that is in the figure below.

If I want to treat LEDs as belonging to a matrix, it is very difficult to find a function for their proper mapping. So I used a buffer array - m_leds - that simulates a standard matrix (not serpentine). This buffer array helps me call a certain LED in the array much easier. See the figure below:

Thus the sixth LED in row 2 can be represented as

 leds[m_leds [2 * 8 + 6]]

and that's LED number 22 from m_leds buffer array and led number 50 in the leds main array - do not forget the numbering of arrays elements starts with 0! :).

I did the same in this code, which you can also find on github. In the video I filmed the effect with 2 grid variants. You can make a variant even without a grid, only the support should be at a distance from the diffuser paper (using a printed frame with a height of 12mm, without compartments) then the effect could be like on Youtube here.

StopWatch Demo

In this small demo I wanted to see how the numbers look on this array of LEDs.

Four Symmetry Demo

I displayed in the 4x8 dial on the upper-left a random number of LEDs with random colors and I mirrored them horizontally, vertically and in both directions. The result was an interesting kaleidoscope effect. I hope you will enjoy it.

Half Square Triangles LED Art

For this program I used the definition of multiple LED strips exactly like in the previous demonstration examples and I also used the m_leds buffer array as in the fire, stopwatch and four symmetry examples.
But I would like to clarify a little how I arrived at the values in the hst_cell_origin and hst_cell_offset arrays.

const byte hst_cell_origin[] = {0, 2, 4, 6, 32, 34, 36, 38, 64, 66, 68, 70, 96, 98, 100, 102};
const byte hst_cell_offset[] = {0, 1, 9, 17, 25, 24, 16, 8, 0, 1, 9, 17, 25, 24, 16, 8};

In the second step, when I talked about the design of the LED matrix, I explained how a cell will look when the animation takes place, ie the simulation of the triangles rotation. In the image below you can see what the first cell (top left) would look like along with the order of the numbers that correspond to the LEDs in the cell.

Because the zero LED will be the one with which the animation will start, it will be the origin of the cell and the other cells will have the origins corresponding to each "zero LED" , from the four, horizontally and vertically, 16 cells with 16 origins. These numbers are in the hst_cell_origin array. You can check if it's ok by comparing the LED numbers on the display (the figure above with red numbers) with the numbers in the array.

In the hst_cell_offset array are numbers that represent the difference between the numbers of the LEDs in the cell (according to the image above) and the number of the origin LED. These differences are the same regardless of the number of the origin LED. The order of the numbers in the array is exactly the "direction of motion" of the animation. Doubled values are needed because the animation is done between two "ends" of the triangles and I wanted to avoid some extra conditions, so I went on some simple "for-next" loops, I'm not a very good coder. Otherwise, I tried to comment on the code so that it is easy to understand. Anyway, if you have any questions about the code, I will be happy to answer.

All codes are downloadable from github.

Step 6: How Is It Working?

I made two videos for this project, one in which I filmed the four demonstration programs and another with the main program "HST LED Art". In each video, I used the two dividing grids I mentioned in step 2, the standard one with 8x8 cells for Palette Demo and Fire Demo and the simplified one for the main program.

Step 7: Conclusion

The LED matrix came out exactly as I imagined and I honestly like it very much, I am very satisfied with the result. Both the demo programs and the main program work perfectly and by using the three division variants, I obtained interesting results. I really want to emphasize that by using the simple version of the divider, for me it seems that the main program looks way better.

I am looking forward to your opinions and I am also waiting for your questions.

Remix Contest

Runner Up in the
Remix Contest