New ground-up ESC - MESC_FOC_ESC

mxlemming,

I use git command-line on Linux. This is what I did:

1. Cloned the repo on github
2. Checked-out the latest branch (#0894c6b2)
3. Loaded the project in KiCAD

But this (from your post on Mar 28, 2021) is nowhere to be seen. The pcb in the cloned project has V0.5 on the silkscreen layer. Saw no change after running "Update PCB from the schematic" in KiCAD. I'm guessing you may still have some changes in your local staging area that should be committed before the repo is pushed to origin (i.e. github). Btw, you can replicate what I did into a clean temporary directory and diff it with your main project.

Thanks,
 
Following feedback from zombies and others, i binned the branch rearranging it further. Never completed, never will be unless you do it.

Reason being that with more area around the FETs there will be more cooling and therefore more power. The FETs are very much limited by the amount of heat that can be conducted out of them when using the ipt015s.

I'll check later that the commit hash I gave above is good for manufacture.
 
Ah! that explains why. I appreciate your help very much. Hoping to place the order by this weekend.

Cheers,
 
zinahe said:
Ah! that explains why. I appreciate your help very much. Hoping to place the order by this weekend.

Cheers,

Hi Zinahe,

I had a quick look through the hardware Repo. I have really not worked on this atall, since March this year, and no substantial changes since December last year when I made the current boards.

MESC Hardware Status 20220920.PNG

If you go for the "as ordered" option (highlighted), it will definitely work. I have done hundreds of miles with it with a friend on two ebikes, me at 13s, him at 20s, running something like 60 phase amps without getting hot atall.

If you want the option to run other micros, then you will have to re generate manufacturing files from the master (also highlighted). This should be fine as well, but untested. The significant difference was the addition of a 100ohm resistance between the external opamps and MCU since fresh MCUs often have weird programming pin configs that fight the opamps. You would also have to add in the INA181A1

Bear in mind that JLCPCB and KiCad have different opinions on footprint orientation,you have to manually check and edit and re-upload. The V0.5 files *should* have the correct orientations.

You will have to add a few components JLC do not have, e.g. connectors, gate drivers if they are out of stock.

Component substitutions... (optional)
1) Recommend using On Semi gate drivers, NCP5183 or similar. More robust than the old Infineons 2181 of the same footprint, though JLC have the IR2181 so...
2) LMR64010 for the DCDC boost is slightly preferable to the TPS61041, but use whatever JLC have (TPS61040 I think is identical)
3) The 3v3 regulator I used originally as supplied by JLCPCB was OK, but frankly not the best. On another board I made I swapped it out with a similar pinout TI reg and found it was much better. If you have the enthusiasm, I would recommend refitting the 3v3 reg with an AMS1117-3v3 which JLCPCB have 28000 of currently and I have found to be much much better on another project.

Might be able to add capacitors from JLC if you feel like modifying. They weren't doing through hole last December. You do not need to fully populate the capacitors. I run it just fine with 2x470uF electrolytics. Also might be able to get them to populate connectors, though these are on the other side.

Good luck, and remember, I will not request either piece back from you if it's broken :D
 
Had a good chance to do some coding recently. I made a few changes:
1) Ported it so I can now run it on F405 (VESC) based hardware
2) Removed all the magic numbers from the main FOC loop
3) Fixed up the sensorless algorithm.

Previously, I was running mainly with hall sensors, though I rode occasionally with the sensorless algorithm I made using a method where I simulated a hall sensor from the back EMF.

The new sensorless algorithm is what I want to write about today, wondering if anyone has any pertinent comments.

My concept (second concept) is as follows:
Vd and Vq are accurately controlled by the PID loops.

Va and Vb are, by necessity kept closely locked in with the rotor back EMF, and are the inverse park transform of the VdVq.

If you were to base the angle directly off the instantaneous back EMF, I think there would be serious stability problems because of rapid changes due to... noise, load... causing sudden back EMF jitter, pushing the angle wrong and then rapid runaway, BUT, if you low pass filter it, the noise and jitter goes away.

Low pass filtering is not desirable since it results in lag and error and slow response. However, we have a system that is strictly cyclical, and where it is therefore not necessary to have a decay time. Sinusoidal.

The integral of a sinusoid being a cosinusoid and so on, if you low pass with no decay, you introduce a phase shift of known magnitude - 90 degrees.

So, we perform the math:
Code:
void flux_observer() {
    // This function we are going to integrate Va-Ri and clamp it positively and
    // negatively the angle is then the arctangent of the integrals shifted 180
    // degrees
    BEMFa = BEMFa + foc_vars.Vab[0] - motor.Rphase * foc_vars.Iab[0] -
            motor.Lphase * (foc_vars.Iab[0] - Ia_last) * foc_vars.pwm_frequency;
    BEMFb = BEMFb + foc_vars.Vab[1] - motor.Rphase * foc_vars.Iab[1] -
            motor.Lphase * (foc_vars.Iab[1] - Ib_last) * foc_vars.pwm_frequency;
    Ia_last = foc_vars.Iab[0];
    Ib_last = foc_vars.Iab[1];


    if (BEMFa > motor.motor_flux) {  BEMFa = motor.motor_flux;    }
    if (BEMFa < -motor.motor_flux) { BEMFa = -motor.motor_flux;    }
    if (BEMFb > motor.motor_flux) {  BEMFb = motor.motor_flux;    }
    if (BEMFb < -motor.motor_flux) { BEMFb = -motor.motor_flux;    }

    angle = (uint16_t)(32768.0f + 10430.0f * fast_atan2(BEMFb, BEMFa)) - 32768;
  }

That is it, in it's entirety. The fast atan2 was borrowed from Oskar Weigl at Odrive, who had borrowed it from some public domain blog. Thanks to both, that simplified my life a load :p.

The clamps on the flux integrals exist to deal with gradual drift in the integrals due to noise and current shunt offsets etc, and simply say "We know what the max integral is, it's a property of the motor, if it's larger than that, we have drifted due to noise so clamp it.".

The fast_atan2 returns an angle in radians, and I use uint16_t for my angles, so I correct for the phase shift and scale.

It works, with my 7pole pair 50-100kV motors it spins with low load down to about 10eHz and once above about 30eHz is thoroughly locked in and can handle aggressive grabbing the rotor, near instantly stopping it etc.

It runs both directions with no fussing, and can go through zero velocity easily, provided the acceleration is fairly rapid.

Observation of the phase angle the PWM/current makes with the hall sensors shows that it is basically phase correct, though clearly lagging by 1pwm cycle in the current implementation (for obvious reasons; last cycles data being used to predict this cycle's angle).

Downside (that I found so far) is that it refuses to run whatsoever with my tiny little 1200kV RC motor. I presume it simply can't see a back EMF at the speeds I can flick it up to by hand. I have not implemented any startup routine yet. (Edit: it works fine with the little motor, not sure what I messed up first time)

Have not tested with field weakening yet. This one might be problematic if field weakening actually does "weaken the field" and reduce the back EMF. (Edit, in the course of doing this, I have observed that field weakening does not actually weaken the field, and the observer works fine under moderate field weakening - tested up to 50A with an 8080 motor for nearly 2x base speed)

So why is this not a normal, standard method for sensorless control? It seems so simple and obvious that I only just tried it having previously thought it could never possibly work or everyone would be doing it. What's the catch? What's going to suddenly bite me?

Going to try loading it onto a bike and giving it some serious load, see if it stays stable when the motor is being driven close to it's saturation limits.

No video yet, unfortunately I actually implemented this on an F405 controller so I could simply discard the notion of saving clock cycles with a processor 2x as fast. I want to first share a video of it running on the original MESC hardware, not borrowed hardware. It will definitely back port to the F303, but I will need to do a bit of tidying up
 
To be honest, that I can't follow your thoughts about sensorless commutation in detail. I guess, it bases on some fundamental equations like this:

V4-BLDC-MOTOR-THEORY.jpg


Can you try to explain better?!

regards
stancecoke
 
stancecoke said:
To be honest, that I can't follow your thoughts about sensorless commutation in detail. I guess, it bases on some fundamental equations like this:

V4-BLDC-MOTOR-THEORY.jpg


Can you try to explain better?!

regards
stancecoke

I'll struggle to explain because there's really nothing to it.

It does indeed come from fundamental equations.

Imagine you spin the motor by hand and scope it... You get a3 phase sin wave. Clearly from this, given any snapshot in time you could calculate the rotor position.

If you made the Clark transform of this 3 phase wave, it would be even easier... You'd just take the arctangent and that would be your angle.

When you're driving the motor with pwm, the same still applies but you have to account for current. You can reconstruct the voltage from back EMF from the pwm, and of course it works out to be the Va and Vb of the PI loop and park transform output minus the IR and Ldi/dt.

But this is noisy. If you arctangent this, you get the angle but with horrendous instability and it will positively feed back error the next cycle.

If you integrate however, your sin waves remain sin waves but phase shifted 90 degrees and increased in amplitude with the same absolute noise.

Thus when you take the arctangent, you get a much more accurate estimation of the angle, only phase shifted 90 degrees. So you just shift it by that angle. (Note in the code that it's 180 degrees, this is because the voltage generated is of course in quadrature to the magnetic field so there's a 90+90 phase shift).

There's nothing more to it.

I need to test this more extensively, it's not yet clear to me how well this holds up to real world use cases. So far I've only run on my bench with 48V and the load being me grabbing the motor shell until it burns my hand.
 
[youtube]9nxzEXHdLXA[/youtube]

Got it running on the original MESC board. This is good. It runs equally well, even though it seems to be overrunning the FOC loop at 35khz.

Need to trim the code a bit or accept that 35khzpwm might just be faster than is strictly needed and reduce to 20ish.
 
flute2k3@hotmail.com said:
you can't find a 2.5$ F303 any more.

More generally you can't find any stm32s with an fpu any more. Or any infineon chips. Or atmel or cypress or...

I'm not personally so concerned, I have enough to see me through and I'm sure they'll come back one day.

I can run this on pretty much any f3 f4 h7 l4, g4... MCU without much effort (day or two, depending how much of a fight the flash puts up) because it's all set up in cubeIDE. I just have to set up 2 timers, get the ADC reading 3 currents and a voltage, map the adc readings to the FOC variables and then... Get the cursed flash to store and retrieve settings.

Last time I ported to f405, it was running in about 2 hours and saving variables by about 4am after I got my more programming competent friend to just fix it.
 
mxlemming said:
flute2k3@hotmail.com said:
you can't find a 2.5$ F303 any more.

More generally you can't find any stm32s with an fpu any more. Or any infineon chips. Or atmel or cypress or...

I'm not personally so concerned, I have enough to see me through and I'm sure they'll come back one day.

I can run this on pretty much any f3 f4 h7 l4, g4... MCU without much effort (day or two, depending how much of a fight the flash puts up) because it's all set up in cubeIDE. I just have to set up 2 timers, get the ADC reading 3 currents and a voltage, map the adc readings to the FOC variables and then... Get the cursed flash to store and retrieve settings.

Last time I ported to f405, it was running in about 2 hours and saving variables by about 4am after I got my more programming competent friend to just fix it.

have you ever thought to work on a platform like esp32? could be painful start from scratch but this is a pretty popular high PPR mcu now days, the integrated BT and wifi may almost unlimited possibility. I see simple FOC support this guy and they now support mosfet low side current sensing.
 
I started out with an esp actually but there are issues with the development environment. The st chips give you a really easy environment with good debugging and register access. The ESP... not so much. Atall.

The simple FOC is nice, but requires encoder and isn't all as simple as they say. It takes some significant setup. Also, being runnable on an Arduino it has some serious performance compromises with speed I think. At the time I wrote the bulk of this and made the first ESC it was not really of any use. I see it's progressed a lot and now people are making quite cute little robots with it. It has position control which I've not even thought about yet and all kinds of nice robotics features... Very cool project but not for me here.

The big thing about the ESP is it's not got floating point support which ultimately is just a nuisance I don't want to deal with.

I also don't really want BLE and WiFi on the same module as is commuting many kilowatts of motor. If a little table walking robot crashes, it falls 3 inches and some tiny trace or fuse might blow. If my board crashes, it locks the rear wheel and shorts 6kg of lithium ion cells through the motor until the 80A fuse blows.
 
mxlemming said:
I started out with an esp actually but there are issues with the development environment. The st chips give you a really easy environment with good debugging and register access. The ESP... not so much. Atall.

The simple FOC is nice, but requires encoder and isn't all as simple as they say. It takes some significant setup. Also, being runnable on an Arduino it has some serious performance compromises with speed I think. At the time I wrote the bulk of this and made the first ESC it was not really of any use. I see it's progressed a lot and now people are making quite cute little robots with it. It has position control which I've not even thought about yet and all kinds of nice robotics features... Very cool project but not for me here.

The big thing about the ESP is it's not got floating point support which ultimately is just a nuisance I don't want to deal with.

I also don't really want BLE and WiFi on the same module as is commuting many kilowatts of motor. If a little table walking robot crashes, it falls 3 inches and some tiny trace or fuse might blow. If my board crashes, it locks the rear wheel and shorts 6kg of lithium ion cells through the motor until the 80A fuse blows.

thank you for share with professional and valuable comments :thumb:
 
Nice work with sensorless foc and porting to the F405. I will definitely give it a go since it will work with existing hardware.

mxlemming said:
But this is noisy. If you arctangent this, you get the angle but with horrendous instability and it will positively feed back error the next cycle.

If you integrate however, your sin waves remain sin waves but phase shifted 90 degrees and increased in amplitude with the same absolute noise.

Since you are integrating the bemf and calculating atan2 anyway, would it be worth implementing a quadrature PLL to track angle with better noise immunity.
 
Would be interesting to have someone else give it a go.

For now, bear in mind it's a right mess inside the code. Like... Carnage.

I need to go through it and remove the mass of commented out functions and get the state machine back to the point where I can reliably press keyboard buttons to make it run detection etc...

Also currently requires hall sensors even though it doesn't use them.

I'm pleased enough with the progress that i want to have a bit of a push over the next few weeks.

I'll look into the pll at some point. I'm not convinced it needs it, the integration vastly reduces the noise; signal in Va Vb with ~1V noise on... 20V signal vs 1V noise on 20Vx the number of pwm periods per sin wave.

I tried it with my problem motor, the at12070, last night. It... Worked... But the id was all over the place. It's a harmonicy mess with super low resistance. Startup was great but at higher speeds it kept on tripping my (very conservative at 48A) overcurrent.
 
district9prawn said:
Nice work with sensorless foc and porting to the F405. I will definitely give it a go since it will work with existing hardware.

mxlemming said:
But this is noisy. If you arctangent this, you get the angle but with horrendous instability and it will positively feed back error the next cycle.

If you integrate however, your sin waves remain sin waves but phase shifted 90 degrees and increased in amplitude with the same absolute noise.

Since you are integrating the bemf and calculating atan2 anyway, would it be worth implementing a quadrature PLL to track angle with better noise immunity.

I had a further look into this in my simulator (written in Excel :? :? ) And have found that with noise 0.1x signal and 0.1x on pretty much any harmonic (that's a really ugly BEMF profile) it can cause about 5 degree error.

A pll would probably help this but would introduce lag. Switching the pll has clock cycle implications.

Unsure what the best way to go with this is tbh, it seems absolutely fine for the 8080 motors which have sensible inductance and ok BEMF but the big motor runs less well and has a large fluctuating Id.

The big motor is also horrid with hall sensor interpolation though and doesn't exactly run beautifully with VESC either. Hoping to get some incremental encoders in the post soon so should be able to get the absolute truth.

What motor would you plan on running?
 
district9prawn said:
A quadrature PLL like this seems to do the trick in simulation. Output is speed, which you can integrate to position.

lUyIiYJ.jpg


I would like to try sensorless foc on an stm32h7 and play around with some algorithms.

What's the transient response of your quadrature pll like? I can see that it would be good for a stable speed estimate, but I would have thought it would result in significant lag as the KTs(z-1) term catches up and you integrate that error into the output angle.

Clearly anything more than about 45 degrees of error becomes instantly unstable.

Do you have H7 based hardware? I really ought to create some if I'm going to carry on doing motors but i just have too many boards now.
 
mxlemming said:
What's the transient response of your quadrature pll like? I can see that it would be good for a stable speed estimate, but I would have thought it would result in significant lag as the KTs(z-1) term catches up and you integrate that error into the output angle.

Should be ok to track rapid acceleration of a small motor with a reasonable loop freq. Haven't tried on real hardware though. Another problem is that it will track 180 degrees out of phase in the reverse direction so need some logic to check speed and adjust sign of the summer to ensure smooth speed reversal.

mxlemming said:
Do you have H7 based hardware? I really ought to create some if I'm going to carry on doing motors but i just have too many boards now.

No hardware of my own. I'm a noob when it comes to power pcb design. At the moment just have a H7 nucleo board wired up to a mosfet board which should be ok for low current.
 
So ina kind of big update, I've been running this sensorless for a few weeks now on my ebikes with the big at12070 motor. I've all but scrapped using hall sensors because it works better sensorless.

It's been a bit longer than I'd like, but I've un mangled most of the magic numbers so it now all works in real volts and amps.

I've changed the interrupt orders so it's now running on the timer interrupt at top and bottom so 70khz update. At the top, it runs FOC PIDs, and at the bottom it increments the angle and runs svpwm

I'm now working on a different aspect of it, that is the sensorless from standstill, by HFI. There's been a bit of an explosion in sensorless from standstill with skytec, some guy calling himself SMC technologies (good luck with that one...) And then VESC had a new HFI...

Well VESC was incomprehensible as usual (though it really does work very well), smc and skytec are not sharing how they do it, so I just had a crack injecting waveforms. It turned out that just injecting a few volts ripple in the d axis would result in no q axis current ripple if the axis was aligned, and if misaligned there would be resultant current ripple in the q axis. The sign of the ripple indicates the direction of misalignment.

A quick but of bodging PID loops later and...
[youtube]plH662qOeQ0[/youtube]

And

[youtube]yvL5Jz6EJGQ[/youtube]

Need to do two more things before it's especially useful,
1) make a transition to the observer since it stops tracking at about 25Hz(plenty for the observer to take over) and
2) resolve the 180 degree ambiguity, since it currently likes to pick an arbitrary direction to spin... Though it's very convinced of that direction.

Extra thanks and credit go to my friend who helps me with C and to Elwin who discussed ideas for this with me in some detail and helped me tame the FOC PIDs before I wrote any code atall.
 
No so convinced by the thermal design though. The Fet will heat up the entire pcb (plus all components) before reaching the heatsink. Sure, if it works well and the fet stay cool, you can cool the entire pcb that way, but if they run hot, wouldn't it drastically shorten the lifespan of all smaller components ?

Take some copper sheet, cut it to size, bend it into an "L" shape, and solder it to the FET tab such that the top of the "L" is flush with the plastic top of the FET. File everything flat and smooth with a sanding block. Heat sink the metal pieces.

They also make FETs (ex: IAUS300N10S5) that have the thermal pad on the top, for cooling. If you are running serious currents you'll want the FETs to be well-cooled.
 
https://youtube.com/shorts/LnsOoPVdSe8?feature=share

[youtube]LnsOoPVdSe8[/youtube]

Implementation of HFI going better than I'd expected. Really quite pleased with it so far.

I'm really not concerned about the current. I can push plenty for my purposes at the moment. 100A is pretty easy and gets me shifting pretty quick at 20s voltage. I've got another controller I built that can do about 300A, but nothing useful to strap it to.

Very glad I've all but given up on VESC related projects. It's easy to get sucked in by the great UI but the learning from fiddling with it and trying to work out what's going wrong is nothing compared to sitting down and just doing it from first principles.

IMG_20220409_230323366.jpg
I put it on a box today instead of last year's tape and string efforts. Working towards tidying up the bike. Which is starting to upset me with it's messiness.
IMG_20220409_121657484_HDR.jpg
 
Updates.

Implemented tracking and switchover between pwm and no pwm and

Implemented a crude 180 degree HFI disambiguation. It's now completely silent at standstill, little hiss as hfi starts and then smooth torque.

Implemented max power limiter so I can set the max battery draw.

It gets easier and faster to develop when you use real numbers and si units.

The original MESC hardware has been stable at 100A running on a hub motor and 3kW at 20s. The old hardware just keeps giving...

Very pleased with where this has ended up. With the bigger motors it's delivering everything I wanted from an ebike, with lots of headroom.

I've been pretty careful but somehow still haven't killed a single MOSFET since the original board... Gate drivers and DCDC chips have been a bit more fragile.

Wondering if I've had a small breakthrough with the ti lm5017 dcdc situation as well, it appears the on time the data sheet gives with resistor choice is way off, despite aiming for 500khz ish it was actually clocking over 1mhz which probably causes extra stress on the switch. They still shouldn't blow though.

After a few hundred miles of testing and gradually boosting the settings higher and higher, it seems to just be pretty stable. I'll try to write a bit of an instruction for anyone interested in trying out the firmware on a VESC/f405 based board. So far, it's been successfully run on a trampa VESC 6 and a VESC 100250 board.

I'm now working on a bit ofa logger for it, writing very simple python.
https://youtube.com/shorts/yKSXnGSjo64?feature=share
[youtube]yKSXnGSjo64[/youtube]
 
flute2k3@hotmail.com said:
@mxlemming, can STM32f302CB do the same thing? happened to have two 302 chips on hand.

It could but it would take porting and setup. Also you'd need external op amps or current sensors since f302 i recall only has 2 and I'm not going to deal with that nonsense.

Just built up the easy DIY ESC from badgineer and casainho (I've been helping badgineer a bit) and I'm trying to port MESC to the black pill f401 which is (just about) pin compatible with blue pill so that might bea better option for you!
IMG_20220512_015313297.jpgIMG_20220512_015327825_HDR.jpg

Give ita few days. I only got the board this evening so I've soldered it up and programmed some pwm and ADC reads. Seems to work ok so far.
IMG_20220512_012349539_HDR.jpg

It's built up with leftover bits from past projects but no contraindications at this stage.
 
Back
Top