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.
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.
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.
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?