[First, I’d like to apologize for my too long absence. I’m now a full time hardware engineer, since two years. My job and the projects I’m working on are exciting, but also quite demanding of my energy and time. My level of laziness being constant, I gave up on writing articles (even if I still do electronic projects at home). This new article is about something I built last year. That’s being said, let’s start:]
[TL;DR: scroll to the end of the article to see more photos, a video and github]
For these of you who have been following my blog, my biggest project so far is the USB temperature logger. I enjoyed making it, I like the outcome, but it has one problem: if you’re not an engineer or a bit technical, it’s not cool. I wanted to make something people would see and find cool (you can add vanity to my laziness). Something with light and not an other LED strip attached to an Arduino. And this time, I wanted an enclosure.
The inspiration came from movies and a poorly lit bathroom: a bathroom washbasin mirror, with lamps around it. To spice things up, it had to be at least dimmable.
Something like that, but round:
After some experiments with lightbulbs and triacs, I decided it was a bad idea to have 220V-powered light bulbs (made of thin and sharp glass), ten centimeters from my head, when my face and hands are soaked with water … But I still wanted something looking like lightbulbs.
The solution came form Paulmann, a german manufacturer offering these things:
It’s supposed to be a customizable system of light bulbs (they offer different sizes, shapes and colours for the “bulb” and you can screw halogen, fluo or LED sockets inside). A bit on the expensive side (10€ for a set) but I was only interested in the glass bulb anyway (the bulbs can be bought separately, for cheaper).
With these, I would be able to use LEDs solving many problems:
- 60Hz whine
- System complexity (no more 220V, triacs, isolation to handle, just PWM)
I also wanted the possibility to display time with the lights, so I decided to fit twelve of them, on a round shape. Here are my first sketches:
Because the LEDs will be driven by a microcontroller, I could add some cool features:
- A motion sensor (so the mirror lights up when one enters the bathroom)
- A capacitive touch sensor dimmer
- An internal clock, to adjust the the luminosity according to the time of the day or night.
Let’s make a list of early parts/requirements:
- LEDs: x12 High power (~10W each) warm white
- Microcontroller with 12 PWM, USB, RTCC
- Capacitive sensor (slider)
- Movement detector (PIR type, as small as possible)
- Off the shelf power supply
- The frame of the mirror should contain all the electronics
- A mirror (duh!)
I started by finding the right dimensions and design for the enclosure/frame. With standard mirror sizes (ie. the ones available at my local hardware store), a size and spacing of the bulbs that would look harmonious, I got an inner frame diameter of 52cm (Ø50cm mirror) —20 inches. The frame is 8 cm (3,15″) wide and the bulbs have a diameter of 6 cm (2,36″).
It’s made of wood. All the electronics and LEDs are mounted on the bottom ring, the upper ring has holes for the bulbs and supports the sides of the frame. Some pictures of the construction:
The face and base rings, with spacers glued to the face ring. (upside-down)
Front ring, with holes for the LEDs. The wooden pieces act like spacers between the front and back rings and support the 1mm thin side plywood (just bent and glued around).
Completed, with pivoting support for the mirror.
With the bulbs. They are glued with silicone joint from inside. The silicone gives some compliance, so the bulbs can move instead of immediately breaking at their base if hit.
At the same time, I worked on the LEDs and the driver:
I chose Bridgelux BXRA-40E0810-A-00 LEDs. Warm white and star shaped footprint. 980 lumens @28,1V 350mA.
For the controller, I found the TS19371 Boost white LED driver, with PWM input and OVP. From Taiwan Semiconductor. As it’s a one-off project, I didn’t care about long-term availability. The other components are quite standard.
The LED current is calculated with the following equation:
Iled = 95mV / Rf
I have a 0,22 Ohm feedback resistor, resulting in a 430mA calculated LED current, which doesn’t match the values from the datasheet’s schematics or the current I measured.
Plot of the input power (@12V) and the LED power (@28V) vs. the PWM duty cycle:
Which gives the following efficiency (vs. PWM duty cycle):
Not bad, especially the most comfortable luminosity is between 40 and 80%.
There’s a bit of “whine” at some PWM values, probably due to the two big ceramic capacitors. (piezo effect). Later, I added big value capacitors (1000uF) across the power supply, every two driver boards.
Even if the LEDs are from a good brand and have a good efficacy, they get very hot without a heatsink. The problem is, the mirror frame is closed and doesn’t have any airflow inside. Putting a fan is of course, out of question, same with vent holes.
My solution was to mount the LEDs on aluminium rods, which act like a heat storage. I got twelve of these rods, 20m diameter and 25mm high, for one Euro each, already cut, on eBay:
(first revision of the PCB)
Here’a graph of the temperature increase of a LED at the maximal voltage and current (100% PWM):
As you can see, no heatsinking isn’t an option. With the aluminium rods, the LEDs can be at 100% for quite long (bathroom timeframe). The software takes care of dimming the light after 15 minutes. There’s also a temperature sensor on one of the heatsinks. The maximal intensity is anyway too bright and shouldn’t happen too often. The startup luminosity is about 50%.
Some photos of the LEDs and drivers construction:
Heatsinks with tapped holes (plus one mounting hole –M3– on the underside).
Driver PCBs with solder paste — ready to be populated.
The next step was the capacitive touch dimmer.
I used the Atmel’s AT42QT2160 Qslide – Matrix Sensor IC. Quite powerful and versatile. It can have up to 16 keys or/and one slider of 8 keys/bits (0..255). For once, Atmel provides an exhaustive data sheet, plus a lot of design material for the keys/sliders/wheels. (Now, you can even get footprints for Altium designer).
It works by sending a charge pulse to one side of an electrode (the sensing element) and sampling it on the other side, comparing the changes over time. Fingers change the capacity of the electrode, as well as the intensity of the sensed electrical field. If the resulting signal goes below a threshold, the chip counts it as a touch. The electrodes can be laid out to form a linear pattern, making a slider or a wheel and the chip configured to output an X value corresponding to the touch position on the slider or wheel.
I followed Atmel’s recommendations for the design of my slider. I managed to get a very good definition, even through the thick wood. (On the first version of the mirror, the sensor was on the side, sensing touches through the 1mm thin plywood. After the update, it’s on the front and still works great through 5mm of plywood!).
Because of my requirements of sensitivity, wood thickness, length and definition, I designed a “Mutualy Coulped – One Dimensional – Two layer – Resistively Interpolated” Slider:
(Atmel’s “Touch Sensors Design Guide”)
The sampling signal is emitted on the Xn lines (top PCB side) sequentially and sampled on Y line (bottom side).
Which looks like that in real life:
Bottom (fingers) side with the Y sampling traces.
Top side: Xn electrodes. 0.8mm PCB, so it could be bent and follow the shape of the mirror frame. Even if the bend radius isn’t too small, I used 0402 components and tried to place them parallel to the bend. The PCB has a footprint for an EEPROM, sharing the sensor’s i2c bus. (The first microcontroller I used didn’t have any EEPROM).
The data sheet gives two important measures to make:
The sampling capacitor Cs voltage. It shouldn’t exceed -0,25V and the ramp should be linear.
The charge transfer pulse (measured with a coin on the sensing surface): Should be square.
The AT42QT2160 connects to my microcontroller via an i2c interface. It has a lot of registers to tweak configuration and parameters for the touch detection. The sensitivity can be adjusted without having to change components on the PCB.
A “change” output pin can be used as an interrupt and relieves the micro controller from sending continuous interrogations on the i2c bus.
The touch sensor attached to the frame with double sided tape (on the front of the frame, after the update). Note the silicone joint holding the bulbs and the wooden spacers supporting the sides of the frame.
The motion sensor.
PIR sensors can be tricky to implement, so I took the easy way and used the Zmotion Detection Module II from Zilog. It costs 10€ from Digikey and only needs a 3.3V power supply and an RS232 interface.
I won’t write a lot about it, first because its implementation is straight forward and second, because I don’t use it anymore after the update, so I didn’t write the code to support it in the new microcontroller.
It features a small microcontroller and a pre calibrated PIR element. Plug and Play.
It also has parameters to tweak the sensibility of the detection and can even tell the direction of the detected movement (going from left to right or right to left).
An other reason why I chose this sensor board, is because the PIR lens is really tiny and once mounted inside the mirror, it’s almost invisible (because of the shape of the bathroom, the sensor was on the side, even more difficult to see).
The light coming from the LEDs was messing with the sensor and it detected a continuous movement once the mirror was on. I had to isolate the sensor board with aluminium foil and tape. Not a big deal.
Putting everything together and giving it a brain.
Ok, now we have our mirror and the frame, 12 LEDs, the touch dimmer and the movement sensor. How do we make everything work?
For the first version, I used a PIC18F87J50. An Xmega256A3BU after the update. I won’t start a debate on Microchip vs. Atmel (that should be a future article), especially the mirror worked exactly the same with both of the microcontrollers.
If you’re familiar with these two microcontrollers, you’ll know they don’t have 12 PWM outputs.
So how can they control the intensity of each of the LEDs?
Simple: Software PWM. Because the LED driver has its own switching frequency (1,2MHz) and an enable input that can be used as PWM dimming, the PWM frequency coming from the micro controller doesn’t need to be too high. In my case, it’s between 120 and 300Hz. Enough to have a good persistence of vision.
(actually, the software of the first prototype was a bit slower and did a cool stroboscopic effect, you could see the water drops going up when you were taking a shower. Psychedelic, but not that funny at 7am, half asleep).
To implement my software PWM, I’m using a timer which fires an interrupt and increases a 8 bit “PWM counter” variable. Each LED has a variable with the PWM value it’s set to. In the same interrupt, I compare each of the LED variables to the PWM counter, setting the corresponding LED pin high, if the LED PWM value is higher than the PWM counter, setting it low if the LED PWM value is smaller than the counter.
There is a few more subtle things:
I’m using the Xmega virtual ports feature, it speeds up the execution of the interrupt (one ASM instruction instead of three or four).
Each LED value is compared sequentially, so they don’t switch on or off at exactly the same time. You cal call it a sort of crude spread-spectrum PWM 🙂
I’m using a 16MHz crystal to clock the Xmega, because the internal RC oscillator had too much jitter (which isn’t a big deal here, it just annoyed me).
Here’s the interrupt jitter with the internal RC oscillator:
And (almost) the same measure after switching the oscillator to an external crystal:
3,5us vs. 10ns Not bad.
I’m also using the USB interface to be able to monitor the microcontroller and set a few parameters (date/time, touch sensor sensibility, read the temperature etc.):
I’m a big fan of the TCN75 i2c (or similar) temperature sensors, but here, I wanted something I could directly attach to one of the LEDs heatsink:
It’s a Thermistor ( NTCALUG03A473H ), a temperature-dependant resistor. I hooked it up to the Xmega’s A/D converter.
My voltage to temperature conversion is very crude, an array of voltages every 5°C, plus an interpolation to get 3°C resolution. I didn’t need more, because I’m just using it to dim the LEDs when the heatsink temperature is too high.
The thermistor, screwed to the side of the upper LED heatsink.
An other feature I found cool to implement, is an anti-fog system. To avoid condensation on the mirror when you’re taking a shower, the mirror is heated up with a resistive wire attached with kapton tape on the back side of the mirror.
The one I chose has a 6,93 Ohms resistance per meter. It gives a current of 1,73A per meter with a 12V power supply.
It’s annoying to work with, because it’s very springy. And it’s even more annoying to solder, even if the data sheet states the opposite.
Unfortunately, the way I attached the mirror to the frame when I built it one year ago prevented me from taping the wire till the center, so only the outer part of the mirror is heated. It works nevertheless not too bad to keep the center free of condensation.
I have two loops of this wire in parallel, taking 2A in total and heating up to 50-60°C. The kapton tape presses the wire against the mirror, ensuring a good enough thermal transfer.
The heating is switched on and off by the microcontroller via a MOSFET transistor (2KS4017).
Resistive wire kaptoned to the mirror’s back.
The power supply.
I said I didn’t want to play with AC and the whole mirror was running on 12Vdc. So what powers it?
A 150W 12V AC-DC converter. 150W is more than enough to power the 12 LEDs and the 2A resistive wire.
In the first version of the mirror (and the first bathroom), it was sitting on the side and the mirror was switched on and off by the motion sensor.
After I moved to my new place, it’s actually connected to the bathroom’s socket for the washbasin light and the mirror is activated with the switch on the wall (it’s a double switch, one for the ceiling lamp, the other for the mirror).
I put some white fabric sleeve on the wires, so they don’t look too bad.
Putting things together.
The twelve LEDs are attached round the enclosure’s baseplate with a screw, from the back of the baseplate to a taped hole in the bottom of each heatsink. The driver boards are held with a wood screw, directly on the baseplate.
The driver boards’ power supply is just wired in parallel (the thick blue and brown wires). Each driver’s PWM input is connected to the microcontroller board.
First power up. I taped the bulbs to the heatsinks, because the LEDs are really powerful and hurt eyes if looked directly at them.
The development “simulator”
Every time I wanted to develop new functions for the firmware, I had to take the mirror from the bathroom, put it on my bench, open the enclosure, connect the AVR JTAG debugger, program the firmware, test it and put the mirror back in the bathroom. Not very convenient.
Because I made several ATxmega256A3BU boards and I order my PCBs from iTead Studio, so I always get ten of them, I could replicate the mirror on my bench, with 3mm LEDs instead of the Bridgelux ones. It has all the functionalities of the mirror, so I can take as much time as I want to write the firmware and to test it:
When I’m sure the new firmware is ok, I just update the real mirror via the USB bootloader. (I made a cutout on the top of the enclosure for the USB plug, next to the 12V DC jack socket).
Photos of the first version/bathroom:
(The PIR motion sensor lens is clearly visible on the side of the frame)
When I moved to a new flat, after the update:
And a quick video showing the main features:
The firmware sources can be downloaded from my github:
The first version of the mirror has been running for one year without any problem. The updated version, for six months now. I wish I had written a series of articles along the design and build of this project, because even if now I still remember all of my process and decisions, the resulting article is a bit long and not detailed enough.
Concerning the mirror, having this big wooden piece the mirror is glued to, prevented me from putting the heating on all of its surface. It works ok, but sometimes it fails to keep the center of the mirror fog free.
If I have time, I’ll try to find a way to put resistive wire on the middle too.
Because the 150W AC/DC power supply has a lot of capacitance and the 12V rail has big capacitors, there’s a one or two seconds lag between the moment you switch the mirror off and the LEDs going actually off. It would be a nice to implement a 220V detection circuit, so the microcontroller knows when the AC current disappears and can switch the LEDs off quicker (and also with an “animation”).