Author Topic: BLDC Motor Controller, Design, Waveforms, Thermal Tests  (Read 29585 times)

0 Members and 1 Guest are viewing this topic.

Offline nuno

  • Frequent Contributor
  • **
  • Posts: 606
  • Country: pt
Re: BLDC Motor Controller, RC Snubber Design + Waveforms
« Reply #25 on: November 09, 2017, 05:34:27 pm »
Lots of excellent advice have already be given to you Glenn. I think you need to put things into perspective, as many aspects depend on the power level and maximum current your system is supposed to deal with.

Past some power point, you shouldn't need to use snubbers. I can't draw a line, but I haven't see any snubbers in typical "mobility" motor controllers of some 200W and up. Snubbers in this application/power level are a kind of a bandaid.

You should check for ringing at your system's maximum current, as ringing amplitude is very strongly current dependent. Then let us know if your snubber capacitor isn't warming up. Search for "double pulse test".

The diode in parallel with the gate resistor will make the switch off very fast, and faster = higher amplitude transients; dv = L di/dt is your law in this application, as has already been mentioned by previous posters. That technique is used to control turn on and turn off times separately, but a resistor is inserted in series with the diode.
« Last Edit: November 09, 2017, 05:37:05 pm by nuno »
 

Offline nuno

  • Frequent Contributor
  • **
  • Posts: 606
  • Country: pt
Re: BLDC Motor Controller, RC Snubber Design + Waveforms
« Reply #26 on: November 09, 2017, 05:48:56 pm »
And by the way... a motor is quite a different load than a resistor. You should use a motor, or at least an equivalent coil, in your tests. I do mine on a motor with a locked rotor.
 

Offline Siwastaja

  • Super Contributor
  • ***
  • Posts: 8172
  • Country: fi
Re: BLDC Motor Controller, RC Snubber Design + Waveforms
« Reply #27 on: November 09, 2017, 06:48:38 pm »
Implement the pulse-by-pulse (or at least as quick as possible) current limit, test it works with your resistor load, then switch to the actual motor as soon as possible. Start with lower DC link voltage first.
 
The following users thanked this post: Glenn0010

Offline Glenn0010Topic starter

  • Regular Contributor
  • *
  • Posts: 214
  • Country: mt
Re: BLDC Motor Controller, RC Snubber Design + Waveforms
« Reply #28 on: November 10, 2017, 12:08:52 pm »
Thanks all for the advice!

I am aiming for around 1kW so 48V and roughly 20A.

What I will do next As @nuno and @Siwastaja recommended is,

1: Test with the voltage on the load with 2 motor wingdings as the load.  I will go to uni to use a current limited supply. I will start at 20V since I need that cause of the 15V buck converter. I will then run at 32V. I will also increase the current limits at each stage to see what effect that has since as you said is VL = L.di,dt.

2: Then I will retest the hall sensor sequence with reference to hte pahses so that I can re implement my old code.

PS some people measured to motor's inductance and it is apparently 311uH at 400Hz
« Last Edit: November 10, 2017, 12:16:17 pm by Glenn0010 »
 

Offline nuno

  • Frequent Contributor
  • **
  • Posts: 606
  • Country: pt
Re: BLDC Motor Controller, RC Snubber Design + Waveforms
« Reply #29 on: November 10, 2017, 01:35:37 pm »
The double pulse test is a switching test in a controlled fashion. You can even just charge your bulk capacitors to your test target voltage and disconnect the power supply for added "safety". Here's one I did on a 25V 20A H-bridge and posted in another topic:



This captures the end of the 1st pulse and the start of the second.
 

Offline Glenn0010Topic starter

  • Regular Contributor
  • *
  • Posts: 214
  • Country: mt
Re: BLDC Motor Controller, RC Snubber Design + Waveforms
« Reply #30 on: November 10, 2017, 02:20:27 pm »
The double pulse test is a switching test in a controlled fashion. You can even just charge your bulk capacitors to your test target voltage and disconnect the power supply for added "safety". Here's one I did on a 25V 20A H-bridge and posted in another topic:



This captures the end of the 1st pulse and the start of the second.

I have looked up up the double pulse and found some really good info so thanks for that! From what I read, the second pulse produces a larger voltage spike since the inductor already has stored current. Do you have pictures of the second pulse? To be honest I was thinking of running this test on my final compact version of this pcb as I am going to make another one to fx all these mistakes.

If I can pick your brain. what do you think about this type of MOSFET module? http://ixapps.ixys.com/Datasheet/MTI85W100GC.pdf the MTI85W100GC as compared to discrete mosfets?

I would think this would have less inductance, small size and possibly better heat transfer, however you cant replace one FET if it is burnt out.

It look somthing like this as seen in Shane colton's blog.



And do all of them come with the copper thermal pad on them as I cannot find any specific reference to it in the data sheet

Regards!


 

Offline Glenn0010Topic starter

  • Regular Contributor
  • *
  • Posts: 214
  • Country: mt
Re: BLDC Motor Controller, RC Snubber Design + Waveforms
« Reply #31 on: November 10, 2017, 03:51:07 pm »
Any thoughts?

You understood the issue, learned quickly, processed that information and found out how to improve it, and actually measured your success in no time. I'm sure you'll be a great power electronics designer sooner than many would expect seeing the first layout.  :-+

Thanks so much for your kind words, looking forward to improve
 

Offline nuno

  • Frequent Contributor
  • **
  • Posts: 606
  • Country: pt
Re: BLDC Motor Controller, RC Snubber Design + Waveforms
« Reply #32 on: November 10, 2017, 05:03:49 pm »
Quote from: Glenn0010
I have looked up up the double pulse and found some really good info so thanks for that! From what I read, the second pulse produces a larger voltage spike since the inductor already has stored current. Do you have pictures of the second pulse?

I don't, but it's not necessary, because, as you said, by the end of the 1st pulse the current is already around the value you want to test at, and the small time it takes from the end of the 1st to the start of the 2nd doesn't allow the current to drop significantly, so both (raise and fall) edges are caught on this graph. I captured these 2 instead of the 2 from the 2nd pulse just for convenience.

Quote from: Glenn0010
To be honest I was thinking of running this test on my final compact version of this pcb as I am going to make another one to fx all these mistakes.

I think you should do it on the layout you currently have (and with the same scales) because it will be a valuable experience and you'll be able to do a direct comparison later with you improved layout(s).

Quote from: Glenn0010
If I can pick your brain. what do you think about this type of MOSFET module? http://ixapps.ixys.com/Datasheet/MTI85W100GC.pdf the MTI85W100GC as compared to discrete mosfets?

I would think this would have less inductance, small size and possibly better heat transfer, however you cant replace one FET if it is burnt out.

I don't really have much experience in this area, but from what I see, the advantages a module has is mainly in compactness, design ease and yes, less inductance (especially on the motor/phase exit node, responsible for the turn-off transient). On the other hand, they tend to be (sometimes much) more expensive than using equivalent discreet FETs. There's also much less options.

By the way, the h-bridge from the double pulse test I posted has a relatively bad layout, but since it has a significant parasitic inductance in the GND connection from the driver to the FET, it provides negative feedback putting a brake on di/dt.
In the graph you can also see the top/bottom FET switching deadtime; the phase current re-circulating on the top FET body diode causes the slight voltage raise (1 diode drop) that can be seen right after switch off and right before switch on. In the central part of the graph Vds is slightly lower because current is re-circulating through the top FET turned ON (looks like I could improve by halving the top-to-bottom-switch deadtime).
« Last Edit: November 10, 2017, 05:11:19 pm by nuno »
 

Offline Glenn0010Topic starter

  • Regular Contributor
  • *
  • Posts: 214
  • Country: mt
Re: BLDC Motor Controller, RC Snubber Design + Waveforms
« Reply #33 on: November 10, 2017, 06:55:39 pm »
Yeah that definitely is a good idea to compare so Im going to do it. I am however first going to finalize my code to test that the motor rotates before just incase.

So a couple questions. did you do it with a locked rotor test? If so you did have to somehow limit the current that goes in cause with a locked rotor the currents must be massive!

I am going to follow this: http://athenaenergycorp.com/wp-content/uploads/2016/03/Rogowski_double-pulse_testing.pdf

However I am surprised that in this resource apparently as seen in the graphs provided the switch voltage does not overshoot.

Do you have to repeat the test in the other direction, ie probing the top side mosfet ot can you assume similar values?

With regards to the FET module it is a bit more expensive, the mosfets I have currently would cost around 13 euros for 6 of them while the module costs around 20 euros.  So I am a bit conflicted it is however a very convenient package I emailed them for some more info regarding the thermal pad and I will see

Thanks!
 

Offline nuno

  • Frequent Contributor
  • **
  • Posts: 606
  • Country: pt
Re: BLDC Motor Controller, RC Snubber Design + Waveforms
« Reply #34 on: November 10, 2017, 11:12:13 pm »
Quote from: Glenn0010
So a couple questions. did you do it with a locked rotor test? If so you did have to somehow limit the current that goes in cause with a locked rotor the currents must be massive!

The current for the double pulse test I controlled by adjusting the ON time of the 1st pulse until it gets to the current I want to test at. In this controller I measure current with a 5mOhm shunt. Nevertheless, as Siwastaja has already mentioned, you really should (not to say must*) control the current (PWM) pulse-by-pulse. I have a voltage comparator comparing the voltage drop on the shunt with a constant value (set by a trimpot, but could be a DAC or something else), and its output is connected to an interrupt pin on the microcontroller. When the "overcurrent" interrupt triggers, the ON time of the PWM is terminated, regardless of currently set duty cycle. As simple as this.
For several reasons, you'll never be able to limit the motor/phase current by setting a limit on your power supply.

Quote from: Glenn0010
I am going to follow this: http://athenaenergycorp.com/wp-content/uploads/2016/03/Rogowski_double-pulse_testing.pdf

However I am surprised that in this resource apparently as seen in the graphs provided the switch voltage does not overshoot.

It's just a concept diagram, not a real world scopeshot ;)

Quote from: Glenn0010
Do you have to repeat the test in the other direction, ie probing the top side mosfet ot can you assume similar values?

I think if you have a symmetrical layout it should be similar, but to be sure, I think you should measure.


* Well... it actually depends on the application.
« Last Edit: November 10, 2017, 11:15:54 pm by nuno »
 

Offline Glenn0010Topic starter

  • Regular Contributor
  • *
  • Posts: 214
  • Country: mt
Re: BLDC Motor Controller, RC Snubber Design + Waveforms
« Reply #35 on: November 11, 2017, 10:44:29 am »
Perfect!

So due to the limitations on my layout (I did not include a current sensor), what I will have to do is to remove the big electrolytic caps, and add the current sensor on the negative DC link to get more accurate-ish measurments. I have a current sensor on the way/ Its the ACS711 is a hall effect. I will use that to keep the isolation between my power and signal circuits because with the shunts I lose my isolation unless I add a bunch other stuff!

The ACS711 has a fault pin aswell so that is usefull
 

Offline nuno

  • Frequent Contributor
  • **
  • Posts: 606
  • Country: pt
Re: BLDC Motor Controller, RC Snubber Design + Waveforms
« Reply #36 on: November 11, 2017, 12:48:18 pm »
You can't remove the DC link caps, unless you want to have a huge voltage spike in the DC bus at FET turn off. Why do you want to remove the caps?
 

Offline Glenn0010Topic starter

  • Regular Contributor
  • *
  • Posts: 214
  • Country: mt
Re: BLDC Motor Controller, RC Snubber Design + Waveforms
« Reply #37 on: November 11, 2017, 03:57:25 pm »
I was going to remove the because I can only add the current sensor between the battery and the PCB due to the layout. And if I tridgger the double pulse at 20A, it wouldn't really be really 20A since the caps are also supplying current or is the difference negligible? Each cap is rated at around 2.5 A ripple current and I have 2 in parallel.

I was going to remove them and solder them in between the battery lead wires before the current sensor to get a more accurate measurement.
 

Offline nuno

  • Frequent Contributor
  • **
  • Posts: 606
  • Country: pt
Re: BLDC Motor Controller, RC Snubber Design + Waveforms
« Reply #38 on: November 11, 2017, 05:23:04 pm »
The caps should be as close to the FETs as possible.

What matters here is the motor/phase current, and it's where you want to test the 20A. You're right that the caps will supply part of it, and it's just the way it works, because the power supply won't be able to give 20A fast enough due to parasitic inductance (wiring, etc). Actually, you can have 20A at the motor and, say, 4A at the battery side; a motor controller is kind of a buck switching regulator without the output cap. So you can put your current sensor on the motor wiring.
 

Offline Siwastaja

  • Super Contributor
  • ***
  • Posts: 8172
  • Country: fi
Re: BLDC Motor Controller, RC Snubber Design + Waveforms
« Reply #39 on: November 12, 2017, 01:53:16 pm »
Sensing the current in motor phases is the right way to go for two reasons:
1) You get reading of all three phases separately (with two measurements), instead of total current only
2) The DC link caps don't smooth the reading out, so you get quicker response

But, DC link measurement is much better than nothing, and certainly doable.

Now, if you want to have a protection against motor inductor starting to saturate, and current starting to rise more quickly than you expect, you need to have the shunt placed so that there is no enormous amount of capacitance which would supply the motor, delaying the current rise in the shunt. Small amount is of course OK, since it's "used up" while switching, i.e., in microsecond timescale. And, it has to be that way, because you need it physically close to the FETs, no space to add the common measurement shunt there.

Large amounts of bulk capacitors can actually slow down your current measurement too much to react safely in time, so in that case, you'd place the shunt between the DC link (sprayed with small low-ESL caps and maybe some part of the bulk capacitance), and the rest of the bulk capacitance.

As you know the motor winding inductance and the supply voltage, you can calculate the rate (A/µs) the current rises when you apply full input voltage over the motor phases. V = Ldi/dt -> solve for di/dt. And, if you know the nominal "maximum phase current" for motor it's supposed to run at (rather continuously), and assume that it starts to severely saturate at 3x that current, then you can easily calculate how long it takes for the current to reach that value if your PWM is stuck at the wrong state, i.e., how fast do you need to react to the current measurement getting over your limit.

Then, the same for capacitance is: i = Cdv/dt -> solve for dv/dt to see how quickly the capacitor voltage fades when you supply the current I from the caps.

You can get a lot fancier with maths and all that, but this should give you an idea what's this all about. Actually modeling this would require you to model the input wire inductance and resistance - how quickly it replenishes those DC bus caps while you are measuring.
« Last Edit: November 12, 2017, 01:58:11 pm by Siwastaja »
 

Offline Glenn0010Topic starter

  • Regular Contributor
  • *
  • Posts: 214
  • Country: mt
Re: BLDC Motor Controller, RC Snubber Design + Waveforms
« Reply #40 on: November 13, 2017, 08:44:12 am »
So from your feedback what im going to do is run the test with current sensors on the motor phase. on both systems to compare them! I am getting some free samples current sensors. I am going to use the ACS733 which is a hall effect current sensor, I can program the current limit for it and if it is exceeded it gives me a fault which can go to external interrupts on the micro controller.

Speaking of which I ran in a bit of a snag while programming the code for the hall sensors. I  programmed that the hall sensors would be connected to eternal interrupts on the uC. This can be set to level triggered (which is not good for this application), or edge triggered. Then you have to set if it is rising or falling edge. Therefore between some transitions the interrupt would not realize that the hall sensors have changed state. Because if you set for example one sensor to be falling edge triggered, when it would rise, nothing would happen. I made a truth table to see if there are any combinations which would work but there aren't any.

Therefore what I have to do is use capture inputs of the time which work by detecting a state change. Although this will take a rework and learning since I never used them, it has the added bonus of  counting the time between the state change, therefore I can detect the motor speed and use that for SPWM which makes life easier in the long run.

So before I run the hardware test I need to figure out the software First

Cheers!
 

Offline Siwastaja

  • Super Contributor
  • ***
  • Posts: 8172
  • Country: fi
Re: BLDC Motor Controller, RC Snubber Design + Waveforms
« Reply #41 on: November 13, 2017, 01:52:45 pm »
I just decode the three-bit hall input to a 6-step value in the (only) control ISR (that does everything else as well) running at around 50 kHz IIRC. Works very well, and is extremely simple. But if you run at extremely high fundamental frequencies, this method doesn't give the exactness of reacting to the state changes through timer input captures when they happen.
 

Offline Glenn0010Topic starter

  • Regular Contributor
  • *
  • Posts: 214
  • Country: mt
Re: BLDC Motor Controller, RC Snubber Design + Waveforms
« Reply #42 on: November 13, 2017, 05:13:07 pm »
I just decode the three-bit hall input to a 6-step value in the (only) control ISR (that does everything else as well) running at around 50 kHz IIRC. Works very well, and is extremely simple. But if you run at extremely high fundamental frequencies, this method doesn't give the exactness of reacting to the state changes through timer input captures when they happen.

I get what you mean, In my first version using an arduino I used to ask the uC continuously to check the digital pins and at higher speeds the motor would start cogging a bit because it was not fast enough. I'm guessing you had a similar problem.

I have now switched to an ARM7 uC granted not as fast as the new CORTEX but still will do the job. What type of interrupt where you running? Just a normal timer interrupt at 50kHz? Because using a capture input should give me an interrupt every pulse and I should not miss any like this. Gotta catch'em all  :-DD
 

Offline Siwastaja

  • Super Contributor
  • ***
  • Posts: 8172
  • Country: fi
Re: BLDC Motor Controller, RC Snubber Design + Waveforms
« Reply #43 on: November 13, 2017, 06:37:41 pm »
No, I have no problem whatsoever with code performance. I'm running the control loops in the ISR, triggered from the PWM generation timer, which is a logical place to do it, since it's nicely synchronized with the PWM generation (i.e., calculate the new PWM setpoints once for each new cycle) and ADC reading (i.e., one new current reading per PWM cycle is processed right here, right after conversion), and it's fast enough to also read the halls, so why not.

Running on ARM Cortex-M0 at 48MHz so not that much processing power, but not too much bloat, so definitely about two orders of magnitude faster than an Arduino.

Although, I could imagine some special cases where I would like to have more resolution to when the hall sensors actually changed state between the ISRs, for that I'd use input capture.
 

Offline Glenn0010Topic starter

  • Regular Contributor
  • *
  • Posts: 214
  • Country: mt
Re: BLDC Motor Controller, RC Snubber Design + Waveforms
« Reply #44 on: November 15, 2017, 04:13:21 pm »
Are you running 6 step commutation or SPWM? What you did with the PWM interrupt is a good effective solution for that

So I implemented the capture input for the hall sensors and it was relatively pain free. Today I tested the motor out on a current limited supply at uni and it worked great using 6 step commutation using my LPC2119. Then I tested it using a battery and it worked great so that's I guess is the first milestone.

Though I have a broad idea on how to implement SPWM, I am going to do some research today to find the best way to implement it. So that is the next goal. Then all that remains is to implement PID for a DC link current limit and I can start designing the final version of the PCB!

Thanks
 

Offline Siwastaja

  • Super Contributor
  • ***
  • Posts: 8172
  • Country: fi
Re: BLDC Motor Controller, RC Snubber Design + Waveforms
« Reply #45 on: November 15, 2017, 04:48:31 pm »
SPWM can mean anything based on who you ask, but I basically modulate the PWM value based on a sine lookup table. This is because even though I'm now just skipping the values through in 6 steps, I originally planned to interpolate inbetween and will do it soon... (I had the sine interpolation in place first, it works very well at modest and high speeds, extremely smooth and quiet running; but in it's most simple form, it was problematic when running extremely slowly (think about 1Hz), so I just removed it.)

Right now, I simply do it in 6 steps based on the current hall position, so the field direction wiggles around 60 and 120 degrees instead of the "optimum" 90 degrees. This keeps the motor running automatically, and the applied amplitude basically configures the current and hence torque (and that way, acceleration). So I have a PID loop around the speed, outputting the amplitude. Speed is measured by the time between the hall state changes.

Works so well that I haven't revised my code for a long time, just running it in the application doing gazillion of other things, but now I happen to need sub-hall-step-precision positioning so need to revise it soon...

Sorry, this code doesn't look very nice, was done in hurry. I stripped down some unimportant details, but just to give the idea what performs well even though very simple.

Code: [Select]
const int hall_loc[8] =
{
 -1, // 000  ERROR
 1, // 001
 3, // 010
 2, // 011
 5, // 100
 0, // 101  Middle hall active - we'll call this zero position
 4, // 110
 -1  // 111  ERROR
};

#define PH120SHIFT (1431655765UL)  // 120 deg shift between the phases in the 32-bit range.
#define PH90SHIFT (1073741824UL)   // 90 deg shift between the phases in the 32-bit range.
#define PH45SHIFT (PH90SHIFT/2)

const int base_hall_aims[6] =
{
0,
PH120SHIFT/2,
PH120SHIFT,
PH120SHIFT+PH120SHIFT/2,
PH120SHIFT*2,
PH120SHIFT*2+PH120SHIFT/2
};

#define HALL_ABC() ((GPIOB->IDR & (0b111<<6))>>6)
#define HALL_LOC() (hall_loc[HALL_ABC()])

/*
The sine table is indexed with 8 MSBs of uint32; this way, a huge resolution is implemented for the frequency,
since the frequency is a term added to the indexing each round. <-- this comment was written when interpolating between hall updates :)
*/

const int sine[256] =
{
0,804,1607,2410,3211,4011,4807,5601,6392,7179,7961,8739,9511,10278,11038,11792,
12539,13278,14009,14732,15446,16150,16845,17530,18204,18867,19519,20159,20787,21402,22004,22594,
23169,23731,24278,24811,25329,25831,26318,26789,27244,27683,28105,28510,28897,29268,29621,29955,
30272,30571,30851,31113,31356,31580,31785,31970,32137,32284,32412,32520,32609,32678,32727,32757,
32767,32757,32727,32678,32609,32520,32412,32284,32137,31970,31785,31580,31356,31113,30851,30571,
30272,29955,29621,29268,28897,28510,28105,27683,27244,26789,26318,25831,25329,24811,24278,23731,
23169,22594,22004,21402,20787,20159,19519,18867,18204,17530,16845,16150,15446,14732,14009,13278,
12539,11792,11038,10278,9511,8739,7961,7179,6392,5601,4807,4011,3211,2410,1607,804,
0,-804,-1607,-2410,-3211,-4011,-4807,-5601,-6392,-7179,-7961,-8739,-9511,-10278,-11038,-11792,
-12539,-13278,-14009,-14732,-15446,-16150,-16845,-17530,-18204,-18867,-19519,-20159,-20787,-21402,-22004,-22594,
-23169,-23731,-24278,-24811,-25329,-25831,-26318,-26789,-27244,-27683,-28105,-28510,-28897,-29268,-29621,-29955,
-30272,-30571,-30851,-31113,-31356,-31580,-31785,-31970,-32137,-32284,-32412,-32520,-32609,-32678,-32727,-32757,
-32767,-32757,-32727,-32678,-32609,-32520,-32412,-32284,-32137,-31970,-31785,-31580,-31356,-31113,-30851,-30571,
-30272,-29955,-29621,-29268,-28897,-28510,-28105,-27683,-27244,-26789,-26318,-25831,-25329,-24811,-24278,-23731,
-23169,-22594,-22004,-21402,-20787,-20159,-19519,-18867,-18204,-17530,-16845,-16150,-15446,-14732,-14009,-13278,
-12539,-11792,-11038,-10278,-9511,-8739,-7961,-7179,-6392,-5601,-4807,-4011,-3211,-2410,-1607,-804
};

#define PID_I_MAX 2000000000LL
#define PID_I_MIN -PID_I_MAX
#define MIN_MULT_OFFSET 10

void tim1_inthandler()
{
static int mult = 0;
static int currlim_mult = 255;
static int32_t cnt = 0;
static int expected_next_hall_pos;
static int cnt_at_prev_hall_valid = 0;
static int cnt_at_prev_hall;
static int prev_hall_pos;
static int prev_ferr = 0;
static int f = 0;
static int pid_f_set;
static int64_t pid_integral = 0;

TIM1->SR = 0; // Clear interrupt flags

int hall_pos = hall_loc[HALL_ABC()];
if(hall_pos == -1) hall_pos = prev_hall_pos; // glitchy value -> assume previous

int reverse = (pid_f_set<0)?1:0;

if(hall_pos == expected_next_hall_pos)
{
// We have advanced one step in the right dirction
// calculate the frequency from the delta time.

if(cnt_at_prev_hall_valid)
{
f = (PH120SHIFT)  /  ((cnt-cnt_at_prev_hall));
}
else
{
f = 0;
}

cnt_at_prev_hall_valid = 1;
cnt_at_prev_hall = cnt;
}
else // We are lost
{
lost_count++;
cnt_at_prev_hall_valid = 0;
f = 0;
}

prev_hall_pos = hall_pos;

expected_next_hall_pos = hall_pos;
if(!reverse) { expected_next_hall_pos++; if(expected_next_hall_pos > 5) expected_next_hall_pos = 0; }
else         { expected_next_hall_pos--; if(expected_next_hall_pos < 0) expected_next_hall_pos = 5; }


// Ramp the speed setpoint.
int next_pid_f_set = (spi_rx_data.speed*100);
if(next_pid_f_set > pid_f_set) pid_f_set+=256;
else if(next_pid_f_set < pid_f_set) pid_f_set-=256;
if((next_pid_f_set - pid_f_set) > -256 && (next_pid_f_set - pid_f_set) < 256) next_pid_f_set = pid_f_set;


// Run speed PID

int pid_f_meas = f>>3;
if(reverse) pid_f_meas *= -1;

int ferr = pid_f_set - pid_f_meas;

spi_tx_data.speed = pid_f_meas>>8;

if(!(cnt & 15)) // don't run the PID every round
{
int dferr = (ferr - prev_ferr);
prev_ferr = ferr;

pid_integral += ferr;

if(pid_integral > (PID_I_MAX)) pid_integral = PID_I_MAX;
else if(pid_integral < (PID_I_MIN)) pid_integral = PID_I_MIN;

mult = ((30*(int64_t)pid_f_set)>>10) /* feedforward */
+ ((50*(int64_t)ferr)>>12) /* P */
+ ((50*(int64_t)pid_integral)>>19)  /* I */
+ ((50*(int64_t)dferr)>>12); /*D*/
}

// Generate the sine

// Hall magic: get the magnetic position of the rotor right now.
int loc = (base_hall_aims[hall_pos] + timing_shift + (reverse?(-PH90SHIFT):(PH90SHIFT)));

// Indexes to the sine table (arithmetic wrap-around utilized):
int idxa = (((uint32_t)loc)&0xff000000)>>24;
int idxb = (((uint32_t)loc+PH120SHIFT)&0xff000000)>>24;
int idxc = (((uint32_t)loc+2*PH120SHIFT)&0xff000000)>>24;

const int max_mult = 150*256;
const int min_mult = -150*256;

if(mult > max_mult) mult = max_mult;
if(mult < min_mult) mult = min_mult;

int sin_mult = mult>>8;
if(reverse) sin_mult *= -1;
if(sin_mult < 0) sin_mult = 0;

if(sin_mult != 0)
sin_mult += MIN_MULT_OFFSET;

// Calculate the final multiplier, which is the combination of the PID loop output and current limit
uint8_t m = (sin_mult * currlim_mult)>>8; // 254 max
TIM1->CCR1 = (PWM_MID) + ((m*sine[idxa])>>14); // 4 to 1019.
TIM1->CCR2 = (PWM_MID) + ((m*sine[idxb])>>14);
TIM1->CCR3 = (PWM_MID) + ((m*sine[idxc])>>14);

cnt++;

int current = latest_adc[1].cur_b-dccal_b; // Temporary solution only looking current in phase B, adc timing must be improved

spi_tx_data.current = current;

if(OVERCURR()) // DRV8302 configurable cycle-by-cycle current limit signal: the gate driver has already terminated the pulse, this is information about it.
{
LED_ON(); led_short = 0; // give long blink
currlim_mult-=50;
}
else if(current < neg_curr_lim || current > pos_curr_lim) // soft current limit (by shunt & amp & adc)
{
LED_ON(); led_short = 1; // give short blink
currlim_mult-=2;
}
else if(currlim_mult < 255)
currlim_mult++;

if(currlim_mult < 5) currlim_mult = 5;

}
« Last Edit: November 15, 2017, 04:59:10 pm by Siwastaja »
 

Offline Glenn0010Topic starter

  • Regular Contributor
  • *
  • Posts: 214
  • Country: mt
Re: BLDC Motor Controller, RC Snubber Design + Waveforms
« Reply #46 on: November 15, 2017, 07:04:18 pm »
Hey,

so I started doing my research on SPWM and I realize that I know much less that I thought. The more I read from different sources the more confused I become!

The following photos is how I tough SWPM was done but I'm pretty sure that it's wrong after doing my research. If you have some time to look for my reasoning in the photos.




I thought that all SPWM was, that instead of switching the phases with a constant duty cycle, you vary the duty cycle from a look up table to get a sine looking wave form but I think this is wrong as seen below. Instead of getting a complete sine current as seen on the right if I do this method, I will get a smoothed version of the wave form on the left as seen in red, where there would be parts of it were the current would be 0 i.e. not sine.



This is further confirmed byu this resource I found:

http://www.zilog.com/appnotes_download.php?FromPage=DirectLink&dn=AN0380&ft=Application%20Note&f=YUhSMGNEb3ZMM2QzZHk1NmFXeHZaeTVqYjIwdlpHOWpjeTloY0hCdWIzUmxjeTlCVGpBek9EQXVjR1Jt

As opposed to trapezodial or block commutation,
 in which two of the three phases are energized for each commutation step, the sinusodial commutation requires all three pahses to be energized for each step


So I am pretty sure I do not have the right concept. I can not understand what is the right ways to switch on the three pahses right now. I will keep doing some more research and try to understand your code.


It surely could not be as simple as say: when you are switching for example, the yellow high side mosfet(half bridge 1), you switch on both blue(half bridge 2) and green  (half bridge 3) low side mosfets. Also I am only applying PWM to the high side FETS while keeping the lowside fets either completely on or completely off. Is this possible for SPWM?
Do you know a good resource to help me in understanding this?



Regards Glenn
« Last Edit: November 15, 2017, 07:16:53 pm by Glenn0010 »
 

Offline Glenn0010Topic starter

  • Regular Contributor
  • *
  • Posts: 214
  • Country: mt
Re: BLDC Motor Controller, RC Snubber Design + Waveforms
« Reply #47 on: November 17, 2017, 02:22:28 pm »
So after a bunch of research I think I figured it out!

First I will implement what I found to be refereed to modified SPWM. Which basically is a trapezoidal control (only switching two phases on at time). However instead of switching them on symmetrically(with the same PWM value), You vary the PWM value to represent a sine wave.

To do this, I must first measure the motor speed to determine the frequency of the electrical cycle and then go from there.

Once I have implemented modified SPWM I will move on to full SPWM. I found a freat resource which states the following and after some matlab simulation #s this was also confirmed.

Using  three  different  pointers  PWM  pulse  width  data  values  corresponding  to  the  three  phase
waveform are accessed. These pointers are adjusted so as to point to pulse width values that are 120
0
 degree
phase shift apart in time from other. The number of PWM pulses per cycle is equal to f c /f m . Where f c  is carrier
frequency and f m  is modulating signal frequency. This number must be divisible  by three in order to obtain
synchronous three phase PWM waveforms. For example if f c  = 3600Hz and f m  = 50Hz then number of pulses per
cycle is equal to 72. This number is divisible by three 72/3 = 24. So while accessing the pulse width values first
pointer  points  to  zeroth  location,  second  pointer  points  to  24
th
  location  of  array  and  at  the  same  time  third
pointer points to 48
th
 location of array. The following  steps illustrate the algorithm to obtain the three phase
PWM waveforms using microcontroller; 
1)  Access the three phase synchronous PWM pulse width data values from look up table using three different
pointers to look up table.
2)  Send the desired PWM code pattern at port pins.
3)  Set the timer value with lowest pulse width value first.
4)  Start the timer and wait until timer flag set.
5)  Send the next desired PWM code pattern at port pins.
6)  Set the timer value with next higher pulse width value.
7)  Start the timer and wait until timer flag set.
8)  Send the next desired PWM code pattern at port pins.
9)   Set the timer value with next higher pulse width value.
10)   Start the timer and wait until timer flag set.
11)   Increment pointer by one and loop back step 1.


So I think I have the jist of it. I am sure that it will not be so easy but I have a good jumping off point
 

Offline Glenn0010Topic starter

  • Regular Contributor
  • *
  • Posts: 214
  • Country: mt
Re: BLDC Motor Controller, RC Snubber Design + Waveforms
« Reply #48 on: December 26, 2017, 04:29:41 pm »
Hey All

So I have been designing a compact version of my controller. I have taken as much advice as possible from you guys. I have finished my first draft so to speak. If anyone can spare some time can you guys take a quick look at the gerber files to spot anything obviously wrong?

I plan on reviewing it again before finalizing it since I have never designed a PCB of this complexity.

Any advice will be greatly appreciated.

The Gerber files should be attached here: https://www.dropbox.com/s/93tcssz6w1glc7w/UCC20520%20Driver%20P0.32%20-%20CADCAM.ZIP?dl=0

Thanks
« Last Edit: December 26, 2017, 04:36:43 pm by Glenn0010 »
 

Offline Glenn0010Topic starter

  • Regular Contributor
  • *
  • Posts: 214
  • Country: mt
Re: BLDC Motor Controller, RC Snubber Design + Waveforms
« Reply #49 on: January 01, 2018, 05:03:45 pm »
Here Is my finalized design! Just waiting for the parts to arrive so I can check the footprints before I order the PCBs its a 4 layer board!
Some of the 3D render items such as the capacitor and the buck converter are messed up since I made some alterations to the footprints however the fottprints are correct. The big silk screen next to the FETs is space for the big electrolytic caps. I will lay them flat against the board. I know some of you suggested that this would increase the lead length and hence the inductance, however I think this is the most space efficecnt way to place them. They are labelled C1 and C2




 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf