Leddie

Markus | Sunday, December 15th 2024, 08:54

-- A simple 6-sided die with LEDs.

Figure 1. Leddie

Leddie is a 6-sided die with nine RGB LEDs on each side. This first prototype is powered by an Atmega8 and an accelerometer, and can run off the wall for about two hours thanks to the built-in 400 mA li-polymer battery.

A little bit of history

I technically started this project about 3 years ago, but that certainly does not at all reflect the time that went into it as it was on hold for most of it. I started out with an Atmega8 knowing it would be underpowered for what I want to do, yet went ahead with it because I knew I would a) be able to get a demo running very quickly on it, and b) because I knew I could achieve my ultra-low power standby modes. (Leddie does not have a power switch, the CPU is always connected to the battery cell.) This decision, however, was also the curse of the project.

Mid-project, I decided that, ultimately, I'd want a WiFi-connected chip in there so that I can sync multiple dies across the Internet to aid, for example, in remote DnD campaigns. That, in combination with the usual curse of getting interested in new projects before finishing the old ones, made me put the project on hold. When I rediscovered the project many months later, I looked at the state I had left it in -- all board layouts completed, pretty much unreviewed and unchecked, and with the Atmega8 -- and decided to just go for it and order everything in the current state. The idea was that there would probably be some things that need changing anyway, so I could use this Rev 1 to learn and iron out the basics, and then fix all of those along with the CPU upgrade in a Rev 2. (Note: Rev2 hasn't happened yet.)

Mechanical Construction

One goal from the start was that the cube should not consist of any parts other than the electronic components and the PCB. No 3D-printed housing, no other mechanical parts.

Therefore, the construction was inspired by how many laser-cut wood panels are assembled. Pieces are aligned using little notches, and are then directly soldered to each other. The additional advantage of soldering them is that the mechanical connections can double as electrical ones.

Figure 2. Unfolded
Figure 2 shows the indidividual side panels of the cube assembled flat on a table for testing purposes. Wires are used to connected the sides that would usually be touching directly when assembled in 3D.
Figure 3. Open box
Fully assembled, as shown in Figure 3, jumper wires are only necessary for the last side that would then be folded shut. It is held in by friction and some glue for good measure.

In terms of PCBs, there's a bottom PCB handling power, a top PCB handling the CPU + accelerometer (all things digital), and side PCBs with the charge/data port and switch. Each PCB has the necessary components for these functionalities on the inside while the outside is always covered in 9 RGB LEDs. The boards are described in more details in the next section.

Electronics

This section describes the circuit on a high level, but I recommend to open the schematic [1] next to it to see the details of the implementation.

Power

Figure 4. Leddie power side

The power board has three main responsibilities:

  • Provide 3V power for the CPU
  • Provide 5V power for the LEDs
  • Handle charging of the 400 mAh 3.7V LiPo battery

The 3V supply is used to power the CPU and accelerometer. It must always be active as the system must be able to wake up from the "off" state using the same button that is used for normal user interactions. This is implemented using a simple low-dropout regulator (LDO) from the battery voltage to the CPU supply rail. This means that the CPU voltage will vary from 3.3V (regulated) down to 3.0 V when the battery runs low. The power supply to the accelerometer is technically a separate power rail, but to save components, its power is switched directly through an I/O pin of the microcontroller, basically abusing its output FETs and power MOSFETs. This is acceptable because the supply current of the accelerometer is lower than the Atmega's drive capability.

The 5V supply is required to drive the WS2812B LEDs. As this voltage is higher than the battery voltage, and quite some current can be required for, for example, bright pulses of all LEDs, this one is implemented as a switch-mode power supply (SMPS). Additionally, a MOSFET is added before the regulator to switch completely switch it off when the device is in standby.

Battery charging is implemented using an integrated linear charge controller. Nothing fancy here.

Digital (CPU + accelerometer)

Figure 5. Leddie digital side

The digital board implements all logic functionality of the die:

  • Processor
  • Accelerometer

The microcontroller is an Atmega8 by Microchip (formerly Atmel), which is based on the 8-bit AVR-architecture running at 16 MHz. This microcontroller implements the entire program logic controlling the LEDs, power systems, and USB communications.

USB functionality is implemented using V-USB [2], which implements USB 1.0 by bit-banging the I/O ports of the AVR. On the hardware side, it only requires a the USB D+ and D- lines to be connected to the chip through a 68 Ohm resistor each and a 1.5k pullup on D-.

To control the WS2812B LEDs, their voltage is shifted from the 3.3V that the microcontroller operates on to the 5V of the LEDs. Note: In the current revision, this is implemented as a simple NPN bipolar transistor with a pullup. This circuit, however, is not fast enough to properly drive the waveform the LEDs need. As a workaround, the level shifter has been removed entirely which appears to work as the LED voltage has been reduced to around 4.5V.

The accelerometer on the board is an MMA8653FCR1, which provides acceleration data on 3 axes. Additionally, it implements drop and tap detection, and is wired to interrupt inputs on the AVR, which allows, for example, to wake the die from deep sleep simply by picking it up.

Sides

Figure 6. Leddie auxiliary side

The sides are all based on the same PCB layout, but with different components populated. As usual, the outside of each side is populated with 9 LEDs each, but the inside can be either of

  • the main tactile button,
  • the USB-micro receptacle, or
  • nothing (2x)
. In addition to these components, different solder bridges are connected depending on which of the four sides it is. The numbers on the labels next to the bridges indicate on which sides they need to be conected.

The PCB layout has been created in a way that supports all these options by overlaying the fooprints on the bottom side of the PCB. The power PCB (which is adjacent on the bottom where the switch or the USB socket is placed) has appropriate cut-outs (or none) on the corresponding sides. S4 is the button, S2 is the USB connector.

Power Consumption

The die is battery-operated, and from a comparatively small one as it needs to remain handleable. Therefore, power consumption has been an important consideration from the start. Basically, we need to look at three operative modes:

  • Power down sleep: The die does not have a hard power switch, so standby needs to give a many months of battery life,
  • Power on: Normal operation, CPU and accelerometer active, some LEDs active at an average medium brightness,
  • All on: Everything active, LEDs all at their brightest white.

The last mode, all-on, is not really a practical use case. Just a back-of-the-envelope calculation for the power draw here shows this is not realistic: 60 mA (current of each LED at max brightness) * 9 LEDs/side * 6 sides = 3.24 A. At 4.5 V, that's around 15 Watts! Designing a power supply to handle this kind of current given the size constraints is just not reasonable. Also, the SK6805 LEDs are plenty bright even at lower settings. A more realistic approximation was a continuous maximum of half the LEDs lit up in a single color, which puts us around 400 mA, which is what the circuit is designed for. While not ideal, the switch-mode converter is able to put out up to 2.1 A for a limited amount of time and bad efficiency, so short bursts of color are possible.

Normal operation mode had a little surprise in store. One common pattern in normal operation mode actually is most LEDs off, because for example only the top side is lit up. Yet, when measuring the power consumption of a die turned completely black, I was still drawing about 45 mA, which very close to value I saw for all LEDs at maybe 2% (already very visible). Why is that? LEDs are pretty efficient, one does not need much current to get a decent amount of light. So, okay, that explains why 2% brightness does not increase the current draw by much, but why the high idle draw? Well, these are "smart" (digital control integrated) LEDs. If you look at the "datasheet" of these kinds of LEDs, the idle current draw with the LED commanded "off" is only 800 uA. But remember, we have 54 of these, that already makes 40 mA! Ooof, that's more than I'd like, but luckily it's not a deal breaker. Assuming an average current of even 100 mA, the die will last for over two hours.

Power-down mode worked flawlessly. The Atmega has a deep-sleep current draw of a few microamps, and everything else can be completely turned off using a MOSFET, or directly using an I/O pin on the microcontroller.

Errata

Now, for the the long long list of errata... As I just grabbed the design files in whatever state they were in when I rediscovered the project many months after stopping, many errors made it through the cracks. I'll attempt to list them here, but no guarantee that I've caught all.

  • Atmega8 missing crystal: For USB, we need a 16 MHz crystal. Workaround: Bodge it on the PCB.
  • Atmega8 supply voltage: The Atmega 8 is not specified to function properly when operated at 3.0V@16 MHz. Workaround: It appears to work :shrug:
  • Pinout on the side PCB is mirrored: On all sides, the top and bottom connectors are mirror flipped (GND should be PWR, 2 should be 3 etc.). Workaround: Cut and strap.
  • WS2812B level shifter too slow: The NPN+Pullup level shifter is too slow. Workaround: Directly connect the Atmega to the WS2812B, seems to work fine as I run them at 4.5V instead of 5.0V...

Cool! I want to build one too!

Everything needed to replicate this project is open source. However, beware that the long list of errata has not been adressed yet, so you'll have to do that yourself unless you want to do the insane amount of cut-and-strap seen in the picture above.

All necessary documentation can be found in my Git repository [3]. kicad contains the schematic and PCB design sources, bootloader the adapted USBasp bootloader to reprogram the die in the assembled state and without special hardware, and finally firmware contains the main application. The application "entrypoint" (designed as a function that's called over and over and must be non-blocking) is app_mainloop() in app.c, with the actual main function for the CPU being in lib/system.c.

If you have any questions, or actually decided to build one, I'd love to hear from you! You can find my contact details on the Contact tab on this website.

Videos

Embedded content has been disabled to protect your privacy.




or click here to allow them permanently,

or click here to watch the video on YouTube:
https://www.youtube.com/watch?v=FE6J7YIEzy0



Please note that, by enabling this video, data is transferred
to YouTube LLC, and is subject to their privacy policy.
Embedded content has been disabled to protect your privacy.




or click here to allow them permanently,

or click here to watch the video on YouTube:
https://www.youtube.com/watch?v=x5G-noaqAK4



Please note that, by enabling this video, data is transferred
to YouTube LLC, and is subject to their privacy policy.

Sources:
    [1]: https://git.notsyncing.net/markus/leddie/releases/download/rev1/leddie.pdf
    [2]: https://www.obdev.at/products/vusb/index.html
    [3]: https://git.notsyncing.net/markus/leddie


Tags: hardware