sending audio on Pins 9 and 10

Dear all,

I've been studying the Make Project "Advances Arduino Sound Synthesis" and tried to expand it so that I can get two independent sine tone signals on the pwm pins 9 and 10.

I have the problem that I can't tune the outputs independently and I don't understand why. I'm using two interrupt service routines on timers 0 and 2 to set the values of the OCR1AL (for pin 9 ) and OCR1BL (for pin 10. I'm only outputting 8 bit values, hence OCR1AH and OCR1BH are ignored).

When I tune the two sine tones close to each other (e.g. by setting OCR0A = 50 and OCR2A = 60) they are producing the same frequency on both pins. If I tune them far apart from each other (e.g. by setting OCR0A = 50 and OCR2A = 100), they produce an octave. Any other intervallic ratios are impossible.

It seems as if the output of OCR1AL and OCR1BL influence each other, which doesn't really make sense to me.

Any help would be much appreciated! Underneath is the complete code.

Thanks!
Marko

/******** Load AVR timer interrupt macros ********/
#include <avr/interrupt.h>

/******** Sine wave parameters ********/
#define PI2     6.283185 // 2 * PI - saves calculating it later
#define AMP     127      // Multiplication factor for the sine wave
#define OFFSET  128      // Offset shifts wave to just positive values

/******** Lookup table ********/
#define LENGTH  256  // The length of the waveform lookup table
byte wave[LENGTH];   // Storage for the waveform

void setup() {
 /******** Populate the waveform lookup table with a sine wave ********/
 for (int i=0; i<LENGTH; i++) {
   float v = (AMP*sin((PI2/LENGTH)*i));  // Calculate current entry
   wave[i] = int(v+OFFSET);              // Store value as integer
 }

 /******** Set timer1 for 8-bit fast PWM output ********/
 DDRB = 6;// pinMode(9, OUTPUT) and pinMode(10, OUTPUT);
 TCCR1B  = (1 << CS10);    // Set prescaler to full speed 16MHz (no prescaling)
 TCCR1A = (1 << COM1A1);  // PWM pin to go low when TCNT1= OCR1A
 TCCR1A |= (1 << COM1B1);  // PWM pin to go low when TCNT1= OCR1B
 TCCR1A |= (1 << WGM10);   // Put timer into 8-bit fast PWM mode
 TCCR1B |= (1 << WGM12); 

 /******** Set up timer 2 to call ISR ********/
 TCCR2A = 0;               // We need no options in control register A
 TCCR2B = (1 << CS20);     // Set prescaller to divide by 8 // try TCCR2B = (1 << CS20) for finer range
 TIMSK2 = (1 << OCIE2A);   // Set timer to call ISR when TCNT2 = OCRA2

 /******** Set up timer 0 to call ISR ********/
 TCCR0A = 0;               // We need no options in control register A
 TCCR0B = (1 << CS20);     // Set prescaller to divide by 8 // try TCCR2B = (1 << CS20) for finer range
 TIMSK0 = (1 << OCIE0A);   // Set timer to call ISR when TCNT0 = OCRA2
   
 OCR2A = 60;               // sets the frequency of the generated wave has to be > TCNT2
 OCR0A = 30;
 sei();                    // Enable interrupts to generate waveform!
}

void loop() {  
}

/******** Called every time TCNT2 = OCR2B ********/
ISR(TIMER0_COMPA_vect) {  // Called each time TCNT2 == OCR2B
 static byte index = 0;    // Points to successive entries in the wavetable
 OCR1BL = wave[index++]; // Update the PWM output
 asm("NOP;NOP");         // Fine tuning
 TCNT0 = 6;              // Timing to compensate for time spent in ISR
}
/******** Called every time TCNT2 = OCR2A ********/
ISR(TIMER2_COMPA_vect) {  // Called each time TCNT2 == OCR2A
 static byte index = 0;    // Points to successive entries in the wavetable
 OCR1AL = wave[index++]; // Update the PWM output
 asm("NOP;NOP");         // Fine tuning
 TCNT2 = 6;              // Timing to compensate for time spent in ISR
}

Welcome to the Forum. Please read the two posts

How to use this forum - please read.
and
Read this before posting a programming question ...

at the top of this Forum on guidelines for posting here, especially the use of code tags which make the code look

like this

when posting source code files. It makes it easier to read, and can be copied with a single mouse click. Also, if you don't do it, some of the character sequences in the code can be misinterpred by the forum code as italics or funny emoticons.

Many questions can be answered by simply reading the documentation which is provided with the IDE, available under the help tab, or online here.

If you have already posted without using code tags, open your message and select "modify" from the pull down menu labelled, "More", at the lower left corner of the message. Highlight your code by selecting it (it turns blue), and then click on the "</>" icon at the upper left hand corner. Click on the "Save" button.

There are many other things that programmers do to make their code understandable. Please do them, as a courtesy to the members who volunteer their time to help you here. One is to use a standard indentation to clearly show the code blocks. So before posting the code, use Ctrl-T in the IDE to reformat the code in a standard format, which makes it easier for us to read.

By the way, PI is already defined in the IDE:

#define PI 3.1415926535897932384626433832795

So you don't need

#define PI2     6.283185 // 2 * PI - saves calculating it later

and you can say

    float v = (AMP*sin((PI*2/LENGTH)*i));  // Calculate current entry

assuming that everything else works.