One of [Dooievriend]’s friends recently pressed him into service to write software for a 3d spectrum analyzer/VU that he made. The VU is a fairly complex build: it’s made up of 1280 LEDs in a 16x16x5 matrix controlled by a PIC32 clocked at 80MHz. [Dooievriend] wrote some firmware for the PIC that uses a variation on a discrete Fourier transform to create a 3D VU effect.
When [Dooievriend] set out to design the audio analyzing portion of the firmware, his mind jumped to the discrete Fourier transform. This transform calculates the amplitude in a series of frequency bins in the audio—seemingly perfect for a VU. However, after some more research, [Dooievriend] decided to implement a constant Q transform. This transform is very similar to a Fourier transform, but it takes into account the logarithmic way that the human ear interprets sound.
[Dooievriend] started implementing the constant Q transform using an interrupt-based sampler, but he quickly ran into issues with slow floating-point math on his PIC32 (which doesn’t have a hardware floating-point unit). Thankfully he rewrote his code using fixed-point math, and the transform runs nearly real-time. Check out the video after the break to see the VU in action, and a second video that gives some details on the hardware build.
To prevent data corruption when using multiple SPI devices on the same bus, care must be taken to ensure that they are only accessed from within the main loop, or from the interrupt routine, never both. Data corruption can happen when one device is chip selected in the main loop, and then during that transfer an interrupt occurs, chip selecting another device. The original device now gets incorrect data.
For the last several weeks, [Paul] has been working on a new Arduino SPI library, to solve these types of conflicts. In the above scenario, the new library will generate a blocking SPI transaction, thus allowing the first main loop SPI transfer to complete, before attempting the second transfer. This is illustrated in the picture above, the blue trace rising edge is when the interrupt occurred, during the green trace chip select. The best part, it only affects SPI, your other interrupts will still happen on time. No servo jitter!
This is just one of the new library features, check out the link above for the rest. [Paul] sums it up best: “protects your SPI access from other interrupt-based libraries, and guarantees correct setting while you use the SPI bus”.
The screenshot on the right shows [Quinn Dunki’s] computer project displaying a Hello World program. Well, it’s only showing the word Hello right now, but the concept is the same. This proves that native 6502 code is running on the processor and reliably outputting data through its VGA hardware. That’s a welcome achievement after watching so much work go into this project.
But with anything this complex you can’t expect to make progress without finding bugs. And this step in the journey had a pretty big one in store for [Quinn]. After writing the assembly code and loading it into the machine she was dismayed to find that there were dropped characters all over the place. Now she shows a screenshot and says it’s easily recognizable as a race condition — proving she has a bigger brain than us.
The problem is a pair of uninterruptible processes running on the same AVR chip (part of the GPU she built). They are fighting with each other for control of the processor cycles and she fixed it by making the daughter board seen in the image above. It moves one of the time-critical processes out of that single AVR chip to fix the issue by using an IDT7200L FIFO SRAM chip.
This week, we are bringing you the final video in our series where [Jack] uses the 3pi robot as a fancy development board for the ATmega328p processor. Today’s video deals with interrupts. If you have been wanting to have your programs do more than one thing simultaneously, interrupts are the solution. [Jack] discusses various ways that you can use interrupts in your programs and then shows how he created a interrupt routine that drives the 3pi’s beeper. He also shows the routines that enable, disable, and control the interrupt.
Since this is the last post for this series of videos, we are posting the code used for all of the previous videos. Click here to grab a copy.
For our next series of videos, we are going to attempt something more challenging so most likely we will be taking a couple of weeks off to do some development before presenting it here. Stay tuned folks, we’ll be back.
Video is after the break…
In case you missed any of the previous videos, check out these links:
Interrupts are the name of the game for more functional microcontroller firmware. [Rajendra] just posted a tutorial covering all of the interrupt types for the PIC 16F688 microcontroller. He gives an overview of all of the major points: what an interrupt is, what causes interrupts, how to read the datasheet (often overlooked) to set up interrupts, and finally he applies it to a test platform and a bit of code.
We’ve been playing around with an Arduino again over the weekend and are a bit frustrated with the restricted access to interrupts. That issue deals with AVR interrupts, a topic with which we’re already well acquainted. But we work with PIC hardware much less often and it’s fun to explore how the other half does things, both in hardware and in code.
Microcontroller interrupts are one of the big tools in our embedded programming arsenal. They make the chip listen for particular events, and once detected they stop what they’re doing and run a separate set of code called and Interrupt Service Routine. We’ve come across two fairly new tutorials on the subject that you should check out if you’re not yet a master on the topic. One is a ProtoShack tutorial on ATmega168 external interrupts, and the other is a Newbie’s Guide to AVR Interrupts by [Dean Camera] (we’ve been a fan of his tutorials for some time). Both cover a range of topics from what interrupts are, to avoiding the common problems of volatile data types and the compiler optimization caveats.
What can you do with interrupts? External interrupts can be used to wake up a project like this LED menorah from sleep mode. Interrupts can be used to monitor a timer for a certain value or an overflow for use in generating a pulse-width modulation signal. The TI Launchpad uses an interval timer interrupt for button debouncing in projects like this code which was ported from an AVR chip. The source for both is available if you wanted to compare how the two differ.
Interrupts are powerful. Learn them, love them, use them.
The guys at Nerdkits have put together this tutorial on connecting a PS/2 keyboard to a microcontroller. Though this tutorial is written for one of the kits they sell, you should be able to apply this to pretty much any microcontroller. It is also a lesson in using interrupts instead of polling. They have several pre built examples ready to download as well as source code for the basic setup.