I’ve been developing code to create two out of phase triangle PWM signals. I’ve already filtered the signal output with a highpass LC filter. The signals are required to feed two IBT-2 H-Bridge modules. Each H-Bridge is connected with its own filters and coils. As you can see from the code, I need higher frequency PWM signals to better filtering. I can not use DAC signals. I need direct PWM control on the H-Bridges modules for efficiency. I also need the PWM signals to smoothly change in frequency, hence the analogread(0). As you can see, I’ve added a trigger signal, just for easily viewing the PWM signals on a scope.
My problem is…I continue to get unpredictable jitter in the PWM signals. See the attached image. There is no pattern to the jitter. Very random. I’ve tried multiple ways to eliminate the jitter. I recently placed while loops using micros() instead of delays, thinking this was the problem and still get the issue. I’ve tried to read and understand the register data on the datasheet and still not getting great results. I’m also using the DUE Arduino board, hopefully this helps.
Is there a way to remove this jitter signal?
typedef struct {
Tc *pTC; // TC0, TC1, or TC2
byte channel; // 0-2
byte output; // 0 = A, 1 = B
}
tTimerInfo;
tTimerInfo timerLookup [] =
{
{NULL,0,0}, // 0
{NULL,0,0}, // 0
{TC0,0,0}, // pin 2 = TIOA0
{TC2,1,0}, // pin 3 = TIOA7
{TC2,0,1}, // pin 4 = TIOB6
};
uint32_t setupTimerPwm (byte pin, uint32_t frequency, unsigned dutyCycle)
{
uint32_t count = VARIANT_MCK/2/frequency;
tTimerInfo *pTimer = &timerLookup[pin];
{
TC_SetRC (TC2, 0, count);
if (pTimer->output == 0)
TC_SetRA (TC2, 0, count * dutyCycle / 4095);
else
TC_SetRB (TC2, 0, count * dutyCycle / 4095);
return count;
}
}
int tri[] = {
0x2d, 0x5a, 0x88, 0xb5, 0xe2, 0x10f,0x13d,0x16a,0x197,0x1c4,
0x1f2,0x21f,0x24c,0x279,0x2a7,0x2d4,0x301,0x32e,0x35c,0x389,
0x3b6,0x3e3,0x411,0x43e,0x46b,0x498,0x4c6,0x4f3,0x520,0x54d,
0x57b,0x5a8,0x5d5,0x602,0x630,0x65d,0x68a,0x6b7,0x6e5,0x712,
0x73f,0x76c,0x79a,0x7c7,0x7f4,0x821,0x84f,0x87c,0x8a9,0x8d6,
0x904,0x931,0x95e,0x98b,0x9b9,0x9e6,0xa13,0xa40,0xa6e,0xa9b,
0xac8,0xaf5,0xb23,0xb50,0xb7d,0xbaa,0xbd8,0xc05,0xc32,0xc5f,
0xc8d,0xcba,0xce7,0xd14,0xd42,0xd6f,0xd9c,0xdc9,0xdf7,0xe24,
0xe51,0xe7e,0xeac,0xed9,0xf06,0xf33,0xf61,0xf8e,0xfbb,0xfe8,
0xfff};
int atri[] = {
0xfff,0xfe8,0xfbb,0xf8e,0xf61,0xf33,0xf06,0xed9,0xeac,0xe7e,
0xe51,0xe24,0xdf7,0xdc9,0xd9c,0xd6f,0xd42,0xd14,0xce7,0xcba,
0xc8d,0xc5f,0xc32,0xc05,0xbd8,0xbaa,0xb7d,0xb50,0xb23,0xaf5,
0xac8,0xa9b,0xa6e,0xa40,0xa13,0x9e6,0x9b9,0x98b,0x95e,0x931,
0x904,0x8d6,0x8a9,0x87c,0x84f,0x821,0x7f4,0x7c7,0x79a,0x76c,
0x73f,0x712,0x6e5,0x6b7,0x68a,0x65d,0x630,0x602,0x5d5,0x5a8,
0x57b,0x54d,0x520,0x4f3,0x4c6,0x498,0x46b,0x43e,0x411,0x3e3,
0x3b6,0x389,0x35c,0x32e,0x301,0x2d4,0x2a7,0x279,0x24c,0x21f,
0x1f2,0x1c4,0x197,0x16a,0x13d,0x10f,0xe2 ,0xb5 ,0x88 ,0x5a ,
0x2d};
const int sPWMArrayValues = 91; // sPWM table array value
const int freq = 15000; // sPWM frequency
const int trig = 18; // Trigger
unsigned long time_now = 0;
void setup() {
analogWrite (4, 1);
analogWrite (5, 1);
pinMode(trig, OUTPUT);
}
void loop() {
int val = analogRead(0); //ADC
val = map(val, 0, 1023, 1, 300); //store delay value and map
digitalWrite (trig, HIGH); //using this as a trigger to read both PWM signals on scope
TC_Start (TC2,0);
for(int i(0); i != sPWMArrayValues; i++){
time_now = micros();
while(micros() < time_now + val);{}
setupTimerPwm (4, freq, tri[i]);
setupTimerPwm (5, freq, atri[i]);
}
digitalWrite (trig, LOW);
for(int i(0); i != sPWMArrayValues; i++){
time_now = micros();
while(micros() < time_now + val);{}
setupTimerPwm (4, freq, atri[i]);
setupTimerPwm (5, freq, tri[i]);
}
}