So Yeah,
I'm using an 8bit R2R DAC on an Arduino Uno, I have it wired to pins 2-9, with a potentiometer wired as a resistor divider to A0 to act as a frequency control. I can write variable overflowCounter directly to the DAC and that gives me a perfect ramp wave on my oscilloscope with no problem. However when I use the same variable as a lookup for my sine_wave[] wavetable it outputs a bunch of noise with a whole cycle of the waveform pic behid the following link (https://dl.dropbox.com/u/19840532/IMG_20120730_101838.jpg)
//avr-libc library includes
#include <avr/io.h>
#include <avr/interrupt.h>
#define LEDPIN 14
byte sine_wave[256] = {
0x80, 0x83, 0x86, 0x89, 0x8C, 0x90, 0x93, 0x96,
0x99, 0x9C, 0x9F, 0xA2, 0xA5, 0xA8, 0xAB, 0xAE,
0xB1, 0xB3, 0xB6, 0xB9, 0xBC, 0xBF, 0xC1, 0xC4,
0xC7, 0xC9, 0xCC, 0xCE, 0xD1, 0xD3, 0xD5, 0xD8,
0xDA, 0xDC, 0xDE, 0xE0, 0xE2, 0xE4, 0xE6, 0xE8,
0xEA, 0xEB, 0xED, 0xEF, 0xF0, 0xF1, 0xF3, 0xF4,
0xF5, 0xF6, 0xF8, 0xF9, 0xFA, 0xFA, 0xFB, 0xFC,
0xFD, 0xFD, 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFE, 0xFE, 0xFD,
0xFD, 0xFC, 0xFB, 0xFA, 0xFA, 0xF9, 0xF8, 0xF6,
0xF5, 0xF4, 0xF3, 0xF1, 0xF0, 0xEF, 0xED, 0xEB,
0xEA, 0xE8, 0xE6, 0xE4, 0xE2, 0xE0, 0xDE, 0xDC,
0xDA, 0xD8, 0xD5, 0xD3, 0xD1, 0xCE, 0xCC, 0xC9,
0xC7, 0xC4, 0xC1, 0xBF, 0xBC, 0xB9, 0xB6, 0xB3,
0xB1, 0xAE, 0xAB, 0xA8, 0xA5, 0xA2, 0x9F, 0x9C,
0x99, 0x96, 0x93, 0x90, 0x8C, 0x89, 0x86, 0x83,
0x80, 0x7D, 0x7A, 0x77, 0x74, 0x70, 0x6D, 0x6A,
0x67, 0x64, 0x61, 0x5E, 0x5B, 0x58, 0x55, 0x52,
0x4F, 0x4D, 0x4A, 0x47, 0x44, 0x41, 0x3F, 0x3C,
0x39, 0x37, 0x34, 0x32, 0x2F, 0x2D, 0x2B, 0x28,
0x26, 0x24, 0x22, 0x20, 0x1E, 0x1C, 0x1A, 0x18,
0x16, 0x15, 0x13, 0x11, 0x10, 0x0F, 0x0D, 0x0C,
0x0B, 0x0A, 0x08, 0x07, 0x06, 0x06, 0x05, 0x04,
0x03, 0x03, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x03,
0x03, 0x04, 0x05, 0x06, 0x06, 0x07, 0x08, 0x0A,
0x0B, 0x0C, 0x0D, 0x0F, 0x10, 0x11, 0x13, 0x15,
0x16, 0x18, 0x1A, 0x1C, 0x1E, 0x20, 0x22, 0x24,
0x26, 0x28, 0x2B, 0x2D, 0x2F, 0x32, 0x34, 0x37,
0x39, 0x3C, 0x3F, 0x41, 0x44, 0x47, 0x4A, 0x4D,
0x4F, 0x52, 0x55, 0x58, 0x5B, 0x5E, 0x61, 0x64,
0x67, 0x6A, 0x6D, 0x70, 0x74, 0x77, 0x7A, 0x7D
};
volatile unsigned long overflowCounter =0; //using an unsigned long as I think eventually I'll need an absolutely huge variable to count the timer rollovers, needs to be volatile so the interrupt code can modify it...
void setup(){
pinMode(LEDPIN, OUTPUT);
//initialise Timer1
timerSetup();
portMappingSetup();
}
ISR(TIMER2_COMPA_vect)
{
digitalWrite(LEDPIN, !digitalRead(LEDPIN));
DACwriter(sine_wave[overflowCounter]);
overflowCounter++;
}
void loop(){
OCR2A = map(analogRead(A5), 0, 1026, 1, 255);
}
//the following function contains all the gubbins to make the Compare Match Timer work
void timerSetup(){
cli(); // Disable interrupts while setting registers
TCCR2A = 0; // Reset control registers
TCCR2B = 0; // Reset control registers
TCCR2A |= (1 << WGM21); // Clear Timer2 on Compare Match (CTC) Mode
TCCR2B |= (1 << CS21); // Prescaler x8 for Timer2
OCR2A = 225
; // Set compared value
ASSR &= ~(1 << AS2); // Use system clock for Timer/Counter2
TIMSK2 = 0; // Reset Timer/Counter2 Interrupt Mask Register
TIMSK2 |= (1 << OCIE2A); // Enable Output Compare Match A Interrupt
sei();
}
//setup port manipulation for DAC
void portMappingSetup(){
DDRD |= B11111100; //bit mask to get exclude the serial TX and RX
DDRB |= B00000111; //bit mask to exclude all but channels 8 and 9
}
void DACwriter(int x) {
int num = x; //store x into num to act as addres for location in wavetable
int numShiftD = num << 2; //shift num up by 2 to avoid serial pins on port D (this eats the 2 digits shifted off the end
PORTD = numShiftD; //send lowest significant digits to port D
int numShiftB = num >> 6; //shift num down by 6 to capture the two bits eaten by the above operation
PORTB = numShiftB; //send remaining two bits to port B and thence to the DAC
}