Hey, would you be willing to share your code & a pic of your circuit? It might be a little much for me on the hardware side, but I'd like to take a look anyway
Where do you buy parts in Ottawa?
Best local sources of parts that I know of are:Gervais Electronics on Industrial near St Laurent, and Active Components on Merivale. Both have walk-in retail with stands of resistors, connectors, and the like and a catalog of components backing them up. For ordering-in I find digikey.ca to be best, $8 flat fee shipping, no customs hassles, and very quick.
Here's a few pics of the Cylon Pumpkin's hardware and the code. Happy to help with any questions.

//version 2 of the cylon pumpkin.
//incorporates wav player with soft playback option
//plays cylon noise at low volume til motion is detected.
//starts cylon noise as soon as motion is detected rather than at beginning of scan
//waveform modified to reduce pop at beginning of playback
#include <stdint.h>
#include <avr/interrupt.h>
#include <avr/io.h>
#include <avr/pgmspace.h>
#define SAMPLE_RATE 8000
//Charlieplexing a cylon pumpkin display
const int cpin1=4; //Charlieplexing pin 1
const int cpin2=5; //Charlieplexing pin 2
const int cpin3=6; //Charlieplexing pin 3
const int cpin4=7; //Charlieplexing pin 4
const int cpin5=8; //Charlieplexing pin 5
const int cpin6=9; //Charlieplexing pin 5
int clow=1;
int chigh=25; //low and high scan limits
int s1=clow;
int delta=1; //scan start, direction
int csfast=50;
int csslow=200; //fast and slow scans
int pirpin=3;
int ledpin=13; //pins for motion detector and standalone led
#include "sounddata.h"
int speakerPin = 11;
volatile uint16_t sample;
byte lastSample;
boolean softly=true;
void setup() {
Serial.begin(9600);
pinMode(ledpin,OUTPUT);
//give the sensor some time to calibrate
Serial.print("calibrating sensor ");
for(int i = 1; i <= 25; i++){
cplex(i);
Serial.print(".");
delay(1000);
}
Serial.println(" done");
Serial.println("SENSOR ACTIVE");
delay(50);
startPlayback();
}
void loop(){
static boolean excited=false; //excited is true when motion is detected
int csspd=csslow; //by default eye scan is slow
if(digitalRead(pirpin)==HIGH){
csspd=csfast;
digitalWrite(ledpin,HIGH);
if (!excited){
softly=false;
startPlayback();
excited=true;
}
}
else {
csspd=csslow;
excited=false;
softly=true;
digitalWrite(ledpin,LOW);
}
int s2=s1+delta; //inner scan
cplex2(s2,s1,csspd); //cplex 2 positions
s1=s1+delta;
if (s1>=chigh){
s1=chigh-1;
delta=-1;
}
if (s1<=clow){
s1=clow+1;
delta=1;
startPlayback();
}
}
void cplex2(int which,int which2, int t){ //cplex 2 positions for t ms
unsigned long when=millis()+t; //when to stop
while(millis()<when){
Serial.print(" t=");
Serial.println(t);
cplex(which);
delay(2);
cplex(which2);
delay(2);
}
}
void cplex(byte digit){
pinMode(cpin1,INPUT);
pinMode(cpin2,INPUT);
pinMode(cpin3,INPUT);
pinMode(cpin4,INPUT);
pinMode(cpin5,INPUT);
pinMode(cpin6,INPUT);//safe mode
digitalWrite(cpin1,LOW);
digitalWrite(cpin2,LOW);
digitalWrite(cpin3,LOW);
digitalWrite(cpin4,LOW);
digitalWrite(cpin5,LOW);
digitalWrite(cpin6,LOW);
int cpinh[]={
cpin1, //0 isn't used
cpin1,cpin2,cpin1,cpin3,cpin1, //1-5
cpin4,cpin1,cpin5,cpin1,cpin6, //6-10
cpin5,cpin6,cpin4,cpin6,cpin3, //11-15
cpin6,cpin2,cpin6,cpin2,cpin5, //16-20
cpin2,cpin4,cpin2,cpin3,cpin4 }; //21-25
int cpinl[]={
cpin1, //0 isn't used
cpin2,cpin1,cpin3,cpin1,cpin4,
cpin1,cpin5,cpin1,cpin6,cpin1,
cpin6,cpin5,cpin6,cpin4,cpin6,
cpin3,cpin6,cpin2,cpin5,cpin2,
cpin4,cpin2,cpin3,cpin2,cpin3 };
pinMode(cpinh[digit],OUTPUT);
digitalWrite(cpinh[digit],HIGH);
pinMode(cpinl[digit],OUTPUT);
digitalWrite(cpinl[digit],LOW);
}
// This is called at 8000 Hz to load the next sample.
ISR(TIMER1_COMPA_vect) {
if (sample >= sounddata_length) {
if (sample == sounddata_length + lastSample) {
stopPlayback();
}
else {
// Ramp down to zero to reduce the click at the end of playback.
OCR2A = sounddata_length + lastSample - sample;
}
}
else {
if(softly){
OCR2A = pgm_read_byte(&sounddata_data[sample])>>2;
} //reduce volume of playback
else{
OCR2A = pgm_read_byte(&sounddata_data[sample]); //full volume playback
}
}
++sample;
}
void startPlayback()
{
pinMode(speakerPin, OUTPUT);
// Set up Timer 2 to do pulse width modulation on the speaker
// pin.
// Use internal clock (datasheet p.160)
ASSR &= ~(_BV(EXCLK) | _BV(AS2));
// Set fast PWM mode (p.157)
TCCR2A |= _BV(WGM21) | _BV(WGM20);
TCCR2B &= ~_BV(WGM22);
// Do non-inverting PWM on pin OC2A (p.155)
// On the Arduino this is pin 11.
TCCR2A = (TCCR2A | _BV(COM2A1)) & ~_BV(COM2A0);
TCCR2A &= ~(_BV(COM2B1) | _BV(COM2B0));
// No prescaler (p.158)
TCCR2B = (TCCR2B & ~(_BV(CS12) | _BV(CS11))) | _BV(CS10);
// Set initial pulse width to the first sample.
if (softly)
OCR2A = pgm_read_byte(&sounddata_data[0])>>2;
else
OCR2A = pgm_read_byte(&sounddata_data[0]);
// Set up Timer 1 to send a sample every interrupt.
cli();
// Set CTC mode (Clear Timer on Compare Match) (p.133)
// Have to set OCR1A *after*, otherwise it gets reset to 0!
TCCR1B = (TCCR1B & ~_BV(WGM13)) | _BV(WGM12);
TCCR1A = TCCR1A & ~(_BV(WGM11) | _BV(WGM10));
// No prescaler (p.134)
TCCR1B = (TCCR1B & ~(_BV(CS12) | _BV(CS11))) | _BV(CS10);
// Set the compare register (OCR1A).
// OCR1A is a 16-bit register, so we have to do this with
// interrupts disabled to be safe.
OCR1A = F_CPU / SAMPLE_RATE; // 16e6 / 8000 = 2000
// Enable interrupt when TCNT1 == OCR1A (p.136)
TIMSK1 |= _BV(OCIE1A);
lastSample = pgm_read_byte(&sounddata_data[sounddata_length-1]);
if (softly) lastSample=lastSample>>2;
sample = 0;
sei();
}
void stopPlayback()
{
// Disable playback per-sample interrupt.
TIMSK1 &= ~_BV(OCIE1A);
// Disable the per-sample timer completely.
TCCR1B &= ~_BV(CS10);
// Disable the PWM timer.
TCCR2B &= ~_BV(CS10);
digitalWrite(speakerPin, LOW);
}