Hi to Everybody!
I am experiencing an issue with the generation of 2 PWM outputs (180deg out of phase from each other) using the same timer.
I am disclosing my code here with as many comments as I could.
Any help from any of you with more experience would be greatly appreciated!!!
void setup() {
/* Setting up 2 output pins for the same Timer /
DDRE = (1 << DDE3); // OC3A: (pin D5)
DDRE = (1 << DDE4); // OC3B: (pin D2)
/ Resetting Timer3 Control Registers A & B /
TCCR3A = 0;
TCCR3B = 0;
/ Resetting timer to 0 /
TCNT3 = 0;
/ Setting-up timer TOP (ICR3) and compare match values /
ICR3 = 500;
OCR3A = 250;
OCR3B = 250;
/ Setting waveform generation mode 14 (Fast PWM, TOP = ICR3) /
TCCR3A |= (1<<WGM31);
TCCR3B |= (1<<WGM33) | (1<<WGM32);
/ Setting prescaler to 1 /
TCCR3B |= (1<<CS30);
/ Setting -up Compare Output Modes:
- inverting for one of the output pins
- non-inverting for the other output pin
*/
TCCR3A |= (1<<COM3A1) | (1<<COM3B0) | (1<<COM3B1);
}
void loop() {
}
The code above was generated and tried on an Arduino Mega2560 Rev3.
However, I tried it also on 2 different Arduino UNO after minor changes (including using Timer1, and corresponding OC1A/OC1B pins)... with exactly the same outcome.
The outcome I am referring to is that the output on OC3A is as expected, however the one on OC3B shows little to no voltage amplitude (average of 0.5V) in phase with OC3B. This is unexpected because I was hoping to have OC3B exactly 180deg out of phase, and with 5V amplitude peaks.
FWI: what I tried also include
powering up the Arduino board from the power barrel (instead of the USB port)... same outcome
connecting each Arduino output to a resistor connected to ground, to see if the issue might have been due to an impedence issue. The interesting thing, is that when I close the circuit with a resistor (5k resistor for each of the 2 outputs), OC3A continues to work normally, but OC3B has 0 mean voltage, with occasional positive 0.5V spikes in correspondence to changes of OC3B... still not as expected. In other words, I noticed a difference in the following 2 cases (even though the outcome was undesired in both of them): 1) voltage measured directly out of the board pins with nothing connected to them (open circuit), 2) voltage measured directly out of the board pins with circuit closed with a simple 5k resistor (one per output, and each connected to the same ground, and ground connected to the Arduino ground pin).
I tested my oscilloscope probes and ensure that they both work (this included switching them and switching port on the oscilloscope, to rule out the possibility of an oscilloscope malfunction).
The above was experienced on 3 different Arduino boards: 2 UNO and 1 Mega2560. This would rule out a possible malfunction of an individual board.
Your post was MOVED to its current location as it is more suitable.
Please follow the advice given in the link below when posting code. Use code tags (the </> icon above the compose window) to make it easier to read and copy for examination
Aarg,
thank you very much for your help!!
The code that you posted works... not yet sure why.
The code I posted was for a 32kHz wave. I tried the code that you posted with 32000 as the argument of your TwoPhaseFrequency function, and it works: it generates 2 opposite waves at 32kHz. Now I have to figure out why mine doesn't...
However, thanks again!!
sorry what I meant is... not sure why mine doesn't work
For those who may be interested, this is my code for an Arduino UNO (this code does not work... and I need to figure out why to improve my knowledge on the subject):
The way it should work is as I mentioned it in the first message:
OC1A pulsing at 32kHz, and OC1B pulsing at the same frequency, but inverted w.r.t. OC1A.
Hopefully this makes it clearer...
IMO it's sufficient to use a phase correct PWM mode and set COMxA0/B0 inverse in TCCRxA. This will output inverse signals on the OCxA/B pins. The duty cycles have to be adjusted if the HIGH time of the outputs should be the same.
The trick was replacing the first two lines of code
" // Setting up output pins
DDRB = (1 << DDB1); // OC1A: (pin D9)
DDRB = (1 << DDB2); // OC1B: (pin D10)
"
with the following
" // Setting up output pins
DDRB |= (1 << DDB1); // OC1A: (pin D9)
DDRB |= (1 << DDB2); // OC1B: (pin D10)
"
... I got why.
Thank you all for taking me out of this time-sink hole... Aarg I truly appreciated the code that you posted: I figured out the issue by reverse eng. the one that you posted and comparing with mine! thanks a lot!
That explains the problem. You set OUTPUT mode on Pin 5 (PE3) but when you set OUTPUT mode on Pin 2 (PE4) you also set INPUT mode on the rest of PORTE, including Pin 5 (PE3).