0

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;   
    }
}

//

3
  • 1
    1. How did you configure your timer ? 2. The sin() function takes something like 100 µs per call. – Edgar Bonet Jun 12 '20 at 10:59
  • You could use OCR1B=OCR1A since both are the same. But, assuming the problem is as StarCat said due to the ISR taking to long, I'd look into creating a table of SIN values. – Gerben Jun 12 '20 at 11:20
  • A better method would be to generate a simple square wave then filter it into a sine wave. No need to mess with complex calculations or even lookup tables. – Majenko Jun 12 '20 at 11:29
2

You are doing complex calculations inside an Interrupt Service Routine. This is not a good idea. Computing sines takes a large amount of time as this consists of multiple, complex floating point operations. Interrupt Service Routines should be short and as simple as possible.

This is probably the reason you can't have two PWM signals active at the same time at the same frequency. The ISRs simply take too long.

The solution would be to pre-calculate the desired waveforms or greatly simplify the waveform calculations (preferably without floating point). If you decide to pre-calculate, take care to stay within the limited amount of memory you have available on your Arduino. You can minimize the memory used by calculating and storing just 1/4 of a complete waveform and constructing the remaining 3/4 from these values.

This leaves the conversion of your PWM output to a real sine wave. How are you planning to do that?

2
  • If the table get too bit (uses too much RAM) you can look into using PROGMEM to keep the table in flash memory. – Gerben Jun 12 '20 at 11:21
  • 1
    the lookup table needs to store only a 1/4 of the sine wave – jsotola Jun 12 '20 at 15:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.