Creating a dead band on PWM pins for arduino mega

Hello all,

So to the point the code im using for an arduino mega 2560 is able to create 6 PWM outputs with 3 of these being the inverse of the other 3 ouputs. (Ive been putting these through a low pass filter to check the output)
What im having trouble with is creating a dead band so no invert and non invert pair of PWM signals are one at the same time.
In the below code SineWrite() is where im addressing the OCRN registers using a lookup table. i thought reading just a bit further ahead in the lookup table would give me my dead band but alas this hasnt worked.
Any ideas on how i can get the dead band i require
photo of what i currently have
(the dead band seems to have made a weird mid section for the two pwm outputs?)

code for reference

const static unsigned int sineLookUp[360] {
29,31,32,34,35,37,38,40,41,43,
45,46,48,50,52,53,55,57,59,61,
62,64,66,68,70,72,74,76,78,80,
82,84,86,88,91,93,95,97,99,101,
103,105,108,110,112,114,116,118,121,123,
125,127,129,132,134,136,138,140,142,145,
147,149,151,153,155,157,159,162,164,166,
168,170,172,174,176,178,180,182,184,186,
188,189,191,193,195,197,198,200,202,204,
205,207,209,210,212,213,215,216,218,219,
221,222,224,225,226,227,229,230,231,232,
233,234,235,236,237,238,239,240,241,242,
242,243,244,245,245,246,246,247,247,248,
248,248,249,249,249,250,250,250,250,250,
250,250,250,250,250,250,249,249,249,248,
248,248,247,247,246,246,245,245,244,243,
242,242,241,240,239,238,237,236,235,234,
233,232,231,230,229,227,226,225,224,222,
221,219,218,216,215,213,212,210,209,207,
205,204,202,200,198,197,195,193,191,189,
188,186,184,182,180,178,176,174,172,170,
168,166,164,162,159,157,155,153,151,149,
147,145,142,140,138,136,134,132,129,127,
125,123,121,118,116,114,112,110,108,105,
103,101,99,97,95,93,91,88,86,84,
82,80,78,76,74,72,70,68,66,64,
63,61,59,57,55,53,52,50,48,46,
45,43,41,40,38,37,35,34,32,31,
29,28,26,25,24,23,21,20,19,18,
17,16,15,14,13,12,11,10,9,8,
8,7,6,5,5,4,4,3,3,2,
2,2,1,1,1,0,0,0,0,0,
0,0,0,0,0,0,1,1,1,2,
2,2,3,3,4,4,5,5,6,7,
8,8,9,10,11,12,13,14,15,16,
17,18,19,20,21,23,24,25,26,28,
};

const static unsigned int sineLookUp120[360] {
168,166,164,162,159,157,155,153,151,149,
147,145,142,140,138,136,134,132,129,127,
125,123,121,118,116,114,112,110,108,105,
103,101,99,97,95,93,91,88,86,84,
82,80,78,76,74,72,70,68,66,64,
63,61,59,57,55,53,52,50,48,46,
45,43,41,40,38,37,35,34,32,31,
29,28,26,25,24,23,21,20,19,18,
17,16,15,14,13,12,11,10,9,8,
8,7,6,5,5,4,4,3,3,2,
2,2,1,1,1,0,0,0,0,0,
0,0,0,0,0,0,1,1,1,2,
2,2,3,3,4,4,5,5,6,7,
8,8,9,10,11,12,13,14,15,16,
17,18,19,20,21,23,24,25,26,28,
29,31,32,34,35,37,38,40,41,43,
45,46,48,50,52,53,55,57,59,61,
62,64,66,68,70,72,74,76,78,80,
82,84,86,88,91,93,95,97,99,101,
103,105,108,110,112,114,116,118,121,123,
125,127,129,132,134,136,138,140,142,145,
147,149,151,153,155,157,159,162,164,166,
168,170,172,174,176,178,180,182,184,186,
188,189,191,193,195,197,198,200,202,204,
205,207,209,210,212,213,215,216,218,219,
221,222,224,225,226,227,229,230,231,232,
233,234,235,236,237,238,239,240,241,242,
242,243,244,245,245,246,246,247,247,248,
248,248,249,249,249,250,250,250,250,250,
250,250,250,250,250,250,249,249,249,248,
248,248,247,247,246,246,245,245,244,243,
242,242,241,240,239,238,237,236,235,234,
233,232,231,230,229,227,226,225,224,222,
221,219,218,216,215,213,212,210,209,207,
205,204,202,200,198,197,195,193,191,189,
188,186,184,182,180,178,176,174,172,170,
};
const static unsigned int sineLookUp240[360] {
17,16,15,14,13,12,11,10,9,8,
8,7,6,5,5,4,4,3,3,2,
2,2,1,1,1,0,0,0,0,0,
0,0,0,0,0,0,1,1,1,2,
2,2,3,3,4,4,5,5,6,7,
8,8,9,10,11,12,13,14,15,16,
17,18,19,20,21,23,24,25,26,28,
29,31,32,34,35,37,38,40,41,43,
45,46,48,50,52,53,55,57,59,61,
62,64,66,68,70,72,74,76,78,80,
82,84,86,88,91,93,95,97,99,101,
103,105,108,110,112,114,116,118,121,123,
125,127,129,132,134,136,138,140,142,145,
147,149,151,153,155,157,159,162,164,166,
168,170,172,174,176,178,180,182,184,186,
188,189,191,193,195,197,198,200,202,204,
205,207,209,210,212,213,215,216,218,219,
221,222,224,225,226,227,229,230,231,232,
233,234,235,236,237,238,239,240,241,242,
242,243,244,245,245,246,246,247,247,248,
248,248,249,249,249,250,250,250,250,250,
250,250,250,250,250,250,249,249,249,248,
248,248,247,247,246,246,245,245,244,243,
242,242,241,240,239,238,237,236,235,234,
233,232,231,230,229,227,226,225,224,222,
221,219,218,216,215,213,212,210,209,207,
205,204,202,200,198,197,195,193,191,189,
188,186,184,182,180,178,176,174,172,170,
168,166,164,162,159,157,155,153,151,149,
147,145,142,140,138,136,134,132,129,127,
125,123,121,118,116,114,112,110,108,105,
103,101,99,97,95,93,91,88,86,84,
82,80,78,76,74,72,70,68,66,64,
63,61,59,57,55,53,52,50,48,46,
45,43,41,40,38,37,35,34,32,31,
29,28,26,25,24,23,21,20,19,18,
};
int x;
int y;
int z;
const int sensorPin = A0;
int sensorValue =0;
int outputValue = 0; 
//int i;
const int button = 22;
int buttonState = 0;
int buttonCase = 0;
int ledPin = 23;
void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(7, OUTPUT);
  pinMode(8, OUTPUT);
  pinMode(11, OUTPUT);
  pinMode(12, OUTPUT);

  //GTCCR = _BV(TSM) | _BV(PSRSYNC);
  TCCR1A = 0;
  TCCR1B = 0;
  TCCR3A = 0;
  TCCR3B = 0;
  TCCR4A = 0; 
  TCCR4B = 0;

  ADCSRA &= ~(bit (ADPS0) | bit (ADPS1) | bit (ADPS2)); // clear prescaler bits
  
  TCNT1 = 0;
  TCNT3 = 0;
  TCNT4 = 0;
  
  ICR1 = 255; //ICR1 = 250
  ICR3 = 255; //ICR3 = 250
  ICR4 = 255; //ICR4 = 250

//  OCR1B = ICR1/2; //Dutycycle is 50% pin 12
//  OCR1A = ICR1/2; //Dutycycle is 50% pin 11
//  OCR4C = ICR4/2; //Dutycycle is 50% pin 8
//  OCR4B = ICR4/2; //Dutycycle is 50% pin 7
//  OCR3B = ICR3/2; //DC is 50% pin 2
//  OCR3C = ICR3/2; //DC is 50% pin 3
//    
//set mode 10 with
  TCCR1A =  _BV(WGM11) | _BV(COM1A1) | _BV(COM1B0)| _BV(COM1B1); //pins 11, 12 _BV(WGM11)
  TCCR3A =  _BV(WGM31) | _BV(WGM31) | _BV(COM3C1) | _BV(COM3B0)| _BV(COM3B1); //_BV(WGM31)
  TCCR4A =  _BV(WGM41) | _BV(COM4C1) | _BV(COM4B0) | _BV(COM4B1); // pins 7 and 8 _BV(WGM41)
  TCCR1B = _BV(WGM13) | _BV(CS10); //No prescaling
  TCCR3B = _BV(WGM33) | _BV(CS30);
  TCCR4B = _BV(WGM43) | _BV(CS40);
 // GTCCR = 0;
  
// ADCSRA |= (bit (ADPS0) ); // 2
}

void loop() {
 
  for(x=0; x<360; x++) {
  //  sensorValue = analogRead(sensorPin);
  // 5 HZ is 514 on sensor pin
  // 60 HZ is 11 steps
  // outputValue = map(sensorValue, 0, 1023 , 0, 255);
    delayMicroseconds(3000);    
      sineWrite(sineLookUp[x],sineLookUp[x],sineLookUp120[x],sineLookUp120[x],sineLookUp240[x],sineLookUp240[x]);
  } 
}
void sineWrite(int sine1,int sineI, int sine2,int sine2I, int sine3, int sine3I) {
  OCR4C = sine1;
  OCR4B = sineI + 2 ;
  OCR1A = sine2;
  OCR1B = sine2I + 2;
  OCR3B = sine3;
  OCR3C = sine3I + 2;
  // top is 12, 8, 3
  //bot is 11, 7, 2
}

With sine output I see no use for a dead band.

That does not make sense to me. What is "one"?
What exactly does "dead band" mean to you?

With PWM use slightly different OCR values for both channels to obtain non-overlapping PWM signals-

Mode 10 is phase-correct PWM, and you are setting up the output pins to be inverted from each other:

And you're offsetting OCRnA from OCRnB:

I'd experiment with a wider separation to see if it works as expected:

void sineWrite(int sine1,int sineI, int sine2,int sine2I, int sine3, int sine3I) {
  OCR4C = sine1 / 2;
  OCR4B = sineI + 2 ;
  OCR1A = sine2 / 2;
  OCR1B = sine2I + 2;
  OCR3B = sine3 / 2;
  OCR3C = sine3I + 2;
  // top is 12, 8, 3
  //bot is 11, 7, 2
}

You can get rid of two of the tables:

      sineWrite(
sineLookUp[x], sineLookUp[x],
sineLookUp[(x+120)%360], sineLookUp[x+120)%360],
sineLookUp[(x+240)%360], sineLookUp[(x+240)%360]
);

If you split your circle into 256 steps instead of 360 you could use a byte variable to get a natural % 256:

      sineWrite(
sineLookUp[x], sineLookUp[x],
sineLookUp[byte(x+85)], sineLookUp[byte(x+85)],
sineLookUp[byte(x+171)], sineLookUp[byte(x+171)]
);

And there's really no need to send every value twice:

      sineWrite(
sineLookUp[x],
sineLookUp[byte(x+85)],
sineLookUp[byte(x+171)]);

Note that the sine values must be less then 254 if you are adding 2 to them. To make them more semetric you could use

  OCR4C = sine1 - 1;
  OCR4B = sine1 + 1 ;

Then you would have to have values from 1 to 254

Arduino DUE (similar board layout as Arduino Mega 2560 Rev3), 84MHz, 3.3V

From the SAM3X datasheet:

Up to 8-channel 16-bit PWM (PWMC) with Complementary Output, Fault Input, 12-bit Dead Time Generator Counter for Motor Control

Some channels can be linked together as synchronous channels

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