Wednesday, May 22, 2013
I just posted a new article to my Embeddedrelated.com blog about endianness and serial communication. It discusses what endianness is and why it's important to serial communication. It also has a tutorial on transmitting data from a microcontroller to a PC an plotting it using Octave. This is part of the data processing aspect of my stoplight costume. I'm using Octave to develop DSP techniques to process the accelerometer data to determine whether or not the person wearing the costume is in motion - part of this is getting the data out of the microcontroller and on to the PC. That's what the article discusses. When I start documenting the software aspects of the costume I'll write about the actual DSP techniques used to process the data, but for now you can read the article.
Sunday, May 5, 2013
Several things about the overall design and approach for my Halloween costume have been bothering me lately:
Accelerometer WoesThe MEMS accelerometer I'm using to detect motion is not well-suited to the task which I'm using it for. I've come to the conclusion that MEMS accelerometers don't so much measure acceleration as they simply register it. Discerning what exactly is happening in the outside world from the output of the accelerometer is a bit of a dicey proposition. Still, I have made significant progress on the issue thanks to an Electronics Stackexchange post by Olin Lathrop detailing a method to derive meaningful data from the cacophony a MEMS accelerometer produces. Using his approach I've been able to process the data to identify what I will call 'motion events'. It can't tell you how fast you're currently going, but it can pretty well determine if you've started to move from a stand-still. This is all the information I need from the accelerometer. Despite this success, the methods used to process the data will probably introduce significant delay when detecting these events - possibly on the order of 1 or 2 seconds. Still, it is just a Halloween costume so I'm going to try not to feel too bad about this.
Power Usage/Battery LifeThe power usage of the board is still pretty poor - it will eat through a 9V battery pretty quickly. A costume isn't going to be impressive if it runs out of juice in a few minutes. To some extent there's just no way around this: LEDs are power-hungry. If I want any significant amount of light they have to draw 10-20mA each. Multiply that by 30 LEDs and that's a lot of power. Of course, they don't have to be that bright all the time. I built PWM into the design so that they could be dimmed when necessary - that's worth a bit of extra power. I will also get some gains my simplifying my power architecture as I mentioned in a previous post and I can also use low-power modes on the microcontroller and modify my design to allow the accelerometer to sleep when it's not used. I'll also be adding a battery monitor circuit so the microcontroller can read the current state of the battery and act accordingly (although I don't know yet what actions it might take). These fixes don't matter nearly as much as the LEDs though, which leads me into my next point...
My first instinct for driving LEDs was to use a linear approach and control the brightness with PWM. The reason for this was that it was simple and straightforward. It's also not the most efficient approach: a fair amount of power is dissipated in the biasing resistor. That's wasted power - it makes no light. This can be avoided by driving the LEDs with current instead of voltage. The benefit of this approach is that very little power is wasted: most of it is dissipated in the LEDs which is exactly where you want it. For best efficiency a switch-mode current driver should be used. There are many off-the-shelf ICs that can be used for this purpose but to minimize costs and maximize board space you can build your own switcher out of discrete components. In this case, it's worthwhile to use the ULN2803 as the switching element and the microcontroller to generate the PWM. The ULN2803 is designed to switch inductive loads and has most of the protection circuitry necessary. It would be nice to have some sort of current-sensing ability but this difficult to implement and isn't strictly necessary - the current system doesn't use any feedback and it doesn't suffer. A full description of the switching circuit can wait for another day but it's wortwhile to note that this circuit doesn't have to be on the main microcontroller board: most of the components can be located on the LED boards. This allows the microcontroller board to drive LEDs either using a switch-mode current approach or in the current linear approach. I prefer to let the microcontroller board be more versatile, so I think I'll modify the LED boards to use this new approach if it ever comes to it. With only minor changes to the microcontroller board it will be able to support both approaches.
Accelerometer InterfaceThis has proved more complex than I first imagined. Two main issues:
- Because they're not running on the same supply the microcontroller can't directly control the accelerometer pins. This means I can't set its measurement range, run a self-test or put the accelerometer to sleep with the microcontroller: I have to use jumpers instead.
- I should have gotten an I2C accelerometer. While analog measurements are fun, they're prone to noise and I have high-currents running around this board (more on that in a second). It is possible to design the board such that the high-current paths and noise are isolated from the accelerometer signal path but if we're optimizing the signal path I vote for making it as short as possible by leaving it entirely inside the accelerometer. You can't get much shorter than that.
Noise has been a significant problem with this design. The main issue is the high-current path used to drive the LEDs. The first time I tried to drive the LEDs and read the accelerometer I was surprised: the accelerometer data was garbage. The scope showed that there was so much noise on the accelerometer lines that they were worthless. Sure enough, turning off the LEDs made it all go away. After examining my layout I wanted to kick myself even more: the power supply for the microcontroller is drawn from the same trace as the power supply for the LEDs. The noise induced by the high-current PWM switching is not isolated from the microcontroller at all! Part of the reason for this is that the layout is so crowded that I couldn't really do it any other way. Why is the layout so crowded? Two reasons:
- It's a single-layer board so it was difficult just to get all the traces going to the right places.
- I used through-hole components which are large and bulky.
I've been considering some approaches to minimize the noise but I don't think I will be able to remove it completely. One approach I considered was to filter the PWM coming out of the microcontroller to provide a smooth control voltage to the ULN2803 rather than a jerky square wave. One problem with this is that it will force the ULN2803 to work in linear mode rather than saturation mode - this will dissipate more power inside that IC and subsequently use up the battery quicker. That's not a tradeoff I'm willing to make right now, so I think I'm going to settle for a better layout and adding a large capacitor on the supply pins of the ULN2803. This will have the effect of minimizing the length of the traces that have switched high-currents on them and also separate those traces from more sensitive areas of the board.
There are thankfully a small number of fixes which can remedy most of the problems I've discussed here:
- Redesign the board and use all surface-mount components
- Replace the voltage-mode accelerometer with an I2C accelerometer
- Simplify the power architecture to power the LEDs from the battery directly and use a single switching 3.3V power supply to power the accelerometer and microcontroller
- Utilize low-power modes on the microcontroller and accelerometer to save power
- Physically separate the 3.3V and 9V portions of the board and place the ULN2803 much closer to the 9V battery. Add a large capacitor on the supply pins of the ULN2803.
- Modify the ULN2803 circuitry to support both the current LED driver approach and the switch-mode current driver approach
Looks like I'll have to redesign the board and possibly upgrade to a two-layer, professionally-made board. More on this as I develop it.