summaryrefslogtreecommitdiff
path: root/content/posts/wifi-led-driver/index.rst
blob: 0cc27c9936b29fc4e371f68c06429a2d6d7fef8b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
---
title: "Wifi Led Driver"
date: 2018-05-02T11:31:03+02:00
---

Project motivation
==================

.. FIXME finished project picture with LED tape
.. raw:: html
    
    <figure>
        <img src="images/lyza_board_in_case.small.jpg">
        <figcaption>The completed driver board installed in the 3D-printed case. This device can now be connected to
        12V and two segments of LED tape that can then be controlled trough Wifi. The ESP8266 module goes on the pin
        header on the left and was removed for this picture.
        </figcaption>
    </figure>

After the `multichannel LED driver`_ was completed, I was just getting used to controlling LEDs at 14-bit resolution.
I liked the board we designed in this project, but at 32 channels it was a bit large for most use cases. Sometimes I
just want to pop a piece of LED tape or two somewhere, but I don't need a full 32 channels of control. I ended up
thinking that a smaller version of the 32-channel driver that didn't require a separate control computer would be
handy. So I sat down and designed a variant of the design with only 8 channels instead of 32 and an on-board ESP8266_
module instead of the RS485_ transceiver for WiFi connectivity.

The Electronics
===============

The schematic was mostly copy-pasted from the 32-channel design. The PCB was designed from scratch. This time, I went
for a 5x7cm form factor to allow for enough room for all connectors and to give the ESP8266_'s WiFi antenna enough
space. The board has two 5-pin Phoenix-style_ for two RGB-White (RGBW) tapes and one 2-pin Phoenix-style_ connector for
12V power input. The control circuitry and the serial protocol are unchanged, but the STM32_ now talks to an ESP-01_
module running custom firmware.

The LEDs are driven using a 74HC595_ shift register controlling a bunch of AO3400_ MOSFETs_, with resistors in front of
the MOSFETs_' gates to slow down the transitions a bit to reduce brighntess nonlinearities and EMI_ resulting from
ringing of the LED tape's wiring inductance.

The board has two spots for either `self-resettable fuses (polyfuses) <polyfuse_>`__ or regular melting-wire fuses_ in
a small SMD_ package, one for each RGBW output. For low currents the self-resettable fuses should be okay but at higher
currents their `trip times get long enough that they become unlikely to trip in time to save anything
<littlefuse-16r-datasheet_>`__, so plain old non-resettable fuses would be the way to go there.

.. FIXME finished board photos
.. FIXME board with test tape picture

.. raw:: html

    <figure>
        <figure class="side-by-side">
            <img src="images/schematic.png">
            <figcaption>
            The schematic of the driver board, with the ESP8266 on the top left, the STM32 microcontroller for LED
            modulation below, the shift register in the middle and the LED drivers and outputs on the right. 
            <a href="resource/lyza_schematic_and_pcb.pdf">Download PDF</a>
            </figcaption>
        </figure><figure class="side-by-side">
            <img src="images/layout.png">
            <figcaption>
            The board layout with the top side being visible. The top side contains the footprint for the ESP8266, the
            microcontroller, fuses, filter cap, connectors and the shift register. The LEDs are connected on the left,
            with one connector per LED tape segment. The power input connector is on the bottom right. The LED driver
            MOSFETs are in small SOT-23 packages on the back of the board. Since this board is not intended for
            super-high currents, the MOSFETs are adequately cooled just through the board's copper planes.
            <a href="resource/lyza_schematic_and_pcb.pdf">Download PDF</a>
            </figcaption>
        </figure>
    </figure>

.. raw:: html
    
    <figure>
        <img src="images/lyza_boards.small.jpg">
        <figcaption>The completed PCBs of this project (front) and the `multichannel LED driver`_ project the driver
        circuitry was derived from (back).
        </figcaption>
    </figure>


The Firmware
============

The STM32_ firmware only had to be slightly modified to accomodate the reduced channel count since the protocol remains
unchanged. The ESP firmware is based on esphttpd_ by Spritetm_. The modifications to the webserver firmware are pretty
basic. First, the UART console has been disabled since I use the UART to talk to the STM32. The few bootloader messages
popping out the UART on boot are not an issue, since they're unlikely to contain the fixed 32-bit address prefix the
serial protocol requires for the STM32_ to do anything.

Second, I added LED control by adding drivers for the serial protocol and a bunch of colorspace conversion functions.
When I first tested the prototype software, I noticed that color reproduction was extremely poor. When I just sent a
HSV_ rainbow fade from a python command line, the result looked totally wrong. The fade did not seem to go at a constant
speed and some colors, in particular yellow, orange and greens, were not visible at all. The problem turned out to be a
stark mismatch of the red, green and blue channels of the LED tape and less-than-optimal color reproduction of the pure
colors. I decided to properly measure the LED tape's color reproduction so I could compensate for it in software. This
turned out to be an extremely interesting project, the details of which you can read in my `LED characterization`_
article.

Third, I updated the built-in websites with some ad-hoc documentation on how to use the thing and a basic interface for
LED control.

.. FIXME screenshot of firmware website

Making an enclosure
===================

To be actually useful, the driver needed a robust enclosure. Bare PCBs are nice for prototyping, but for actually
putting the thing anywhere it needs a case to protect it against random destruction.

The board has four mounting holes with comfortable spacing in its corners to allow easy mounting inside a 3D-printed
case. The case itself is described in an OpenSCAD_ script. To make it look a little nicer, a little 3D relief is laid
into the lid. The 3D relief is generated with a bit of blender magic. The source STL_ model is loaded into blender, then
blender's amazingly flexible rendering system is used to export a depth map of a projection of the model as a PNG_ file.
This depth map is then imported as a triangle mesh into OpenSCAD_.

For the relief to look good, I chose a rather high resolution for the depth map. This unfortunately leads to extreme
memory use and processing time on the part of OpenSCAD_, but since I have access to a sufficiently fast machine that is
not a problem. Just be careful if you try opening the OpenSCAD_ file on your machine, OpenSCAD_ will probably crash
unless you're on a beefy machine or interrupt it when it starts auto-rendering the file.

The board is mounted into the enclosure using knurled insert nuts that are pressed into a 3D-printed hole using a bit of
violence.

.. FIXME openscad screenshot
.. FIXME enclosure parts
.. FIXME finished enclosure with board inside

.. raw:: html

    <figure>
        <figure class="side-by-side">
            <img src="images/lyza_case_raw.small.jpg">
            <figcaption>The 3D-printed case with threaded inserts before painting.</figcaption>
        </figure><figure class="side-by-side">
            <img src="images/lyza_case_complete.small.jpg">
            <figcaption>The 3D-printed case with the board installed after painting. This was my first attempt at
            painting a 3D-printed case so it looks pretty bad.</figcaption>
        </figure>
    </figure>

.. _`multichannel LED driver`: {{<ref "posts/multichannel-led-driver/index.rst">}}
.. _`LED characterization`: {{<ref "posts/led-characterization/index.rst">}}
.. _ESP8266: https://en.wikipedia.org/wiki/ESP8266
.. _RS485: https://en.wikipedia.org/wiki/RS-485
.. _Phoenix-style: https://www.phoenixcontact.com/online/portal/de?uri=pxc-oc-itemdetail:pid=1757019&library=dede&tab=1
.. _STM32: http://www.st.com/resource/en/datasheet/stm32f030f4.pdf
.. _ESP-01: http://www.watterott.com/de/ESP8266-WiFi-Serial-Transceiver-Modul
.. _74HC595: http://www.ti.com/lit/ds/symlink/sn74hc595.pdf
.. _AO3400: http://aosmd.com/pdfs/datasheet/AO3400.pdf
.. _MOSFETs: https://en.wikipedia.org/wiki/MOSFET
.. _EMI: https://en.wikipedia.org/wiki/Electromagnetic_interference
.. _polyfuse: https://en.wikipedia.org/wiki/Resettable_fuse
.. _SMD: https://en.wikipedia.org/wiki/Surface-mount_technology
.. _fuses: https://en.wikipedia.org/wiki/Fuse_(electrical)
.. _littlefuse-16r-datasheet: http://m.littelfuse.com/~/media/electronics/datasheets/resettable_ptcs/littelfuse_ptc_16r_datasheet.pdf.pdf
.. _OpenSCAD: http://www.openscad.org/
.. _STL: https://en.wikipedia.org/wiki/STL_(file_format)
.. _PNG: https://en.wikipedia.org/wiki/Portable_Network_Graphics
.. _esphttpd: https://github.com/Spritetm/esphttpd
.. _Spritetm: http://spritesmods.com/
.. _`HSV`: https://en.wikipedia.org/wiki/HSL_and_HSV