# Sine wave using arduino uno

Hi all,
I am an adruino hobbyist, i want to make sine wave using arduino uno,
for that i using timer0 as interrupt, OCR0A set to 17 for 3.6khz interrupt(16000000/(100hz*36 interval)/256-1),
If i am using only one pwm pin i am getting correct frequency but when i enable two pwm pin i am getting only half if the frequency, kindly advise what is wrong and how to correct it.
.................................
This code i am getting correct frequency at PWM pin 9.

//
ISR(TIMER0_COMPA_vect)
{
OCR1A=(256+((((sin(num*3.14/180))256))))/2;
//OCR1B=(256+((((sin(num
3.14/180))*256))))/2;
num=num+10;
if(num >= 360)
{
num = 0;
}
}
//
............................
This code i am getting only half of the previous frequency at PWM pin 9,10

//
ISR(TIMER0_COMPA_vect)
{
OCR1A=(256+((((sin(num*3.14/180))256))))/2;
OCR1B=(256+((((sin(num
3.14/180))*256))))/2;
num=num+10;
if(num >= 360)
{
num = 0;
}
}
//

Please post your entire code (in code tags according to the forum guidelines, please!). There are obviously variables and code that you haven't shown, that can impact how that ISR operates. We can't help with what we can't see.

Some issues I can see:
Timer0 is used by the core for timing.
You recalculate the same floating point expression twice.
You needlessly convert radians to degrees, when the whole thing would work perfectly well in radians.

``````#include <avr/io.h>
#include <avr/interrupt.h>

static int num=0;
static int num1=0;
boolean toggle0 = 0;
#define FREQ_POT A0
#define FREQ_MIN 17
#define FREQ_MAX 174
#define POT_MIN 0
#define POT_MAX 1023

void setup(){

Serial.begin(9600);
TCCR0A = 0;
TCCR0B = 0;
TCNT0  = 0;
OCR0A = 17;
TCCR0A |= (1 << WGM01);
TCCR0B |= (1 << CS02);
TIMSK0 |= (1 << OCIE0A);
/*** Timer 1 ***/
TCCR1B &= ~(_BV(CS12));
TCCR1B &= ~(_BV(CS11));
TCCR1B |= _BV(CS10);
TCCR1B &= ~(_BV(WGM13));
TCCR1B &= ~(_BV(WGM12));
TCCR1B &= ~(_BV(WGM11));
TCCR1B |= _BV(WGM10);
TCCR1A |= _BV(COM1A1);
TCCR1A &= ~(_BV(COM1A0));
TCCR1A |= _BV(COM1B1);
TCCR1A &= ~(_BV(COM1A0));

TCCR2B &= ~(_BV(CS22));
TCCR2B &= ~(_BV(CS21));
TCCR2B |= _BV(CS20);
TCCR2B &= ~(_BV(WGM22));
TCCR2B &= ~(_BV(WGM21));
TCCR2A |= _BV(WGM20);
TCCR2A |= _BV(COM2A1);
TCCR2A &= ~(_BV(COM2A0));
pinMode(11,OUTPUT);
pinMode(10,OUTPUT);
pinMode(9,OUTPUT);
OCR2B=0;
OCR1B=0;
OCR1A=0;

}
void loop()
{

}
ISR(TIMER0_COMPA_vect)
{
OCR1A=(256+((((sin(num*3.14/180))*256))))/2;
OCR1B=(256+((((sin(num*3.14/180))*256))))/2;
num=num+10;
if(num >= 360)
{
num = 0;
}
}
``````

in code tags according to the forum guidelines, please!

``````/*** Timer 1 ***/
TCCR1B &= ~(_BV(CS12));
TCCR1B &= ~(_BV(CS11));
TCCR1B |= _BV(CS10);
TCCR1B &= ~(_BV(WGM13));
TCCR1B &= ~(_BV(WGM12));
TCCR1B &= ~(_BV(WGM11));
TCCR1B |= _BV(WGM10);
TCCR1A |= _BV(COM1A1);
TCCR1A &= ~(_BV(COM1A0));
TCCR1A |= _BV(COM1B1);
TCCR1A &= ~(_BV(COM1A0));
``````

Your set up of Timer1 is not correct.

First, you approach is confusing compared to what you have done with Timer0. You are better to clear all the ide presets with TCCR1A = 0 and TCCR1B = 0 and then set the bits you want. The clearing of individual bits is then not necessary.

I see two errors. Do you have a data sheet and the register map in front of you?

``````TCCR1B &= ~(_BV(WGM11));
TCCR1B |= _BV(WGM10);
``````

WGM11 and WGM10 are on TCCR1A.

``````TCCR1A |= _BV(COM1A1);
TCCR1A &= ~(_BV(COM1A0));
TCCR1A |= _BV(COM1B1);
TCCR1A &= ~(_BV(COM1A0));
``````

I think that you intend to clear COM1B1, but you have either a typo or cut and paste error and have not done so.

cattledog:
WGM11 and WGM10 are on TCCR1A.
I think that you intend to clear COM1B1,

I have corrected the mistake WGM10, 11, thank you, COM1B1 set to 1 that is correct....

But i have problem in below code,
This code i am getting correct frequency at PWM pin 9.

``````ISR(TIMER0_COMPA_vect)
{
OCR1A=(256+((((sin(num*3.14/180))*256))))/2;
//OCR1B=(256+((((sin(num*3.14/180))*256))))/2;
num=num+10;
if(num >= 360)
{
num = 0;
}
}
``````

This code i am getting only half of the previous frequency at PWM pin 9,10

``````ISR(TIMER0_COMPA_vect)
{
OCR1A=(256+((((sin(num*3.14/180))*256))))/2;
OCR1B=(256+((((sin(num*3.14/180))*256))))/2;
num=num+10;
if(num >= 360)
{
num = 0;
}
}
``````

Please post the complete code which demonstrates the problem. I strongly encourage the approach which starts with registers set to 0 and then set bits. The ide generates presets for the default pwm modes with analogWrite().

COM1B1 set to 1 that is correct....

I made a mistake in my first posting and I intended to say that you hadn't cleared COM1B0. It is a bit that is likely set by the ide.

``````TCCR1A |= _BV(COM1A1);
TCCR1A &= ~(_BV(COM1A0));
TCCR1A |= _BV(COM1B1);
//TCCR1A &= ~(_BV(COM1A0));
TCCR1A &= ~(_BV(COM1B0));
``````