Comments (27)
LowPassFilter LPF_target(0.5); // the higher the longer new values need to take effect
void loop()
{
...
motor.move(LPF_target(target));
from split_hoverboard_simplefoc.
[Moving the message here]
Some signs were wrong in my case:
The extrapolation seems to work at constant speed at least now.
I need to do more tests this evening.
from split_hoverboard_simplefoc.
I did some tests, it seems the zero_electrical_angle was still off by 0.17 something (should be 1.92 instead of 2.09), it needed to be tweaked.
The way the sensor alignment procedure is done in simplefoc, it cannot be precise, it's meant for encoders mainly, so for hall sensors it has to be tweaked by hand. I believe you also played around with this parameter.
That's what I meant when I said the hoverboard firmware are already tweaked for hoverboard wheels, those aspects are probably hardcoded or baked into the firmware.
I might have to work on a better sensor alignment for hall sensor.
With bad alignment, FOC will probably be bad even if the current sensing is done right.
from split_hoverboard_simplefoc.
With my 2.0 board the sensor alignment procedure never did work at all. Only with the Gen1 stm32F103 did it succeed.
That is why i never understood how you obtained the 2.09.
Yes i did try to optimize your 2.09 but did not find a better value:
unsigned long iOptimize = 0;
float fOptimize = 0;
..
OUT2T(fOptimize*1000, motor.zero_electric_angle*1000)
fOptimize = -0.2 * (ABS( (float)((iOptimize++ + 20) % 80) - 40) - 20)/20;
motor.zero_electric_angle = 2.09 + fOptimize;
I might have to work on a better sensor alignment for hall sensor.
Might be good if you would be more prescise. We have used the word "alignment" in so many contexts by now, so i do not really understand what you mean with "better sensor alignment".
Only parameter is this zero_electric_angle
. So you want to write a better auto zero_electric_angle
detection ?
from split_hoverboard_simplefoc.
Sensor alignment is what happens here.
This will work well with an encoder, but with a hall sensor it just gives you a hint.
I need to try this as well.
from split_hoverboard_simplefoc.
the motor is blocking in the other direction if I am using 1.92.
I need to investigate more.
from split_hoverboard_simplefoc.
Ok I think I found the solution, and I have learned more, I summarized it all here
I am curious how Eferu compares with those number but I wouldn't be able to check before this weekend.
Eferu doesn't have such compensation (or I couldn't find it in the model), probably it's optimized only for some of the speed range.
from split_hoverboard_simplefoc.
Nice. I do not really understand a lot of your post over there.
But i am working with my Arduino-FOC that i forkerd from your Arduino-FOC.
So if you publish your local code changes to your repo, i can sync my fork to test your work with my test setup :-)
(today i worked on a 20A 80V ESP32 OLED mppt charger..)
from split_hoverboard_simplefoc.
I updated the dev branch.
from split_hoverboard_simplefoc.
Now that is a bit confusing (for me). You seem to work on three different branches and the latest _configure6PWM is in main but smoothedSensor in another branch ?
from split_hoverboard_simplefoc.
I am talking about the dev branch of this repository:
It uses the dev-gd32 branch of my Arduino-foc fork, and the dev branch of my arduino-foc-drivers fork.
from split_hoverboard_simplefoc.
I did a pull request to simplefoc dev branch with the direction fix and they accepted it.
So I think the smoothing is complete.
I will work on improving the autodetect only after the current sensing.
from split_hoverboard_simplefoc.
Okay @Candas1 here my test comparison between EFeru and your firmware here on a Gen1 board:
driver.voltage_power_supply = 26; // 3.6 * BAT_CELLS; // power supply voltage [V]
motor.voltage_limit = driver.voltage_power_supply * 0.58; // should be half the power supply
STM32 Gen1 board:
bin target [rpm/V] [A]
smFOC T5+E -5.4 0.17
smFOC T-5+E +5.3 0.17
EFeru +390 -5.4 0.25
EFeru 390 +5.4 0.23
smFOC T15+E -11.4 0.31
smFOC T-15+E +11.1 0.30
EFeru +760 -11.3 0.38
EFeru -760 +11.3 0.37
smFOC T26 -13.9 0.68
smFOC T-26 +12.9 0.48
EFeru 1000 -14.6 0.50
EFeru -1000 +15.0 0.51
no SmoothingSensor:
smFOC T5+E0 -5.5 0.19
smFOC T-5+E0 +5.3 0.19
smFOC T15+E0 -11.8 0.49
smFOC T-15+E0 +11.1 0.38
This inital nasty "push" might be because some class variable is not initialized to 0..
To make the Commander class work nicely with the short uart cable of the gen1 board, it would be nice if you would update your config.h to
// Define to prevent recursive inclusion
#ifndef CONFIG_H
#define CONFIG_H
#if defined(PLATFORMIO)
#ifdef STM32F103RC
#define HOVER_GEN 1
#define HOVER_LAYOUT 0
// too late here, has to be a build flag #define SIMPLEFOC_PWM_LOWSIDE_ACTIVE_HIGH false
// call motor.initFOC() without parameters to auto align sensor and copy values from debug log
#define MOTOR_zero_electric_offset 4.19
#define MOTOR_sensor_direction Direction::CCW
// log debug output over master/slave uart
//#define DEBUG_UART Serial
HardwareSerial oSerialSteer(PB11, PB10); // short cable 5VT EFeru USART3 GPIO Configuration
#define DEBUG_UART oSerialSteer
#else
#define HOVER_GEN 2
#define HOVER_LAYOUT 0
// call motor.initFOC() without parameters to auto align sensor and copy values from debug log
#define MOTOR_zero_electric_offset 2.09
#define MOTOR_sensor_direction Direction::CCW
// SEGGER RTT Debug
#define DEBUG_STLINK rtt // Uncomment to enable DEBUG over stlink dongle
#endif
#else
// LAYOUT_x_y is used in defines.h
#define HOVER_GEN 2
#define HOVER_LAYOUT 0
// 2_0 // https://github.com/flo199213/Hoverboard-Firmware-Hack-Gen2
// 2_1 // https://github.com/krisstakos/Hoverboard-Firmware-Hack-Gen2.1
// 2_2 // 2023/05/11 only MASTER and TEST_SPEED: motor is spinning but needs a push to startup :-/
// 2_4 // NOT READY !!! https://github.com/RoboDurden/Hoverboard-Firmware-Hack-Gen2.x/issues/3
// 2_5 // NOT READY !!! https://github.com/RoboDurden/Hoverboard-Firmware-Hack-Gen2.x/issues/11
// 1_0 // old Gen 1 boards with two motors
// call motor.initFOC() without parameters to auto align sensor and copy values from debug log
#define MOTOR_zero_electric_offset 2.09
#define MOTOR_sensor_direction Direction::CCW
// SEGGER RTT Debug
#define DEBUG_STLINK rtt // Uncomment to enable DEBUG over stlink dongle
// log debug output over master/slave uart
//#define DEBUG_UART Serial2
#endif
#define BLDC_POLE_PAIRS 15 // all hoverboard motors have 15 pole pairs ?
#define BAT_CELLS 7 // battery number of cells. mostly 10 = 10s = 36V. Sometimes 7 = 7s = 25V
#ifdef DEBUG_UART
#define DEBUG_UART_BAUD 115200 // [-] Baud rate for HoverSerial (used to communicate with the hoverboard)
#endif
#define TIME_SEND 10000 // [ms] Sending time interval
#endif // CONFIG_H
https://github.com/Candas1/Split_Hoverboard_SimpleFOC/blob/dev/src/main.cpp#L88 would be changed to
Commander command = Commander(SERIALDEBUG);
The auto calibration did again not work for me.
I got this MOTOR_zero_electric_offset 4.19
from an older version of our code when the auto calibration did work.
By now i have the same identical bldc motors installed in the gen1 test setup and the gen2.0 setup.
Lower case comands were more suitable for me:
command.add('t', doTarget, "target voltage");
// add smoothing enable/disable command E (send E0 to use hall sensor alone, or E1 to use smoothing)
command.add('e', enableSmoothing, "enable smoothing");
command.add('p', doPhaseCorrection, "phase correction");
command.add('z', doZero, "zero electrical angle");
command.add('f', doLPF, "LPF");
I also added a low pass to target
:
fSpeed = 0.999 * fSpeed + 0.001 * target;
//GPIO_BOP(GPIOB) = (uint32_t)GPIO_PIN_7;
motor.move(fSpeed);
//GPIO_BC(GPIOB) = (uint32_t)GPIO_PIN_7;
maybe this line is missing your main.cpp:
driver.voltage_limit = motor.voltage_limit; // stupid bug to have two voltage_limit in different places
from split_hoverboard_simplefoc.
Thank you.
Great so SFOC is more efficient, but not as fast.
It could be the inductance value has to be tweaked on different motors. I am using one with 5 coil wires and 30mm magnets. I am thinking about buying a LCR meter to measure it.
I tried the low pass filter class from SFOC some time ago but couldn't get it to work for the target.
No driver and voltage limit are equal by default.
from split_hoverboard_simplefoc.
I don't think so:
void BLDCMotor::init() {
...
// sanity check for the voltage limit configuration
if(voltage_limit > driver->voltage_limit) voltage_limit = driver->voltage_limit;
motor::voltage_limit
can be smaller than driver::voltage_limit
But i do no longer want to think about that stupidity to have two different voltage_limit
and on top both (seemingly to me) being used at random in BLDCMotor.cpp :-(
from split_hoverboard_simplefoc.
from split_hoverboard_simplefoc.
If you uncommented the curent sense, maybe the current sense alignment is running
from split_hoverboard_simplefoc.
Your last update to Candas1/Arduino-FOC/tree/dev-gd32 was two weeks ago.
So i do not understand what you mean with "... maybe the current sense alignment is running"
from split_hoverboard_simplefoc.
I have tested the smoothed sensor with 25V sine (stm Gen1 board):
float fTarget = LPF_target(target) * (ABS((float)(((millis()-iLoopStart)/10 + 250) % 1000) - 500) - 250)/250;
motor.move(fTarget);
fAnglePred = fmod(smooth.angle_prev * 57.295779513082320876798154814105 + 360.0 , 360.0);
fAngleReal = fmod(sensor.angle_prev * 57.295779513082320876798154814105 + 360.0 , 360.0);
Looks like i need to also set an optimized phase correction for SmoothingSensor::update():
// Apply phase correction if needed
if (phase_correction != 0) {
if (_motor.shaft_velocity < -0) angle_prev -= _motor.sensor_direction * phase_correction / _motor.pole_pairs;
else if (_motor.shaft_velocity > 0) angle_prev += _motor.sensor_direction * phase_correction / _motor.pole_pairs;
}
I am not too happy with this more general SmoothingSensor approach that can wrap any kind of rotation-position sensor as it can not make use of the interrupt driven HallSensor method HallSensor::updateState()
.
Instead it must rely on the Sensor:.update() function which is called in motor.loopFOC()
far more often (every single blue dot in the curve of fAnglePred
) than HallSensor::updateState()
(the coarse 4° steps of the grey curve fAngleReal
).
And SmoothingSensor does not implement its own lowpass but cleverly uses _motor.shaft_velocity
which has a lowpass:
float FOCMotor::shaftVelocity() {
// if no sensor linked return previous value ( for open loop )
if(!sensor) return shaft_velocity;
return sensor_direction*LPF_velocity(sensor->getVelocity());
}
This method is called in void BLDCMotor::move(float new_target)
and therefore motor.move(target)
has to be called at the same rate as motor.loopFOC()
.
I think this is NOT intuitive as people might want to call motor.move
only a few times per second to update a new target speed.
So yes, SmoothingSensor is working but all it basically does is adding a low pass to the angle and does a linear prediction
float dt = (_micros() - angle_prev_ts) * 1e-6f;
angle_prev += _motor.sensor_direction * _constrain(_motor.shaft_velocity * dt, -_PI_3 / _motor.pole_pairs, _PI_3 / _motor.pole_pairs);
Implement that "two lines" directly into HallSensor might be the better way...
from split_hoverboard_simplefoc.
SmoothingSensor.h
// For hall sensors, the predicted angle is always 0 to 60 electrical degrees ahead of where it would be without
// smoothing, so offset it backward by 30 degrees (set this to -PI_6) to get the average in phase with the rotor
float phase_correction = 0;
Setting it to +0.1 already had a bad effect.
Setting it to -0.52 = -Pi/6 was okay but does not really help:
from split_hoverboard_simplefoc.
here the downside of a low pass: it takes some time the direction change is noticed:
from split_hoverboard_simplefoc.
I already discussed with the contributor, I told him it's not optimal for hall sensors. But that's the best solution we have now and it works most of the time.
EFeru would stop predicting at slow speed or direction change, this is easy to do.
from split_hoverboard_simplefoc.
I guess i will spend half a day to test my direct HallSensor impelementation against these SmoothedSensor results here :-)
from split_hoverboard_simplefoc.
You could have checked already weeks ago.
Feel free to talk to him. I don't want to be a proxy between you and him.
from split_hoverboard_simplefoc.
Again, i do not want to pose problems when i can not offer solutions.
And i already figured out that linear prediction with a speed average is sufficient.
The inaccuracies i showed in the pics above are only at direction changes, so low speed an we do not really have to care for.
It is possible to give SmoothingSensor.h
its own speed low pass
float shaft_velocity;//!< current motor velocity
LowPassFilter LPF_velocity{DEF_VEL_FILTER_Tf};//!< parameter determining the velocity Low pass filter configuration
but as the speed will not change when motor.move()
is not called, it is okay to use the lowpass filtered motor.shaft_velocity
which gets updated by motor.move()
.
And when i only call motor.move
at 10 Hz and some heave torque on the motor affects the shaft_velocity we have a lowpass anyway and do not see that when smoothing.
So everything is okay with SmoothingSensor :-)
from split_hoverboard_simplefoc.
OK then we are aligned.
I know it's not a perfect solution but it's good enough for now.
When all works we can check what is worth improving.
from split_hoverboard_simplefoc.
I think it is already perfect for us.
In the beginning i thought that a higher grade polynomial would better predict future speed changes like in my screenshots..
(That is why i did not want to wait for SmoothingSensor...)
But this is only needed at very slow speeds and we do not need to care for that.
At normal speed when noise and efficiency is important, the refresh rate is so high that a linear prediction is sufficient.
(That is why i stopped with my HallSensor-prediction.)
Now seeing that SmoothedSensor is more silent than my linear prediction, i happily close that chapter.
I guess when you have finished your channel3 timer0 adc, you have successfully ported SFOC to GD32F130.
I would still like to have a callback when adc has finished to trigger motor.loopFOC() every second call :-)
from split_hoverboard_simplefoc.
Related Issues (10)
- please join and help us :-) HOT 49
- running simpleFOC from an interrupt and not the main loop() HOT 14
- I2C interfering with SimpleFOC ? HOT 10
- Improve memory footprint for C6 builds HOT 13
- Project dependency on https://github.com/Candas1/Arduino-FOC.git requires manual process to update HOT 13
- GD32 timer initialization is not working properly HOT 88
- motor does not reach max speed like old Gen2.x binary HOT 84
- adding LowsideCurrentSense ... HOT 160
- adding Gen1 enviroment (STM32F103RC) .. HOT 8
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from split_hoverboard_simplefoc.