This week, we did a few corrections and improvements on the schematics and started the the actual design of the PCBs.
We chose the plexiglass sphere for bouLED. Its internal diameter is 350mm so we took a margin and reduced the triangles’ sides to 179mm. This was enough information to place the LEDs. Having done the triangle design with OpenScad revealed helpful to check the placing as I imported a DXF version of it in Mentor’s software, as Alexis suggested. I was also happy that we chose a rather regular LED repartition, so I could use grids instead of manually copying 78 coordinates.
For the routing, however, we’ll need to know the positions of the screw holes in the PCB. Hichem is currently working on that, designing the pieces with SolidWorks. (I started doing it with FreeCAD but the SolidWorks lobby had the last word.)
This will be a 2-layer PCB, with a ground plane on the bottom. The voltage regulator will go on the back side of the PCB, with the jumpers.
The electrical design of the faces is almost done. The triangles were first thought to be the equivalent of the LED strips:
But then we chose to put one 14.8 to 5V regulator on each face:
Add a few connectors and that’s all there is to these PCBs.
In addition to not being decided about the internal structure of bouLed, we also need to choose the enclosing transparent sphere. This constitutes an important size constraint, and we might have to reduce bouLED’s size by a few millimeters to fit it. More on that soon.
Hichem got the MARG working last week-end, so we tested it with our simulation (see his post) and confirmed this model would suit us and go on our central PCB. With this and the voltage regulators chosen, we have almost all we need to design the PCBs. The triangular ones may be simpler to design, but before we want to know precisely the physical structure of bouLED.
For ease of conception and of battery management, it should be possible to open the icosahedron. One way to do it is to make five faces removable, as shown on this simple model.
The inner armature would support the electronics and the LiPos, ideally keeping the MARG in the center of the icosahedron. Thus the stick supporting the removable part should be moved, and probably replaced with something stronger. The faces would be connected to the central part with JST-like connectors, easy to plug and unplug.
We want to chain the triangles without using too long wires, and we want a removable part. This will dictate how we’ll position each face and how we’ll place the connectors on it, while keeping all triangular PCBs identical. The LED repartition we think we’ll use surely is even enough not to be considered when choosing the face’s orientations.
Following the suggestions of the teachers, we measured the maximum power consumption of the LEDs again. We may have misused the power generator the first time, or didn’t set the LEDs at full brightness. Anyway, under rigorous measurements, our first triangle of 133 LEDs uses 4.5A under 5V. This is at a blinding brightness, nevertheless this is a huge power if you have 20 triangles and we’re thinking about how to provide it.
After finishing the 3D visualization (though it’s not merged on master yet and one could argue it’s therefore not finished), I joined Hichem on his work with the MARG. We want it working ASAP, so we can be sure we’ll use this chip, and we can start designing the PCBs. We spent some time today debugging his code. We suspect the I2C timings are the reason why we couldn’t get an acknowledge from the MARG, and we hope to solve it tomorrow.
Last week we finally printed a triangle of the right size (see Hichem’s post). Hichem cut the led strip into smaller ones, and I re-soldered them to fit the triangle, which was not hard but took some time.
For the final object, we won’t have to solder 20 times as many LEDs. We’ll just put individual LEDs on triangular PCBs -we just started drawing the circuit diagrams. The point of this first triangle is to be able to display stabilized animations before all the PCBs are built.
I also worked on the 3D visualisation. Matthias had re-written the first one with PyQtGraph, because VTK didn’t suit him. But this new one had terrible performance: computing the new LED positions every frame made the framerate drop to around 1fps. Therefore, we had to write another simulator. This time, no more compromises, no more Python, just C++, OpenGL and sweat. Matthias set up the OpenGL context and let me have fun with matrices, geometry, textures and instancing. It’s not quite finished yet (not to mention glitches), but we can dynamically color each LED, rotate the model by feeding the simulator quaternions via stdin, and still get 300 fps on integrated graphics.
When it’s done, we’ll be able to display images on it, and get an idea of the final result. However we haven’t decided yet how we’ll store and project images on the icosahedron. We’re also unsure if displaying text is possible with our relatively low resolution.
Yesterday I stopped making knots with the wires: I soldered them to the LED strip on one end, and put pins on the other.
The issues I had to control the last LEDs of the strip were actually due to the APA102 datasheet being wrong, in addition to being poorly translated from Chinese into English. The “end frame” of the SPI message it described was indeed required, to supply more clock signals than the length of the payload. But not enough if you have a hundred LEDs, as explained on this very informative blog. The data signal being delayed by half of clock cycle by each LED, the length of the end frame should be proportional to the number of LEDs.
Then there’s the brightness setting, 5 bits on each LED frame, which everyone agrees to set to 0b11111 and forget about.
We should soon have a 3D printed triangle that fits the LEDs (see my friends’ posts). The LEDs shall then be rearranged: we’ll cut the ribbon into smaller ones and re-solder them. Then we’ll look at the signal coming out on the end of the ribbon and see if we can put another one in series.
To build the 19 other faces, we might need a few more LED strips. We did some measurements, and one 5V LED strip consumes a bit more more than 1A. Until now our test card could supply enough power when using a reasonable brightness, but with more than 15 times as many LEDs, we’re looking at big batteries for bouLED to be autonomous.
As we want to use led strips for bouLED, trying to turn these LEDs on with our microcontroller would be a good start.
Our STM32L475 luckily happened to have SPI controllers. I used one in the frequency range recommended in the APA102 LED strip datatsheet, that is around 1MHz, to display simple animations on the ribbon. After some playing with the wires and some endianness considerations, I could control almost all of the 133 LEDs (and I’m investigating why some won’t obey). Thanks to ChibiOS, the current implementation already makes use of the DMA, so that SPI transactions don’t take up much CPU time.
The next step will be to see if we can increase the frequency. Then we’ll need to consider more LED strips: the SPI controllers can only send data on a few GPIOs, while we might need to plug 20 LED strips (or less if we can put some in series).
The first thing I did for our project bouLED was to write a python script to visualise the orientation of our test card.
bouLED will need to know its orientation, which will be computed from a MARG (Magnetic, Angular Rate, and Gravity) sensor using Madgwick’s algorithm. In order to easily check the results of this computation, we want to draw and rotate a 3D shape as we rotate the card with the MARG sensor. The orientation of the card is represented as a quaternion, and will be sent to my python script via a serial port.
We haven’t implemented Madgwick’s algorithm yet, so I just sent arbitrary quaternions to test the visualization. Its latency was at first unacceptable (~0.5s) when I used PySerial to read the serial port. Sending the serial port to the script standard input made the latency imperceptible.