[SOLVED] PWM timer sync for BLDC inverter

Post here first, or if you can't find a relevant section!
jdenis
Posts: 18
Joined: Sun May 08, 2016 7:18 pm

[SOLVED] PWM timer sync for BLDC inverter

Post by jdenis » Sat Aug 04, 2018 9:12 pm

Hi, i'm trying to build a 3 phase inverter for a PM BLDC to use in a electric KART, but I need 6 PWM signals, UVW HIGH and UVW LOW, to make the sine wave for the phases, so O can't use one timer, since they have only 4 channels, I'm using timer 4 and 1, pins PB9 PB8 PB7 PB6 and PA10 PA9!

Is there a way to sync the timers? Using PWM I have trouble with one channel high side going up and the low on the other timer going out of phase, so it doesn't move and than jumps when it matches! I bought a logic analyzer to test it but if anyone can help me I'll be a very happy camper! I'll post the 3 phase sine generator code as soon as I make it work!

The driver is IR2101S, and I'm using a 24khz PWM frequency

Code: Select all

 HardwareTimer timer1(1);  timer1.setPeriod(40);
 HardwareTimer timer4(4);  timer4.setPeriod(40);
the full PWM value if I did the correct calculations is 2880, i.e. pwmWrite(UH,2880);

Thanks!!!
Last edited by jdenis on Thu Aug 09, 2018 1:31 pm, edited 1 time in total.

User avatar
mrburnette
Posts: 3001
Joined: Mon Apr 27, 2015 12:50 pm
Location: Greater Atlanta
Contact:

Re: PWM timer sync for BLDC inverter

Post by mrburnette » Sun Aug 05, 2018 3:42 am

Check out this and see if it may lead you to the answer: (thanks to DuskWuff)

https://electronics.stackexchange.com/q ... -same-time

Other results: https://www.google.com/search?q=STM32F1 ... ronization

Good luck,

Ray

stevestrong
Posts: 3053
Joined: Mon Oct 19, 2015 12:06 am
Location: Munich, Germany
Contact:

Re: PWM timer sync for BLDC inverter

Post by stevestrong » Sun Aug 05, 2018 6:23 am

I think the 6 signals can be reduced to 3*2, which means you only need 3 signals and their negate for the three phases.
TIMER1 channels both normal and negate signals are available on pins, check the pin mapping in the chip manual.
TIM1_CHx and TIM1_CHxN, wherein x = [1,2,3] == PA8,PA9,PA10 + PB13,PB14,PB15 (RM0008 p.178, Table 46).

jdenis
Posts: 18
Joined: Sun May 08, 2016 7:18 pm

Re: PWM timer sync for BLDC inverter

Post by jdenis » Sun Aug 05, 2018 6:23 pm

Thanks for the feedback's!!!

Steve, 3*2 will not work to... if it's out of sync when the 2 values start matching it will go at twice the rate and when they aren't matching there will be no LOW and HIGH at the same time so the motor will not turn, and then the motor will jump between not on to 2x matching... I really need the 6 channels to run in sync!!!

Ray, thanks!!! That's exactly what I need! The stm32duino has this:

Code: Select all

void HardwareTimer::setMasterModeTrGo(uint32_t mode) {
	this->dev->regs.bas->CR2 &= ~TIMER_CR2_MMS;
	this->dev->regs.bas->CR2 |= mode;
}
So I think i can use to set master mode, but for the slave I'm at a loss, is there something like a tutorial that you guys know so I can learn to handle the registers? I'm really a noob at programming... I just learn'd by messing around...

If my thinking is correct, I need to:

1. Set setPeriod on both timers;
2. Set one of the 2 timers as MASTER let's say timer 1 using the setMasterModeTrGo;
3. Set TIMER_SMCR_TS and TIMER_SMCR_SMS on the other one...

Now do I need to reset them to sync? If so how? refresh()? On the slave only or both?
On the 2nd step I don't know what to put on MODE...
How do I do the 3rd step? :shock:
Do I need to address the master to the slave, or if i have a master set it will work directly?

Do I need to do something else?

Again REALLY thanks!

User avatar
mrburnette
Posts: 3001
Joined: Mon Apr 27, 2015 12:50 pm
Location: Greater Atlanta
Contact:

Re: PWM timer sync for BLDC inverter

Post by mrburnette » Sun Aug 05, 2018 7:28 pm

jdenis:

You are well ahead of 90% of the members because you have a logic analyzer. ..

I'm off in defective SSD land on a new product delivered Friday - I do not do well when name brand companies pump junk through distributors such as NewEgg.

Anyway, were I doing what you are doing, I'd get out my Saleah and make it earn its keep. STM has a PDF or two on timers and several online sources may be of value:
https://www.google.com/search?q=stm32f1 ... r+tutorial

Also Geoffrey Brown from Indiana U. has at least one STM32 PDF and also a github page full of STM32 resources... might be worth a diversion.

The STM32DUINO has its roots deeply in the Leaflabs Maple effort and those pages are still online & searchable (via Google):
Like this: stm32f103 timer synchronization site:leaflabs.com

And, there is that dreaded TechRefMan.

Good luck,

Ray

stevestrong
Posts: 3053
Joined: Mon Oct 19, 2015 12:06 am
Location: Munich, Germany
Contact:

Re: PWM timer sync for BLDC inverter

Post by stevestrong » Sun Aug 05, 2018 8:00 pm

For your requirements you may end up using low level direct register setting.
The step by step instruction is in RM0008 p.399 "Timer synchronization" -> "Using one timer to start another timer".

Just try it and you will see it is not that bad to use low level code. The big issue is to first make clear what you exactly need 8-) .

jdenis
Posts: 18
Joined: Sun May 08, 2016 7:18 pm

Re: PWM timer sync for BLDC inverter

Post by jdenis » Sun Aug 05, 2018 8:51 pm

Thats my issue... I have NO idea on how to write the register, and handle low level programming...

Tomorrow the logic analyzer will arrive and then i'll be able to test it precisely, I just found out the un-sync with a oscilloscope, I'll look on the leaflabs and the stm32duino cores to try finding the how to's!!!

I did a while ago fixed a SSD from OCZ... lord knows how but the atmel eeprom was corrupted, had tree ssd's two working just cloned one to the other and it worked...

The ssd's should have a diagnostic system... usually they have a RX TX pins but nothing useful for us mortals...

Again thanks for all!!!!!!!!

Here's the code, it's messy for now I put 3 arrays one for each fase... I'll use only one with a 120 degree diference for each phase, I tought that the problem was there so i made the code as direct as possible... Only after all that I discovered that the problem was the un-sync timers! And the speed control etc. is just for testing! At least the hardware works perfectly :D

Code: Select all

//INIT

  const int8_t sineU[] = {
    0,3,7,10,14,17,21,24,28,31,34,37,41,44,47,50,53,56,59,62,64,67,69,72,74,77,79,81,83,85,
    87,88,90,91,93,94,95,96,97,98,98,99,99,99,99,99,99,99,99,99,98,98,97,96,95,94,93,91,90,88,
    87,85,83,81,79,77,74,72,69,67,64,62,59,56,53,50,47,44,41,37,34,31,28,24,21,17,14,10,7,3,
    0,-3,-7,-10,-14,-17,-21,-24,-28,-31,-34,-37,-41,-44,-47,-50,-53,-56,-59,-62,-64,-67,-69,-72,-74,-77,-79,-81,-83,-85,
    -87,-88,-90,-91,-93,-94,-95,-96,-97,-98,-98,-99,-99,-99,-99,-99,-99,-99,-99,-99,-98,-98,-97,-96,-95,-94,-93,-91,-90,-88,
    -87,-85,-83,-81,-79,-77,-74,-72,-69,-67,-64,-62,-59,-56,-53,-50,-47,-44,-41,-37,-34,-31,-28,-24,-21,-17,-14,-10,-7,-3};
    
  const int8_t sineV[] = {
    87,85,83,81,79,77,74,72,69,67,64,62,59,56,53,50,47,44,41,37,34,31,28,24,21,17,14,10,7,3,
    0,-3,-7,-10,-14,-17,-21,-24,-28,-31,-34,-37,-41,-44,-47,-50,-53,-56,-59,-62,-64,-67,-69,-72,-74,-77,-79,-81,-83,-85,
    -87,-88,-90,-91,-93,-94,-95,-96,-97,-98,-98,-99,-99,-99,-99,-99,-99,-99,-99,-99,-98,-98,-97,-96,-95,-94,-93,-91,-90,-88,
    -87,-85,-83,-81,-79,-77,-74,-72,-69,-67,-64,-62,-59,-56,-53,-50,-47,-44,-41,-37,-34,-31,-28,-24,-21,-17,-14,-10,-7,-3,
    0,3,7,10,14,17,21,24,28,31,34,37,41,44,47,50,53,56,59,62,64,67,69,72,74,77,79,81,83,85,
    87,88,90,91,93,94,95,96,97,98,98,99,99,99,99,99,99,99,99,99,98,98,97,96,95,94,93,91,90,88};
    
  const int8_t sineW[] = {
    -87,-88,-90,-91,-93,-94,-95,-96,-97,-98,-98,-99,-99,-99,-99,-99,-99,-99,-99,-99,-98,-98,-97,-96,-95,-94,-93,-91,-90,-88,
    -87,-85,-83,-81,-79,-77,-74,-72,-69,-67,-64,-62,-59,-56,-53,-50,-47,-44,-41,-37,-34,-31,-28,-24,-21,-17,-14,-10,-7,-3,
    0,3,7,10,14,17,21,24,28,31,34,37,41,44,47,50,53,56,59,62,64,67,69,72,74,77,79,81,83,85,
    87,88,90,91,93,94,95,96,97,98,98,99,99,99,99,99,99,99,99,99,98,98,97,96,95,94,93,91,90,88,
    87,85,83,81,79,77,74,72,69,67,64,62,59,56,53,50,47,44,41,37,34,31,28,24,21,17,14,10,7,3,
    0,-3,-7,-10,-14,-17,-21,-24,-28,-31,-34,-37,-41,-44,-47,-50,-53,-56,-59,-62,-64,-67,-69,-72,-74,-77,-79,-81,-83,-85};

  //Motor
  int32_t motorStep = 0, motorPhase = 0, motorStepTimer = 0;
  byte NRD = 1;
  int throttle = 0;

  //Debounces
  uint32_t encoderDebounce = 0, gearDebounce = 0;
  
//PIN ASSIGNMENT

  #define UH PB9
  #define UL PB8
  #define VH PB7
  #define VL PB6
  #define WH PA10
  #define WL PA9

  #define REVERSESW PB1
  #define DRIVESW PB0
  
  //int UH = PB9, UL = PB8, VH = PB7, VL = PB6, WH = PA10, WL = PA9;
  //int REVERSESW = PB1, DRIVESW = PB0;
   
//FLOATS AND OTHERS

  int32_t kU = 0, kV = 0, kW = 0;
  int16_t jU = 0, jV = 0, jW = 0, currentStep = 0, oldStep = 0;
  
//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

void setup(){

//PINMODE

  afio_cfg_debug_ports(AFIO_DEBUG_SW_ONLY);
  adc_set_sample_rate(ADC1, ADC_SMPR_7_5); adc_set_sample_rate(ADC2, ADC_SMPR_7_5);
  HardwareTimer timer1(1);  timer1.setPeriod(40);
  HardwareTimer timer4(4);  timer4.setPeriod(40);
  //Serial3.begin(200000);
  
  pinMode(REVERSESW, INPUT_PULLUP); pinMode(DRIVESW, INPUT_PULLUP); 
  
  pinMode(UL, PWM); pinMode(VL, PWM); pinMode(WL, PWM); pwmWrite(UL,0); pwmWrite(VL,0); pwmWrite(WL,0);
  pinMode(UH, PWM); pinMode(VH, PWM); pinMode(WH, PWM); pwmWrite(UH,0); pwmWrite(VH,0); pwmWrite(WH,0); 

  //Charge BOOTSTRAP
  pwmWrite(UL,2880); pwmWrite(VL,2880); pwmWrite(WL,2880);
  delay(50);
  pwmWrite(UL,0); pwmWrite(VL,0); pwmWrite(WL,0);
  
  motorSquare();
    
  //Throttle
  pinMode(PA0, INPUT_ANALOG); pinMode(PA2, INPUT_PULLUP); pinMode(PA7, INPUT_PULLUP);

} //--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

void loop(){
  //Throttle
  throttle = adc_read(ADC1, 0);
  //if(throttle < 409){throttle = 0;}

  //GEAR
  //if(digitalRead(REVERSESW) == digitalRead(DRIVESW)){NRD = 2;}
  //if(digitalRead(REVERSESW) == LOW){NRD = 1;} if(digitalRead(DRIVESW) == LOW){NRD = 3;}
  //if(NRD == 2){throttle = 0;} 

 
  if(micros() - motorStepTimer > throttle*100){motorSine();}

} // VOID LOOP END --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

void motorSine(){
  kU = (sineU[motorStep]*288)/10;
  if(kU == 0){pwmWrite(UH,0); pwmWrite(UL,0);}
  if(kU > 0){pwmWrite(UH,kU); pwmWrite(UL,0);}
  if(kU < 0){kU = kU*-1; pwmWrite(UH,0); pwmWrite(UL,kU);}

  kV = (sineV[motorStep]*288)/10;
  if(kV == 0){pwmWrite(VH,0); pwmWrite(VL,0);}
  if(kV > 0){pwmWrite(VH,kV); pwmWrite(VL,0);}
  if(kV < 0){kV = kV*-1; pwmWrite(VH,0); pwmWrite(VL,kV);}

  kW = (sineW[motorStep]*288)/10;
  if(kW == 0){pwmWrite(WH,0); pwmWrite(WL,0);}
  if(kW > 0){pwmWrite(WH,kW); pwmWrite(WL,0);}
  if(kW < 0){kW = kW*-1; pwmWrite(WH,0); pwmWrite(WL,kW);}

  motorStep++;

  if(motorStep < 0){motorStep = 179;}
  if(motorStep > 179){motorStep = 0;}
  
  motorStepTimer = micros();
  
}

pokemon99
Posts: 58
Joined: Wed Jun 07, 2017 9:09 am

Re: PWM timer sync for BLDC inverter

Post by pokemon99 » Mon Aug 06, 2018 3:55 am

Good afternoon. Interest in this topic. What is motorSquare()?

jdenis
Posts: 18
Joined: Sun May 08, 2016 7:18 pm

Re: PWM timer sync for BLDC inverter

Post by jdenis » Mon Aug 06, 2018 9:57 am

Oh yeah that was before sine wave, where I had a square wave signal!!! But the motor jumps so now i'm implementing sine wave, this code is extremely in test so wait... I'll post a workable code when i have it!!! Cheers!

User avatar
mrburnette
Posts: 3001
Joined: Mon Apr 27, 2015 12:50 pm
Location: Greater Atlanta
Contact:

Re: PWM timer sync for BLDC inverter

Post by mrburnette » Mon Aug 06, 2018 12:15 pm

It may be useful, if for no reason but a mental interlude, to review Don's Magic Sinewaves:
https://www.tinaja.com/magsn01.shtml

Ray

Post Reply