A car is a rolling pile of hundreds of microcontrollers these days — just ask any greybeard mechanic and he’ll start his “carburetor” rant. All of these systems and sub-systems need to talk to each other in an electrically hostile environment, and it’s not an exaggeration to say that miscommunication, or even delayed communication, can have serious consequences. In-car networking is serious business. Mass production of cars makes many of the relevant transceiver ICs cheap for the non-automotive hardware hacker. So why don’t we see more hacker projects that leverage this tremendous resource base?
The backbone of a car’s network is the Controller Area Network (CAN). Hackaday’s own [Eric Evenchick] is a car-hacker extraordinaire, and wrote up most everything you’d want to know about the CAN bus in a multipart series that you’ll definitely want to bookmark for reading later. The engine, brakes, doors, and all instrumentation data goes over (differential) CAN. It’s fast and high reliability. It’s also complicated and a bit expensive to implement.
In the late 1990, many manufacturers had their own proprietary bus protocols running alongside CAN for the non-critical parts of the automotive network: how a door-mounted console speaks to the door-lock driver and window motors, for instance. It isn’t worth cluttering up the main CAN bus with non-critical and local communications like that, so sub-networks were spun off the main CAN. These didn’t need the speed or reliability guarantees of the main network, and for cost reasons they had to be simple to implement. The smallest microcontroller should suffice to roll a window up and down, right?
In the early 2000s, the Local Interconnect Network (LIN) specification standardized one approach to these sub-networks, focusing on low cost of implementation, medium speed, reconfigurability, and predictable behavior for communication between one master microcontroller and a small number of slaves in a cluster. Cheap, simple, implementable on small microcontrollers, and just right for medium-scale projects? A hacker’s dream! Why are you not using LIN in your multiple-micro projects? Let’s dig in and you can see if any of this is useful for you. Continue reading “Embed With Elliot: LIN is for Hackers”→
I should really like I2C more than I do. In principle, it’s a brilliant protocol, and in comparison to asynchronous serial and SPI, it’s very well defined and clearly standardized. On paper, up to 127 devices can be connected together using just two wires (and ground). There’s an allowance for multiple clock-masters on the same bus, and a way for slaves to signal that the master to wait. It sounds perfect.
In reality, the tradeoff for using only two wires is a significantly complicated signalling and addressing system that brings both pitfalls and opportunities for debugging. Although I2C does reduce the number of signal wires you need, it gets dangerous when you have more than a handful of devices on the same pair of wires, and you’re lucky when they all conform to the same standard. I’ve never seen twenty devices on a bus, much less 127.
But still, I2C has its place. I2C was designed to connect up a bunch of slower, cheaper devices without using a lot of copper real estate compared to its closest rival protocol: SPI. If you need to connect a few cheap temperature sensors to a microcontroller (and their bus addresses don’t clash) I2C is a great choice. So here’s a guide to making it work when it’s not working.
Serial Peripheral Interface (SPI) is not really a protocol, but more of a general idea. It’s the bare-minimum way to transfer a lot of data between two chips as quickly as possible, and for that reason alone, it’s one of my favorites. But that doesn’t mean that everything is hugs and daffodils. Even despite SPI’s simplicity, there are still a few ways that things can go wrong.
In the previous article in this series, inspired by actual reader questions, I looked into troubleshooting asynchronous serial connections. Now that you’ve got that working, it’s time to step up to debugging your SPI bus! After a brief overview of the system, we’ll get into how to diagnose SPI, and how to fix it.
It’s the easiest thing in the world — simple, straightforward serial data. It’s the fallback communication protocol for nearly every embedded system out there, and so it’s one that you really want to work when the chips are down. And yet! When you need it most, you may discover that even asynchronous serial can cost you a few hours of debugging time and add a few gray hairs to your scalp.
In this article, I’m going to cover most (all?) of the things that can go wrong with asynchronous serial protocols, and how to diagnose and debug this most useful of data transfer methods. The goal is to make you aware enough of what can go wrong that when it does, you’ll troubleshoot it systematically in a few minutes instead of wasting a few hours.
If there’s one thing that a lot of small microcontrollers hate (and that includes the AVR-based Arduini), it’s floating-point numbers. And if there’s another thing they hate it’s division. For instance, dividing 72.3 by 12.9 on an Arduino UNO takes around 32 microseconds and 500 bytes, while dividing 72 by 13 takes 14 microseconds and 86 bytes. Multiplying 72 by 12 takes a bit under 2.2 microseconds. So roughly speaking, dividing floats is twice as slow as dividing (16-bit) integers, and dividing at all is five to seven times slower than multiplying.
There’s a whole lot of the time that you just don’t care about speed. For instance, if you’re doing a calculation that only runs infrequently, it doesn’t matter if you’re using floats or slow division routines. But if you ever find yourself in a tight loop that’s using floating-point math and/or doing division, and you need to get a bit more speed, I’ve got some tips for you.
Some of these tips (in particular the integer division tricks at the end) are arcane wizardry — only to be used when the situation really calls for it. But if you’re doing the same calculations repeatedly, you can often gain a lot just by giving the microcontroller numbers in the format it natively understands. Have a little sympathy for the poor little silicon beasties trapped inside!
To wrap up my quick tour through the wonderland of make and makefiles, we’re going to look at a pair of possible makefiles for building ARM projects. Although I’m specifically targeting the STM32F407, the chip on a dev board that I have on my desk, it’s reasonably straightforward to extend these to any of the ST ARM chips, and only a bit more work to extend it to any ARM processor.
One of the main contributions of an IDE like Arduino or mbed or similar is the ease of including external libraries through pull-down menus. If you’ve never built a makefile-based project before, you might be surprised how it’s not particularly more difficult to add libraries to your project. Continue reading “Embed with Elliot: ARM Makefile Madness”→
Direct-digital synthesis (DDS) is a sample-playback technique that is useful for adding a little bit of audio to your projects without additional hardware. Want your robot to say ouch when it bumps into a wall? Or to play a flute solo? Of course, you could just buy a cheap WAV playback shield or module and write all of the samples to an SD card. Then you wouldn’t have to know anything about how microcontrollers can produce pitched audio, and could just skip the rest of this column and get on with your life.
But that’s not the way we roll. We’re going to embed the audio data in the code, and play it back with absolutely minimal additional hardware. And we’ll also gain control of the process. If you want to play your samples faster or slower, or add a tremolo effect, you’re going to want to take things into your own hands. We’re going to show you how to take a single sample of data and play it back at any pitch you’d like. DDS, oversimplified, is a way to make these modifications in pitch possible even though you’re using a fixed-frequency clock.
The same techniques used here can turn your microcontroller into a cheap and cheerful function generator that’s good for under a hundred kilohertz using PWM, and much faster with a better analog output. Hackaday’s own [Bil Herd] has a nice video post about the hardware side of digital signal generation that makes a great companion to this one if you’d like to go that route. But we’ll be focusing here on audio, because it’s easier, hands-on, and fun.