If you’ve ever turned a rotary encoder or pushed a cursor button and had it skip a step or two, you’ve suffered directly from button bounce. My old car stereo and my current in-car GPS navigator both have this problem, and it drives me nuts. One button press should be one button press. How hard is that to get right?
In the last session of Embed with Elliot, we looked into exactly how hard it is to get right and concluded that it wasn’t actually all that bad, as long as you’re willing to throw some circuitry at the problem, or accept some sluggishness in software. But engineers cut corners on hardware designs, and parts age and get dirty. Making something as “simple” as a button work with ultra-fast microcontrollers ends up being non-trivial.
And unsurprisingly, for a problem this ubiquitous, there are a myriad of solutions. Some are good, some are bad, and others just have trade-offs. In this installment, we’re going to look at something special: a debouncer that uses minimal resources and is reasonably straightforward in its operation, yet which can debounce along with the best of ’em.
In short, I’ll introduce you to what I think is The Ultimate Debouncer(tm)! And if you don’t agree by the end of this article, I’ll give you your money back.
Continue reading “Embed With Elliot: Debounce Your Noisy Buttons, Part II”
“Psst…hey buddy! Wanna see the sweetest little debouncing routine this side of Spokane? C’mon over here. Step right over those bit-shift operators, they don’t bite. Now look at this beauty right here: I call her The Ultimate Debouncer(tm)!”
Everybody who works with microcontrollers eventually runs into the issue of switch bounce or “chatter”, and nearly everyone has their own favorite solution. Some fix it in hardware, others fix it in software. Some hackers understand chatter, and others just cut-and-paste the classic routines. Some folks even try to ignore it, and they might even get lucky, but everyone’s luck runs out sometimes.
In the next two “Embed with Elliot” installments, I’ll look a little bit at bouncing, look into doing hardware debouncing both the simple way and the right way, and build up a basic software routine that demonstrates some of the principles and which works just fine, though it’s not optimized. We’ll be laying the groundwork.
In the next installment, I’ll let you in on my personal favorite debounce routine. It’s a minor tweak on a standard, but with some special sauce that’s worth spreading around. I’ll call it the Ultimate Debouncer(tm), but will it stand up to the scrutiny of the Hackaday commenteers? (How’s that for a cliffhanger?!?)
For now, though, let’s look into switch bounce and the standard ways to fix it in hardware and software.
Continue reading “Embed With Elliot: Debounce Your Noisy Buttons, Part I”
Why Buffer? Because buffers cut you some slack.
Inevitably, in our recent series on microcontroller interrupts, the question of how to deal with actual serial data came up. In those examples, we were passing one byte at a time between the interrupt service routine (ISR) and the main body of code. That works great as long as the main routine can handle the incoming data in time but, as many people noted in the comments, if the main routine takes too long the single byte can get overwritten by a new one.
The solution? Make some storage room for multiple bytes so that they can stack up until you have time to process them. And if you couple this storage space with some simple rules for reading and writing, you’ve got yourself a buffer.
So read on to see how to implement a simple, straightforward circular buffer in C for microcontrollers (or heck, for anything). Buffers are such a handy tool to have in your programming toolkit that you owe it to yourself to get familiar with them if you’re not already.
Continue reading “Embed With Elliot: Going ‘Round With Circular Buffers”
Welcome to part three of “Interrupts: The Good, the Bad, and the Ugly”. We’ve already professed our love for interrupts, showing how they are useful for solving multiple common microcontroller tasks with aplomb. That was surely Good. And then we dipped into some of the scheduling and priority problems that can crop up, especially if your interrupt service routines (ISRs) run for too long, or do more than they should. That was Bad, but we can combat those problems by writing lightweight ISRs.
This installment, for better or worse, uncovers our least favorite side effect of running interrupts on a small microcontroller, and that is that your assumptions about what your code is doing can be wrong, and sometimes with disastrous consequences. It’s gonna get Ugly
TL;DR: Once you’ve started changing variables from inside interrupts, you can no longer count on their values staying constant — you never know when the interrupt is going to strike! Murphy’s law says that it will hit at the worst times. The solution is to temporarily turn off interrupts for critical blocks of code, so that your own ISRs can’t pull the rug out from under your feet. (Sounds easy, but read on!)
Continue reading “Embed With Elliot: Interrupts, The Ugly”
We love interrupts in our microcontroller projects. If you aren’t already convinced, go read the first installment in this series where we covered the best aspects of interrupts.
But everything is not sunshine and daffodils. Interrupts take place outside of the normal program flow, and indeed preempt it. The microcontroller will put down whatever code it’s running and go off to run your ISR every time the triggering event happens. That power is great when you need it, but recall with Spider-Man’s mantra: With great power comes great responsibility. It’s your responsibility to design for the implicit high priority of ISRs, and to make sure that your main code can still get its work done in between interrupt calls.
Put another way, adding interrupts in your microcontroller code introduces issues of scheduling and prioritization that you didn’t have to deal with before. Let’s have a look at that aspect now, and we’ll put off the truly gruesome side-effects of using interrupts until next time.
Continue reading “Embed With Elliot: Interrupts, The Bad”
What’s the biggest difference between writing code for your big computer and a microcontroller? OK, the memory and limited resources, sure. But we were thinking more about the need to directly interface with hardware. And for that purpose, one of the most useful, and naturally also dangerous, tools in your embedded toolchest is the interrupt.
Interrupts do exactly what it sounds like they do — they interrupt the normal flow of your program’s operation when something happens — and run another chunk of code (an interrupt service routine, or ISR) instead. When the ISR is done, the microcontroller picks up exactly where it left off in your main flow.
Say you’ve tied your microcontroller to an accelerometer, and that accelerometer has a “data ready” pin that is set high when it has a new sample ready to read. You can wire that pin to an input on the microcontroller that’s interrupt-capable, write an ISR to handle the accelerometer data, and configure the microcontroller’s interrupt system to run that code when the accelerometer has new data ready. And from then on everything accelerometer-related happens automagically! (In theory.)
This is the first part of a three-part series: Interrupts, the Good, the Bad, and the Ugly. In this column, we’ll focus on how interrupts work and how to get the most out of them: The Good. The second column will deal with the hazards of heavyweight interrupt routines, priority mismatches, and main loop starvation: the Bad side of interrupts. Finally, we’ll cover some of the downright tricky bugs that can crop up when using interrupts, mainly due to a failure of atomicity, that can result in logical failures and corrupted data; that’s certainly Ugly.
Continue reading “Embed With Elliot: Interrupts, The Good…”
Raindrops on roses, and whiskers on kittens. They’re ok, but state machines are absolutely on our short list of favorite things.
There are probably as many ways to implement a state machine as there are programmers. These range from the terribly complex, one-size-fits-all frameworks down to simply writing a single
switch...case block. The frameworks end up being a little bit of a black box, especially if you’re just starting out, while the
switch...case versions are very easy to grok, but they don’t really help you write clear, structured code.
In this extra-long edition of Embed with Elliot, we’ll try to bridge the middle ground, demonstrating a couple of state machines with an emphasis on practical coding. We’ll work through a couple of examples of the different ways that they can be implemented in code. Along the way, we’ll Goldilocks solution for a particular application I had, controlling a popcorn popper that had been hacked into a coffee roaster. Hope you enjoy.
Continue reading “Embed With Elliot: Practical State Machines”