This week I’ve been working on an interesting project with an Arduino at it’s core. The design is for the Briefcase Project, an exhibition which is opening in Wellington on August 8th. I’ll share more details closer to the date, but for now here are some little code snippets that I’ve found really useful, and maybe not so well documented elsewhere.
First of all, a useful way to achieve pretty accurate event timing without having to delve into the AVR’s Timer registers and learn about Interrupt Service Routines and so on. In your main loop() put:

int x;  //timing interval
long foo;  //timing placeholder
if (millis() - foo > x) {
 foo = millis();
 //run the following chunk of code every x milliseconds
}

This isn’t rocket science if you’ve seen it before, but if you’ve been stumbling around forever (like me) trying to figure out how to trigger multiple unrelated events then it’s genius! You can also replace millis() with micros() for greater precision.

I use that technique to create really simple audio output on the Arduino (bit-banging, they call it). Basically you select a pin and tell it to toggle every few microseconds. I like to use port manipulation to address pins, which I think is not so common in Arduino land but it makes sense to me.

void setup(){
 //set pins 2-7 as output
 DDRD |= B11111100;
}

long t1;  //timing placeholder
int f;  //output frequency in Hz

void loop() {
 if(micros() - t1 > 500000/f){
   t1 = micros();
   PORTD ^= B00000100; //toggle pin 2
 }
}

Now there’s a couple tricks in there. First DDRD is the direction register for port D, used to set which pins are inputs and which are outputs. The instruction DDRD |= B11111100; is a safe way to set pins 2-7 as outputs, leaving pins 0 and 1 alone, as they are needed for communication with the computer.

Then in the timing loop I’ve used 500000/f as the timing interval, where f is the resulting frequency in Hz. The 500,000 factor isn’t immediately obvious but it comes from 0.5*1,000,000 – 0.5 because the code fires every half cycle, and 1,000,000 to convert from seconds to microseconds.

The final trick is using a bitwise XOR to toggle a pin. In this case PORTD ^= B00000100; which toggles pin 2. The ^= operator allows you to toggle up to 8 pins simultaneously with one instruction (e.g. PORTD ^= B10110100; would toggle pins 2, 4, 5, and 7).

So there you have it, the simplest way to generate polyphonic audio on the Arduino. Stay tuned in the next couple of weeks to see what I’ve been using this code for…