Go Down

Topic: 180 phase shift between 2 PWM signals  (Read 620 times) previous topic - next topic

chiesadoc

Sep 26, 2019, 04:54 pm Last Edit: Sep 26, 2019, 07:04 pm by chiesadoc
Greetings everyone,

I am working with an Arduino Mega 2560. I am trying to control two LEDs using 2 PWM signals (1 for each LED). I am using 2 Timers to do this (16-bit Timer/Counter, 1 for each PWM generation).

Is it possible to generate a 180-degree phase shift between those 2 PWM signals? These two PWMs have the same frequency (20 Hz | 50 ms period) and 9.09 % Duty Cycle (so that I can have a 50 ms period PWM with a 5 ms "ON" interval). I would like one PWM to be 25 ms forward with respect to the other one (to achieve a 180-degree phase shift).

Can this be done by manipulating the Atmega2560 using the DataSheet or by applying some kind of delay function in some part of the code? I am employing an oscilloscope to see both PWM signals more clearly. The sketch that I will post next compiles properly. I am trying to solve this problem from a coding point of view, not by hardware. 1 PWM is coming out from digital pin 5 (PWM) and the other one from digital pin 11 (PWM).

Additional details: I employed a 1024 Prescaler in order to set the Timer/counter (1 and 3) frequency to 15.625 kHz (16MHz/1024) for each timer respectively.

Code: [Select]
#include <avr/io.h>
#include <util/delay.h>

// 6 Timers in Arduino Mega 2560 (2 of 8-bits and 4 16-bits).

void pwm_init1()
{
 
   DDRB |= (1<<DDB5); // output pin | PB5 ( OC1A/PCINT5 ) | digital pin 11 (PWM)
     
   TCCR1A = (1 << COM1A1) | (0 << COM1A0) | (1 << WGM11) | (0 << WGM10);
   
   // non-inverting PWM on OC1A, PWM Phase Correct, TOP = ICR1

   TCCR1B = (1 << WGM13) | (1 << WGM12) | (1 << CS12) | (0 << CS11) | (1 << CS10);
}

void pwm_init2()
{
 
   DDRE |= (1<<DDE3); // output pin | PE3 (AIN1/OC3A) | digital pin 5 (PWM)

   TCCR3A = (1 << COM3A1) | (0 << COM3A0) | (1 << WGM31) | (0 << WGM30);
   
   // non-inverting PWM on OC3A, PWM Phase Correct, TOP = ICR3
   
   TCCR3B = (1 << WGM33) | (1 << WGM32) | (1 << CS32) | (0 << CS31) | (1 << CS30);
 
}
 
int main (void)
{
   uint64_t icr1;
   uint64_t ocr1;

   uint64_t icr2;
   uint64_t ocr2;


   icr1 = 780;   
   ocr1 = 71;     

   icr2 = 780;   
   ocr2 = 71;
   
   pwm_init1();
   pwm_init2();
 
   while(1)
   {
       ICR1 = icr1;
       OCR1A = ocr1;

       ICR3 = icr2;
       OCR3A = ocr2; 
   }
}


I hope my question was clear and well-bounded.

Best regards,
Frank


PerryBebbington

Hello Frank,
Welcome to the forum.

Please read 'how to use this forum - please read' (there's a clue in the title), then go back and modify your code according to the instructions. You are more likely to get helpful, friendly answers if you follow the forum instructions.

Thank you.

chiesadoc

Thank you. I apologize. I will proceed to reformulate my post.

Best regards,
Frank

cattledog

Quote
I am working with an Arduino Mega 2560. I am trying to control two LEDs using 2 PWM signals (1 for each LED). I am using 2 Timers to do this (16-bit Timer/Counter, 1 for each PWM generation).
Using two timers is not necessary. It is more simple to use the hardware output on one timer, and have one output set for inverting and the other for non inverting.


Grumpy_Mike

Quote
I would like one PWM to be 25 ms forward with respect to the other one (to achieve a 180-degree phase shift).
That means the frequency of the PWM applied to the LEDs would be 50HZ. What are you hoping to achieve with this? You certainly will not be able to see any difference between the LEDs.

If it were me, I would simply drive the second LED through a transistor from the pin driving the first one.

Go Up