All the code discussed in this post is available on Github
A few weeks before leaving my last hardware gig, I was asked to give a presentation to the new batch of interns about how we get the job done. Discussing the ethos and pathos of design philosophy isn't very difficult, but as usual in the world of hardware it seemed prudent to provide a practical demonstration. Given that this fell outside the purview of my typical deliverables, and because I had a bit of time to fool around, I decided to play with some new technologies to show what the modern world of software can do for electrical folks in an afternoon — So I tacked together an electron app with a micro-controller, a few power supplies, and an accelerometer to demonstrate some EE basics.
Engineering is mostly about making the best possible product with the resources at hand, like throwing a whisk into a power drill to make mashed potatoes last Thanksgiving:
The software toolchain we use in the world of hardware is dated, because in general we value consistency and reliability over the bleeding edge for our analytical tools. If we are already designing our hardware to be as forward thinking as possible, we don't necessarily want to be spending time learning a new programming language every week — however, in order to combat stagnation, it's good practice to dip our feet back into the pool of available software to see what improvements time has wrought. But what problems does an electrical hardware engineer need to solve with software? Plenty. Here's one.
Briefly, a common issue in the world of hardware design is power distribution. There are two classes of power supplies common in consumer electronics, each with their own benefits and detriments; choosing which one to use and when is difficult even for experienced engineers because often times the difference is subtle, subjective, and user-facing. Disturbingly, the discerning factor is sometimes mathematical and therefore requires statistical analysis.
These two most common classes of DC power distribution (“voltage regulators”) are switching supplies such as a buck regulator and linear supplies such as low-dropout regulators (LDOs) — the former are efficient and create lots of electrical noise, the latter are inefficient but very clean. Bucks are more expensive than LDOs, but less are needed because they can handle more power and do so far more efficiently, therefore we need to choose carefully which is appropriate for a given design. As such, I designed a circuit with one of each to demonstrate the differences between them.
Here's the buck regulator:
And here's the LDO:
Now that we've prototyped the design in a breadboard, let's check the conventional wisdom that, by design, the buck regulator is noisy and the LDO is clean:
I know this may look complicated, but it really isn't. The LDO is the bottom signal, and the Buck is the top — These are images captured from an oscilloscope, a piece of equipment designed to measure how voltage or current changes in the time domain. Each horizontal division on the y-axis represents 10 millivolts (mV), or about 1/150th of the voltage of a AA battery. That may not seem like a lot, but the electronics in something like a modern-day cellphone are extremely sensitive and sometimes even a few millivolts can be make or break in a design. Why does the buck look so much 'fuzzier' than the LDO?
It's all part of their operation. Bucks use Pulse Width Modulation (PWM) and a low-pass filter to efficiently provide lots of power, at the cost of additional noise. The SW signal shows the input to the inductive low-pass filter, and the buck signal is zoomed in very closely on the output. Notice how the buck signal looks like a sawtooth, rising while the SW signal is high and falling when it is low:
So! Yikes, that buck regulator is messy — 30mV of peak-to-peak noise looks pretty stark next to ~5mV of noise on the LDO. Will that electrical fuzz have any effect on the accelerometer? The short answer is “yes”, because barring complete electrical isolation, signals will propagate through a system until they attenuate to such a degree as to be unmeasurable. And these guys are connected by a wire, so the only isolation we’re getting is inside the accelerometer itself. This attenuation within the part is called “Power Supply Rejection Ratio”, or "PSRR", and is a key metric in low-noise systems.
So what about the long answer? In theory, we now know that electrical noise will appear in some form on the signal the accelerometer is measuring, but how much of a real-world effect will this noise have? For that, we need to do some experiments. And to do some experiments, we turn to the spooky world of software.
Modern(-ish) Software Tools for Hardware
At the time of writing, the zeitgeist in the world of Electrical Engineering is to use Python for instrument control and data analysis, thanks to fantastic libraries like PyVISA and Matplotlib. There are a great many advantages to this toolchain for measuring and crunching numbers in large datasets, as well as displaying this data in austere charts and graphs. However, most of the applications written in this tool-chain end up seeming arcane, working exclusively in the command line and outputting accurate, if highly academic, data.
Consider these hydroponics metrics from an old project.
Not super clear, but it gets the idea across for people who are familiar with the subject. Alas, therein lies the rub. For a business, compelling data is only useful if all of the key decision-making folks understand it, which means the most effective data is also beautiful and accessible. So when presenting our data to a larger audience such as an exec team, we built a the following web view instead.
With this goal in mind, we can break up the task into three parts:
- Collecting the data
- Analyzing the data
- Visualizing the data
Collecting the Data
The first step in collecting our data is picking our hardware and designing the circuit. In this case, I used spare parts from past projects, namely:
With some assorted passive components and a USB breakout board for power, these are all we'll need. The Teensy microcontroller will allow us to communicate with our accelerometer over I2C, and we can swap the power supply by moving wires around our breadboard. Thanks to Sparkfun's pre-existing driver code, we should be able to plug this in and see some raw data on the serial port using minicom:
Great! Now that we have the raw data, we can move on to analysis.
Analyzing the Data
# Clone this repository git clone https://github.com/electron/electron-quick-start # Go into the repository cd electron-quick-start # Install dependencies npm install # Run the app npm start
And to add serial port functionality, we can grab it off of npm inside the application directory:
npm install serialport
After this, all of the code handling the serial port setup can go inside of the
main.js file, my implementation of which can be found on the project github.
See? If the σ is small, this curve could be very tight
So how do we calculate this for our signal?
The data is received in a continuous stream at roughly the speed of the I2C bus, so our sample rate is in the 10's of kHz — this means our data points will pile up fast. If we try and analyze the entire set and re-analyze any time a new point is added, we'll run into bottlenecks on the CPU and indeed on the renderer (one second would yield over 10,000 points, more pixels probably than the horizontal axis of your display). Therefore, we'll analyze the signal in chunks, pushing the data into a queue of limited size (say 100) and running the analysis only there; this has the added benefit of keeping our calculation current, as we are then calculating the standard deviation of the last hundred milliseconds or so.
To calculate the standard deviation of this chunk of data is simple, we can do it ourselves (it really isn't so hard). Or because we're using a programming language with incredible library support, we can use MathJS.
First we install it:
npm install mathjs
Then, we use it:
var math = require('mathjs'); var sigma_x = math.std(dataset);
Cool! So we're ready for the last step.
Visualizing the Data
Now that we have an electron app that, behind the scenes, collates and analyzes our data, we are ready to display it for the world to see. For this, we need a couple of things:
- Some HTML and CSS like you'd see on any website
For the former, I elected to use HTML5 Boilerplate as it handles most of the things I don't want to touch (404 pages, obvious CSS) and lets me cobble together a very basic
main.css and call it a day.
For the latter, I chose Chart.js because it's very pretty and very concise, isn't it?
After combining the boilerplate and Chart.js, we're good to go!
After all that work, what were the results?
It looks like the dogma is correct, the accelerometer is much noisier when powered by the buck! The standard deviation on each axis is ~1.5-2x higher on the noisier power source, so it looks like the PSRR on this part is not very good.
Does this mean when designing with an accelerometer (or any sensor) we should always use an LDO, no questions asked? No! Depending on the application, this kind of noise can be fine. These units here are in micro-g's, or 1/1000 the force of gravity; if we're measuring acceleration in a car, this noise here is probably acceptable. Finely measuring the motion of a smart phone? Maybe not so much.
Bottom line is, you gotta do the math to know for sure. And thanks to the ever evolving world of software, the tools for doing so are getting better every day.