come on!
⦠why Iām trying to use simplefoc lib?ā¦
because Iām bamby in C++ and BLDC motor.. !
am I looking for something that doesnāt exist?
come on!
⦠why Iām trying to use simplefoc lib?ā¦
because Iām bamby in C++ and BLDC motor.. !
am I looking for something that doesnāt exist?
Yeah, if you donāt want to learn C++, you should probably buy an ODrive or something instead of trying to reuse the onewheel motherboard. SimpleFOC is a huge boost compared to starting from scratch, but itās still fairly technical compared to a well tested and documented firmware written for a specific piece of hardware. And even those are difficult to use. When I tried ODrive, I ended up having to add an arduino and its associated ratās nest of wires just to tell the motor to relax when set to 0 speed.
Of all things Iāve done in life, I think brushless motor control has the largest gap between how complicated I imagined it to be and how complicated it really is.
On the bright side, SimpleFOC uses C++ in the old fashioned āC with classesā style. I canāt stand āmodern C++ā with its ridiculously complicated standard library that youāre pressured into using for absolutely everything. Iām happiest with regular C, but the addition of member functions and inheritance does save a fair amount of typing, so I begrudgingly admit itās the better choice in most cases.
none of that sirā¦. to be clear, I donāt emit a single critic about the actual lib⦠a gift for community.
my only concern is to know if simplefoc is able to generate waves to drive a motor quietly. if yes , I will dig further, if no , okay , no pb either, Iāll push my investigation for my personnal fun
best regards
Certainly it can. And since calling setPwm directly works, the problem is pretty much narrowed down to something that happens in the very small BLDCMotor::velocityOpenloop function, so it should be easy to find. And hopefully fixing it will fix the bad closed loop waveforms too.
okay⦠āje vais tirer la pelotteā
This is really weird. The output from open loop should be a nice sine wave, like the one you posted from your own test code.
Can you set an appropriate voltage limit and then run the motor in pure voltage mode, without setting the Resistance, KV or inductance values on the motor?
This should remove any complicated calculations based on the sensor that might affect the resultsā¦
I would really love to had make a mistake.
I will try tomorrowā¦.
Hi
after removing all the bellow stuff ā¦
//BLDCMotor motor = BLDCMotor(polePairs,0.25,1.00,0.006);
BLDCMotor motor = BLDCMotor(polePairs);
the result is exactly the same..
but
if I remove the line
motor.monitor();
il the main loop ,
void loop()
{
//________normal section
// main FOC algorithm function
motor.loopFOC();
// Motion control function
motor.move();
// display the currents
// motor.monitor();
//________end normal section
}
I have the following curve ::
so behaviour change only by removing motor monitoring??? ![]()
still not sinus ⦠but.. it is probably a clue for you guysā¦.
You know, Iāve never actually used the monitoring code⦠Looking at it now, it can indeed cause blocking delays. I think it was ok on the original 8-bit arduinos, but on STM32, multiple calls to Serial.print in a single frame is bad. We should change it to either print one variable per frame and divide the delay by the number of variables enabled, or have it print into a char array and then print the whole thing to serial at once.
The chopped peaks of the wave looks like itās saturating. One more confusing thing about SimpleFOC is that the motor voltage limit can only be half the driver voltage limit (or 58% if using SpaceVectorPWM). Iām not sure if thatās whatās happening in this case, but itās something to be aware of. Hereās an article explaining it in more detail Field Oriented Control | Arduino-FOC
so you are saying that Iām the first and only guy that used the monitoring feature , really? ![]()
herebellow the limits implemented :
// pwm frequency to be used [Hz]
// for atmega328 fixed to 32kHz
// esp32/stm32/teensy configurable
driver.pwm_frequency = 15000;
// power supply voltage [V]
driver.voltage_power_supply = 20;
// Max DC voltage allowed - default voltage_power_supply
driver.voltage_limit = 10;
// dead_zone [0,1] - default 0.02f - 2%
driver.dead_zone = 0.01f;
I remember that I also tested the
driver.voltage_limit = 5;
just to see⦠and the result was a wave , indeed half the previous but divided by two ⦠with the same shape.
tomorrow Iāll try to remove completly the
SimpleFOCDebug::enable(&SerialDebug);
bye and good night ![]()
I just noticed the voltage divisions set to 2 in the last oscilloscope image. So 10V peak to peak is indeed saturating at your driver voltage limit. Try motor.voltage_limit = 1; and see how it looks.
Also double check that your driver.voltage_power_supply is correct. Looking back at your successful sine wave in post #39, the oscilloscope divisions are 5V, so peak to peak amplitude is ~16V. But since the code says 10+4*sin(i) it should be 8V peak-to-peak. The voltages you pass to setPwm are divided by voltage_power_supply to give the raw PWM duty, so if voltage_power_supply doesnāt match the actual power supply, then the actual output voltages wonāt match your commanded voltages either.
Indeed surprising I havenāt heard of anyone else having trouble with it. Although I doubt itās been your primary problem since itās unlikely the interruptions would be perfectly synchronized to your wave frequency to create the same wave shape every cycle.
things are turning interestingā¦
so first, I replay my last test .. : for your convinience I added the power input voltage in BLUE
as one can see, power voltage is 20V
now, as required , I added the following :
motor.voltage_limit=1;
and ⦠tada!
finally ⦠a nice sinusā¦
ok done! we got it!
letās back on the culprit⦠I uncommented the following :
motor.monitor(); <= sinewavekiller!
and guess whatā¦
so⦠for my personnal understandingā¦
-I shouldnāt use āxxx.monitorā method anymore
-it is unclear to me the difference between :
driver.voltage_limit = 10;
and
motor.voltage_limit=1;
![]()
I think, I figured out my answer by my own.
driver.voltage_limit = 10;
allow PWM max duty cycle to stop at around 50% in my case, because
driver.voltage_power_supply = 20;
and
motor.voltage_limit=1;
set the max PWM seen for one phase vs gnd , here 1V meaning 2V peak to peak
right?
I pushed a little bit further my invesgations :
when I set the motor.target value much higher , the sin wave starts to became āsquareā
it is probably because of the µC load is far too high according its possibilities.right?
Please take a look at: Field Oriented Control | Arduino-FOC
It explains the relationship between motor voltage limit, driver voltage limit and power supply voltage.
Regarding the monitoring, printing too much from the main loop causes problems, this is known. Thatās why the downsample for the monitoring is set to 100 by default, and you can increase it further as needed.
Itās also true as Deku said that printing to serial has different performance impacts depending on the MCU type and framework used. STM32F1 isnāt the fastest MCU type, and doesnāt have a FPU so your performance will be limited a bit by that. Still, normally we would not expect the monitoring (with downsample of 100 or more) to have such a big impact, so I wonder if there is something additional going on. What kind of position sensor are you using? Is the clock configuration for the board correct, so that the MCU is running at a fast clock speed?
And whatās the serial setup? What speed is it configured to, or is it using USB serial?
hi
actually, system is configured as velocity_openloop and torque control voltage, as required before.
monitoring is no more used (but when it was downsampling ration was set to 1:1000)
What kind of position sensor are you using?
nothing change on the board since the very begining of my course : hall sensor, legacy , into the wheel (Onewheel hardware , known in good condition)
Is the clock configuration for the board correct, so that the MCU is running at a fast clock speed
no idea sir!
Iām also surprised that the code does something āout of the boxā ⦠almost magic, I know that clock structure isnāt a small part , ⦠and I donāt have a clue to where it is set ā¦
And whatās the serial setup? What speed is it configured to, or is it using USB serial?
monitoring is no more used in main loop, but it is set to 115.2Kbds
thanks for your interest
F_CPU return 64Mhz
, the last time I used a µC, clock with 4Mhz full throttle ⦠a small Tiny85 from atmelā¦
so , it is now a kind of mysteryā¦.
void loop()
{
// digitalWrite(leds[0], HIGH);
//________normal section
// main FOC algorithm function
digitalWrite(leds[0], LOW);
digitalWrite(leds[0], HIGH);
motor.loopFOC(); //2µs
// Motion control function
motor.move(); //3µs
// display the currents
// motor.monitor(); //<= sinewavekiller! can take 2ms to complete!
//________end normal section
}
allow me to report some measurment , I used my scope and an output to catch execution time :
motor.loopFOC(); //2µs
and
motor.move(); //3µs
I also measure motor.monitor , and it takes sometimes 2ms .
so it reasonnable to say that µC isnāt so much loaded.
if I push from motor.target=5 to motor.target=15 , sinus wave loose its shape, and timings remain the sameā¦.
mystery againā¦..
Itās still not clear whatās happeningā¦
but 2us + 3us is only 5us or 200kHz - thatās much faster than your PWM speed. You should slow that down a bitā¦
what do you mean?
it is clear for me that my loop should be as fast as possible. The evidence here is that µc burden is very light.
cannot explain such a wave shape degradationā¦..