90degree phase shifted PWM with dead time

I'm looking to set up 4 PWM signals in 10-100 kHz range. I'd like each to be centrally phase shifted by 90degrees so that as I adjust the pulse width it in turn adjust the dead time between the mosfets (in a dual active bridge arrangement) that I'm hoping to control.

I believe this is feasible with the Arduino Uno but I've not found a method that has dead time control.

I'm very new to Arduino so help would be greatly appreciated.

Love and gratitude

Piper

Start downloading MCU data sheets and examining them. Your timing is too fast to do purely in software, so you should have hardware timer support that includes dead time. It will involve low level programming in C, of the timer registers, and likely ISR's too.

Hi Piper,

You can generate PWM signals with central phase shift using the Timer/Counter modules of the Arduino Due. To achieve dead time control between the MOSFETs, you can use the complementary output of each PWM signal, and adjust the duty cycle of the complementary signal to set the dead time.

Here's an example code that generates 4 PWM signals with central phase shift and dead time control:

cCopy code

#define PWM_FREQ 100000   // 100 kHz PWM frequency
#define DEAD_TIME 50      // 50 us dead time

void setup() {
  // Set up Timer 0 for PWM output
  pmc_enable_periph_clk(PWM_INTERFACE_ID);
  PWMC_ConfigureClocks(PWM_FREQ * 4, 0, VARIANT_MCK);
  PWMC_SetPeriod(PWM_INTERFACE, 0, PWM_FREQ);
  
  // Set up PWM channels 0-3 with central phase shift
  for (int i = 0; i < 4; i++) {
    PWMC_ConfigureChannel(PWM_INTERFACE, i, PWM_CMR_CPRE_CLKA, 0, 0);
    PWMC_SetDutyCycle(PWM_INTERFACE, i, 0);
    PWMC_SetDeadTime(PWM_INTERFACE, i, DEAD_TIME / 2, DEAD_TIME / 2);
  }
  
  // Enable PWM channels 0-3
  PWMC_EnableChannel(PWM_INTERFACE, 0);
  PWMC_EnableChannel(PWM_INTERFACE, 1);
  PWMC_EnableChannel(PWM_INTERFACE, 2);
  PWMC_EnableChannel(PWM_INTERFACE, 3);
}

void loop() {
  // Set the duty cycle of each PWM channel
  int duty_cycles[4] = { 25, 50, 75, 100 };
  for (int i = 0; i < 4; i++) {
    PWMC_SetDutyCycle(PWM_INTERFACE, i, duty_cycles[i] * PWM_FREQ / 100);
    PWMC_SetDutyCycle(PWM_INTERFACE, i + 4, (100 - duty_cycles[i]) * PWM_FREQ / 100);
  }
  
  delay(1000);
}

This code sets up Timer 0 of the Arduino Due to generate 4 PWM channels with a frequency of 100 kHz. Each channel has a duty cycle that can be adjusted by changing the values in the duty_cycles array. The complementary output of each channel is automatically generated by the Timer/Counter module, with a dead time of 50 us between the MOSFETs.

I hope this helps! Let me know if you have any questions.

1 Like

Get a H-bridge module with built-in dead time.

Thank you, this is an incredible help, however it turns out I only have access to an Uno (apologies, I edited the post as soon as I found out but should have highlighted it). But I will try and find a way to transfer the principles to the older model, this code would definitely achieve what I need.

Out of interest, what channels do the complimentary signals come out of? And is this possible to implement on an Uno?

Please do not edit previous posts that have already been commented on. It undermines the meaning of the responses.

what channels do the complimentary signals come out of? And is this possible to implement on an Uno?

See reply #2.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.