Generating 2 pwm signals from pin9 and pin10 on an Uno in phase

I am generating 2 pwm signals at 20kHz from an Arduino Uno. One has a varying duty cycle and outputs to an igbt driver ic, but this varied duty cycle creates DC current which is a problem with my transformer as it causes flux walking and will saturate my core. So I was thinking to create a second pwm signal using pin 10 (other signal is coming from 9 as I have timer1 setup), I initially thought these two pwm's would be in phase. I was going to use this second pwm at a low duty cycle (~10%) to shutdown my driver ic via a fast switching mosfet to reset any built up flux on my transformer core caused by the variable duty cycle I create to keep my current constant (making an arc welder). Attached is the picture of my oscope and it appears to be shifted by 10us of the 50us period. I looked into register manipulation and it looked like OCR1A was what would help, but I'm a little lost in how to implement it for my purposes. Any suggestions or help is appreciated, thank you in advance.

The waveforms appear to be "in phase" to me. The high pulses are aligned center to center. If you want the pulses to START at the same time, use "FastPWM" and not "Phase Correct PWM".

Thank you, that is exactly what I want. I see now I was incorrect to state it as out of phase. I used a pwm library from a user "runnerup", so I guess the default was "pwm, phase correct". I'll start looking at how to modify that to fast pwm. Thank you for the quick response.

Ok so now I have set WGM10-13 to 1 as that is what it states I'll need to do to put it into fast pwm for TCCR1A and TCCR1B, but it still seems to not be starting at the same time and my second signal seems to center on my first. (still looks like my attached pic)

something like

TCCRA_16(timerOffset) = (TCCRA_16(timerOffset) & B11111110) | (wgm & 3);
TCCRB_16(timerOffset) = (TCCRB_16(timerOffset) & B11111111) | ((wgm & 12) << 1);

from ATimerDefs.cpp as well as something similar in BTimerDefs.cpp

I feel I'm missing something still though. Also, I rarely use arduino or code for that matter, so it is probably something pretty obvious that I'm just missing. Thank you for any additional guidance.

Also I can tell I'm editing the right spot as I set it to all 1's and lost pwm out of pin 9. I know the other part that changes is resetting TOV flag at top vs bottom, but I don't really see this occurring in this code either way.

If the two pins are in the same register, you can write them in a single instruction using the port registers. Both pin 9 and 10 are in register B, so this works in your case.

You may need to write your own PWM code based on timer interrupts, I don't know if there are ready made libraries. To set/reset the pins at the same time you'd need something like this:

// PB1 = pin 9, PB2 = pin 10.
PORTB |= (1 << PB1) | (1 << PB2); // Set bits: sets both pins HIGH.
PORTB &= ~((1 << PB1) | (1 << PB2)); // Clear bits: sets both pins LOW.

I think you are right. I initially used the libraries I found here as they worked for me as they gave me the ability to set the frequency and duty cycle, but this additional requirement may have made using this library not possible. I appreciate the suggestions, and was fearing I may have to go back to scratch and write my owm pwm code, but feel my research of trying to make this one work may help in doing so.

https://forum.arduino.cc/index.php?topic=117425.0

This is the code I'm referencing if anyone has experience with it as my last ditch effort to save the work I've already put in on the circuits and additional code. But likely I'll start making my own pwm based on interrupts.

Ok so now I have set WGM10-13 to 1 as that is what it states I'll need to do to put it into fast pwm

That will put you in Mode 15 which is FAST PWM to OCR1A and you will loose one output.

You need to be in Mode 14 (Bits set in WGM 13:12:11 but not in WGM10) which is FAST PWM to ICR1. ICR1 will set the frequency and OCR1A and OCR1B will set the duty cycles.

Hi,

Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png?

Are you trying to use an IGBT to switch current through a transformer primary to produce AC output on the secondary?

A single IGBT will not do the job as you need AC on the primary input , not pulsed DC.

Tom... :slight_smile:

No, I am using a full h-bridge configuration. I'll see if I can get a pic up here shortly. But basically I have pwm from the arduino into a pair of IR2302 igbt driver ic's, driving a full hbridge configuration with the primary side of the transformer as the load. I first rectify wall volatge to get around 120sqrt(2) VDC at the Collector, then chop it up to 20kHz with the pwm driven hbridge. I also have back end rectification to get a DC arc welder, and I'm using a transducer to get current feedback, that I'm reading into an arduino adc to change the duty cycle when the current dips or rises above the set limit.

A single PWM signal should be able to drive an H-bridge, then you don't have to worry about syncing two pins.

I'm sorry I didn't make that clear, but the need for the second pwm arose when I had to vary duty cycle to keep current constant, which in turn created dc current on my transformer. So was hoping to use the second pwm at 10% duty cycle to toggle my driver ic on and off to "reset" any built up flux to avoid saturation.

Are you still trying to modify the PWM Frequency library?

Since you have a very specific need for two FAST PWM pulses at 20KHz and different duty cycles you might find it
more simple to set up the timer registers directly.

Ok, that kind of goes back to the original issue. If I could simply do this by manipulating the registers then I could do so using the library I'm using as I can see where the compare registers are being set, and I can change that to change modes. Unfortunately, switching to mode 14 "fastpwm" didn't change it. I really don't have time to rewrite all this as it is for a project that is due in a week. My other option is an analog solution using a current peak mode controller, but it requires a different current transformer then what I was given, so was trying to make the transducer I had work. I just felt I was so close and liked how I had more control over the pwm via code and use of the arduino. But from the responses I'm starting to feel that it won't be possible to get my second PWM to start on the first pwms lead edge.

But one last question.
Is there a way to delay a timer from initializing? I was thinking I could setup timer2 like timer1, even though it is 8 bit vs 16. I already have it generating a 20khz pwm, but it is delayed even more, but if I could delay it 18us then it would start on the timer1 pwm from pin9's second pulse, and be on the rising edge as I need it to be.

Here is the setup for 20Khz fast pwm on pins 9 and 10. You could adopt this code to use without the library, or figure out how to hack the library setup to get the mode you need.

void setup() {

  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);

  //InitTimer1
  TCNT1  = 0;
  TCCR1A = 0;
  TCCR1B = 0;

  //set to mode 14 fast pwm to ICR1 top value
  //non inverted output on pins 9 (A) and 10 (B)
  //ICR1 set frequency OCR1A and OCR1B set duty cycle
  //prescaler 8 gives .5 microseconds per timer tick

  // TCCR1A
  // Bit                 7      6      5       4     3      2      1      0
  // Bit Name          COM1A1 COM1A0 COM1B1 COM1B0 -----  ----- WGM11  WGM10
  // Initial Value       0      0      0       0     0      0      0      0
  // changed to          1      0      1       0     0      0      1      0

  TCCR1A = B10100010;

  // TCCR1B  prescaler 8 .5us/tick
  // Bit             7     6      5       4       3      2        1       0
  // Bit Name      ICNC1  ICES1 ----   WGM13    WGM12    CS12    CS11     CS10
  // Initial Value    0     0     0        0       0      0        0       0
  // changed to       0     0     0       1       1      0        1       0

  TCCR1B = B00011010;

  ICR1 = 99;//Set Top Value, -> frequency 20 kHz with 16 MHz internal clock, count is 0 referenced for 100 ticks
  OCR1A = 50; //duty cycle pin 9 value 0-99
  OCR1B = 10; //duty cycle pin 10 value 0-99
}

void loop() {}

Hi,
Something like this?

Tom... :slight_smile:

I roughly understand the workings of that schematic - from AC to DC to high-frequency AC into a transformer to create DC again - but that leaves me with the question: what's the purpose? (I know, off-topic, just curious).

Hi,
It has to do with the BLACK art of MIG and TIG welding.

I'm nowhere near an expert, just fix the occasional, fixable, welder.

Different metals and different welding processes need adjustable current and current profile when starting and stopping an arc.

Tom... :o

I'm starting to wish we had decided to do a mig instead. Very similar but much easier to control voltage than current. I think the motor scared us away at first but looking back that looks to be a much simpler problem to navigate. Thank you all for the help once again, I'm going to try the code above and see if I get anything different.

Cattledog, you are my hero!! Also the first post was dead on that I had to be in fast pwm, I just didn't know what other than wgm10-13 to change to get it there, so those register values made it all work as I needed it too. Thank you all so much!!

I attached the o-scope pic just cause I figured people may want proof it worked.

WVmarvle, one advantage to this method is massively reducing the size of the transformer needed. 60hz transformers for this power level get huge, while you can shrink it to a handheld size transformer with this high frequency chopped up voltage. This has to do with the cores magnetic properties and how chopping it up at higher frequencies allows the core to handle the same power at a much smaller size. Which is why now microwaves and welders can be so much more portable.