Electronics – IllumiNative

Table of Contents

Requirements

  • Total of 1500 - 2000 lumen of luminous flux
  • Two-channel constant current drive
  • Bluetooth interface
  • 12-24V DC input

Submodules

The electronics can be seen as three distict submodules (click to see design & build process):

Considerations

Brightness steps

The problem with our standard 8-bit PWM on the ATMeag is that its steps are linearly spaced. 256 steps would be enough for our eye to notice no discrete steps within the desired luminous flux rate, if only they were spaced logarithmically. Our eye’s perception of brightness is approximately logarithmic. This means doubling the perceived brightness requires four times the light. So at the lower end of the duty cycle, we’re gonna have too big increments in order to dim without noticable steps, while at the upper end the steps could be much wider without us noticing any jumps in brightness.

Software Solution

So what’s the solution? Logarithmic PWM, right? No idea if that exists – i’ve never heard of it. Instead, we can increase the resolution of our PWM to a lot more steps, and then choose a tiny subset of logarithmically-spaced duty cycle values. Assuming our LEDs have a near-linear power-to-brighness curve, looping over that subset should give us almost linear dimming.

These lookup tables for different bit depths, created by the fine guys at mikrocontroller.net forum, should illustrate what i’m saying:

const uint16_t pwmtable_8D[32] PROGMEM =
{
    0, 1, 2, 2, 2, 3, 3, 4, 5, 6, 7, 8, 10, 11, 13, 16, 19, 23,
    27, 32, 38, 45, 54, 64, 76, 91, 108, 128, 152, 181, 215, 255
};

const uint16_t pwmtable_10[64] PROGMEM =
{
    0, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 6, 6, 7, 8, 9, 10,
    11, 12, 13, 15, 17, 19, 21, 23, 26, 29, 32, 36, 40, 44, 49, 55,
    61, 68, 76, 85, 94, 105, 117, 131, 146, 162, 181, 202, 225, 250,
    279, 311, 346, 386, 430, 479, 534, 595, 663, 739, 824, 918, 1023
};

const uint16_t pwmtable_16[256] PROGMEM =
{
    0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3,
    3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 7,
    7, 7, 8, 8, 8, 9, 9, 10, 10, 10, 11, 11, 12, 12, 13, 13, 14, 15,
    15, 16, 17, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
    31, 32, 33, 35, 36, 38, 40, 41, 43, 45, 47, 49, 52, 54, 56, 59,
    61, 64, 67, 70, 73, 76, 79, 83, 87, 91, 95, 99, 103, 108, 112,
    117, 123, 128, 134, 140, 146, 152, 159, 166, 173, 181, 189, 197,
    206, 215, 225, 235, 245, 256, 267, 279, 292, 304, 318, 332, 347,
    362, 378, 395, 412, 431, 450, 470, 490, 512, 535, 558, 583, 609,
    636, 664, 693, 724, 756, 790, 825, 861, 899, 939, 981, 1024, 1069,
    1117, 1166, 1218, 1272, 1328, 1387, 1448, 1512, 1579, 1649, 1722,
    1798, 1878, 1961, 2048, 2139, 2233, 2332, 2435, 2543, 2656, 2773,
    2896, 3025, 3158, 3298, 3444, 3597, 3756, 3922, 4096, 4277, 4467,
    4664, 4871, 5087, 5312, 5547, 5793, 6049, 6317, 6596, 6889, 7194,
    7512, 7845, 8192, 8555, 8933, 9329, 9742, 10173, 10624, 11094,
    11585, 12098, 12634, 13193, 13777, 14387, 15024, 15689, 16384,
    17109, 17867, 18658, 19484, 20346, 21247, 22188, 23170, 24196,
    25267, 26386, 27554, 28774, 30048, 31378, 32768, 34218, 35733,
    37315, 38967, 40693, 42494, 44376, 46340, 48392, 50534, 52772,
    55108, 57548, 60096, 62757, 65535
};

Source: mikrocontroller.net/articles/LED-Fading (german language)

Hardware Solution

An “analog” solution could be to use a log amp that would be placed after the digital output of the microcontroller. Actually looks like a neat and proper solution to the problem, but is less elegant that the software solution in terms of BOM price, PCB size and assembly time.

So i will go with the former (software) solution first, and see if it can satisfy my expectations.

Resolution vs. Clock frequency

In order to make our light source as natural as possible, we don’t want the PWM pulses to reach our LEDs. Instead, the LEDs should run on smooth DC. This requires filters somewhere between the PWM output of the µC and the LEDs. Preferrably, the filters are between the µC and the driver MOSFET, where there is little current. Higher current means larger filters.

Timer1 on the 328 has 16 bit and two output compare registers. We can use that to drive two PWM outputs with up to 16 bit resolution (0-65535). But this would reduce out PWM frequency to 16MHz216244Hz. So we have to make a of trade-off between switching frequency and resolution. Lower frequency also means larger filters.

VCCS to our help

I found a nice circuit called the Voltage Controlled Current Sink. It uses an opamp to create a constant current that corresponds to a control voltage. If we feed clean DC to the control input, we get a clean, constant current on the output. That control voltage can be generated using PWM and filters that have to handle only a low current.

It is advisable to drive (high-current) LEDs at constant current instead of constant voltage in order to have more control over the actual power consumption and light output, less dependent on manufacturing tolerances and thermal properties.

Software Choice

KiCad

First choice would be KiCad, which is open source software with binaries available for all major platforms. After playing around a bit with it, i find it has quite a lot of features, but some steps in the process are very unintuitive. Also, as with Inkscape, its integration with macOS isn’t too impressive (eg. having to close a tab with CMD+Q instead of CMD+W).

Pros:

  • Multi-layer support (>2)
  • Good mass-editing tools (eg. apply width to all traces of selected nets)
  • open-source
  • High quality parts in the standard library, including 3D models

Eagle

Of course, there is the industry standard “Eagle”. It’s commerical, closed-source software that has recently been acquired by Autodesk. Its usability and feature range is quite the same as KiCad – not too easy to get into for a rookie. Probably its main advantage is the vast amount of component libraries you find online, due to it being the de-facto standard. With no clear advantages (apart from parts libraries) over KiCad and the drawback that it’s closed source, i see no good reason for using it. Don’t get me wrong: It’s clearly good software – i’m just to lazy to learn all its peculiarities, considering the very basic demands my projects impose on an electronics design tool.

Upverter

Upverter is an online tool, that supports 2-layer layouts. It has a shared parts library, directly accessible from within the app. That makes it really easy and fast to use – not having to search for parts through google, download & install them. Out of those i tried, it’s also the most easy-to-understand solution for beginners. For its good usabilty, i choose it for all my projects, unless i need any special features that only Eagle or KiCad provide (eg. >2 layers).

General Electronics Design Process

The general process goes as follows:

Schematic

First step is always to design the schematic, which describes the desired electric properties of the system, basically by telling which components to use and how to hook them together.

  1. RTFM for each critical part (“Typical Application” often gives a quick overview over the required external components)
  2. Place symbols
  3. Draw connections between components
  4. Use flags if too many connections would cross
  5. Check that all required connections are established, and that there are no unintended ones

The result of that step should be an easily readable and editable drawing. Its “data only” representation is called the netlist, which is required in the next step.

Board Layout

Parts Placement

When the first version of the schematic is complete, i move over to the board layout. The design software typically takes a netlist and just puts all parts into a workspace, without arranging them. The software draws lines between pins that need an electrical connection.

Now the job is to rearrange all components smartly, so that you can later easily draw traces between all pins that need to be connected. There are some components that need to be placed close to each other, eg. decoupling capacitors need to be placed in close proximity to the power sinks they “supply”. Apart from that, one can try to arrange components in a way that minimizes the length of the connections between them, and more importantly, reduce crossovers of traces. Crossovers usually mean you need to use vias and route through another layer of the PCB.

Fabacademy intentionally lists 1208 sized components in the standard inventory because their pads are spaced apart wide enough so one can draw a route between them, using the component as a bridge.

Usually, i place large (& high pin count) components first, and arrange the small ones (& low pin count) around them.

Hint: When placing components close to each other, keep in mind your soldering process. Hand soldering requires quite some extra clearance so you can access all pins with the soldering iron, without frying any other parts.

Traces

As soon as all components have been arranged, i start to draw the traces. Before that, i set up a clearace constraint in the software to ensure that no pads or traces are closer together than the tool is capable to separate. Usually, i choose a minimum trace clearance of .3mm, to ensure the Othermill can work it with a 1/100” end mill, at least. In case i underrun that constraint while lying out the traces, the sofware can warn me early that my design might be impossible to fabricate with that tool.

For standard signal and low current power lines, i use the default .508mm trace width set in Upverter. For higher current lines (~1A and above), i use an online calculator to determine the appropriate trace width for given current rating and trace length. The 35mil copper layer on most standard PCB materials equals a weigth of 1ozft2.

Pours

As a final step, i define the pour areas. […]