i found an ever better fix:
Code: Select all
clean:
@echo "Cleaning files..."
@clean.bat
-rm -f *.asm
-rm -f *.rel
-rm -f *.lk
-rm -f *.lst
-rm -f *.rst
-rm -f *.sym
-rm -f *.cdb
-rm -f *.map
-rm -f *.elf
-rm -f *.adb
@echo "Done."
Code: Select all
clean:
@echo "Cleaning files..."
@clean.bat
-rm -f *.asm
-rm -f *.rel
-rm -f *.lk
-rm -f *.lst
-rm -f *.rst
-rm -f *.sym
-rm -f *.cdb
-rm -f *.map
-rm -f *.elf
-rm -f *.adb
@echo "Done."
We are not controlling the max value of the phase current. The phase current is only used for doing the simplyfied FOC.
Code: Select all
if (ui16_motor_speed_erps > MOTOR_ROTOR_ERPS_START_INTERPOLATION_60_DEGREES)
{
// read here the phase B current: FOC Id current
ui8_adc_id_current = UI8_ADC_PHASE_B_CURRENT;
if (ui8_adc_id_current > 127) { ui8_angle_correction++; }
else if (ui8_adc_id_current < 125) { ui8_angle_correction--; }
}
Yes, I think my battery is that one 48v13Ah, that I bought from BMSBattery.honya96 wrote: ↑Feb 12 2018 6:39pm@Casainho - Can you share your 48V battery specs?
I wonder if you are able to test at 40A with your direct motor, so you can tune the firmware for higher powers. I am still not confident to test it..
I believe the phase current controll at zero/near zero speed is not ok yet.
Edit: 48v13Ah? Probably 13s6p 2.2Ah 10A LG cells so its ok for quite long 60A bursts if you bypass the bms.
Well I think original firmware does limit it or atleast cuts when over limit. Will do some tests...stancecoke wrote: ↑Feb 13 2018 11:11amWe are not controlling the max value of the phase current. The phase current is only used for doing the simplyfied FOC.
Master branch also cuts if you block the motor for some seconds. The current is ALWAYS being limited to max configured current!!honya96 wrote: ↑Feb 13 2018 2:58pmWell I think original firmware does limit it or atleast cuts when over limit. Will do some tests...stancecoke wrote: ↑Feb 13 2018 11:11amWe are not controlling the max value of the phase current. The phase current is only used for doing the simplyfied FOC.
I think that it will be needed, or if not possible, a ramp-up of max battery current linear with erps up to like 20 should do the job.
Problem is even when casainho has 12fet with 1000w direct hub, it can ask for too much phase amps from standstill and blow the mosfets.
I dont understand how can you not be motivated to run 2kw ~65kph when your bike can handle it
Unfortunately I am not riding bicycle lately and just using car.
On our firmware, currently, it is used only for FOC (as Stancecoke told before and did show the only piece of code that uses phase B current sensor signal, that only looks for 2.5V (127 value) and increase or decrease ui8_angle_correction:
Code: Select all
// read here the phase B current: FOC Id current
ui8_adc_id_current = UI8_ADC_PHASE_B_CURRENT;
if (ui8_adc_id_current > 127) { ui8_angle_correction++; }
else if (ui8_adc_id_current < 125) { ui8_angle_correction--; }
No point in talk about phase current to protect the motor as the hardware only has 1 phase current sensor, while we would need to have the 3 phase currents -- so we are using instead the motor current(the current that flows from the battery).
I think I got it, more or less as you suggested:stancecoke wrote: ↑Feb 10 2018 11:30amRead the throttle value, the direct torque-signal and the human power (human power averaged over one, or at least a half crank revolution) and give the highest value to the motor. With this, the support will start from zero speed, it will oszillate at startup, but it will be smooth from the point, where the human power value is higher than the simple torque value, the thumb throttle as highest priority and overrides the other values...
Code: Select all
void ebike_throttle_type_torque_sensor (void)
{
...
// divide the torque sensor throttle value by 4 as it is very sensitive and multiply by assist level
f_temp = (float) ((ui8_throttle_value_filtered >> 2) * lcd_configuration_variables.ui8_assist_level);
}
Code: Select all
// set PWM duty_cycle target value only if we are not braking
if (!motor_controller_state_is_set (MOTOR_CONTROLLER_STATE_BRAKE))
{
// now use the lowest value from the PI controllers outputs
motor_set_pwm_duty_cycle_target (ui8_min (
motor_current_pi_controller_state.ui8_controller_output_value,
wheel_speed_pi_controller_state.ui8_controller_output_value));
}
else
{
// keep reseting PI controllers so the I term will not increase while we are braking!
pi_controller_reset (&motor_current_pi_controller_state);
pi_controller_reset (&wheel_speed_pi_controller_state);
}
It is inline what I measured some time ago: https://opensourceebikefirmware.bitbuck ... ensor.htmlstancecoke wrote: ↑Feb 14 2018 12:39pmHmm, I don't understand your latest code in detail...
I can't see the typical sinusoidal shape in the torque-curve?!
I can't imagine being less scatter using the average. Do you have a link were I can read more about it for a similar situation?stancecoke wrote: ↑Feb 14 2018 12:39pmWhy don't you average the torque signal over a crank revolution? This would avoid the scatter.
I am sure others ways can work. For instance, keep resetting the target value instead of resetting the I term.stancecoke wrote: ↑Feb 14 2018 12:39pmI think you are doing many things much more complicated than necessary, e.g. a reset of the integral part of the controller should not be done to avoid sudden changes in the setpoint which could cause the motor to stutter. The control loop will decrease the integral part fast enough automatically, if you choose proper parameters ...
I had a closer look to you code now. As far as I understand, you are averaging the torque-signal over four AD-conversions, in the fixed frequency of the slow loop. So you have no reference to the pedal position.
Code: Select all
// low pass filter the torque sensor to smooth the signal
ui16_throttle_value_accumulated -= ui16_throttle_value_accumulated >> 2;
ui16_throttle_value_accumulated += ((uint16_t) ui8_throttle_value);
ui8_throttle_value_filtered = ui16_throttle_value_accumulated >> 2;
Code: Select all
ui16_TIM2_counter = TIM2_GetCounter ();
if ((ui16_TIM2_counter - ui16_motor_controller_counter) > 781) // every 100ms
{
ui16_motor_controller_counter = ui16_TIM2_counter;
motor_controller ();
ebike_app_controller ();
continue;
}
Code: Select all
#if defined(TORQUESENSOR) || defined(TORQUE_SIMULATION)
// Update cadence, torque and battery current after PAS interrupt occurrence
if (ui8_PAS_Flag == 1)
{
ui16_PAS=ui16_PAS_Counter; //save recent cadence
ui16_PAS_High=ui16_PAS_High_Counter;
...
ui8_PAS_Flag =0; //reset interrupt flag
ui8_temp = ui8_adc_read_throttle (); //read in recent torque value
ui16_torque[ui8_torque_index]= (uint8_t) map (ui8_temp , ADC_THROTTLE_MIN_VALUE, ADC_THROTTLE_MAX_VALUE, 0, SETPOINT_MAX_VALUE); //map throttle to limits
ui16_sum_torque = 0;
for(a = 0; a < NUMBER_OF_PAS_MAGS; a++) { // sum up array content
ui16_sum_torque+= ui16_torque[a];
}
ui8_torque_index++;
if (ui8_torque_index>NUMBER_OF_PAS_MAGS-1){ui8_torque_index=0;} //reset index counter
}
Seems you missed my new code -- you can see on the commits diffs:stancecoke wrote: ↑Feb 15 2018 8:16amI had a closer look to you code now. As far as I understand, you are averaging the torque-signal over four AD-conversions, in the fixed frequency of the slow loop. So you have no reference to the pedal position.
Code: Select all
if (ui8_pas_state != ui8_pas_state_old) // PAS signal did change
{
ui8_pas_state_old = ui8_pas_state;
(...)
ui8_torque_sensor_throttle_value = UI8_ADC_THROTTLE;
ui8_torque_sensor_pas_signal_change_counter++;
if (ui8_torque_sensor_pas_signal_change_counter > (PAS_NUMBER_MAGNETS << 1)) // ui8_pas_signal_change_counter = (PAS_NUMBER_MAGNETS*2) means 1 pedal rotation
{
ui8_torque_sensor_pas_signal_change_counter = 1; // this is the first cycle
ui8_torque_sensor_throttle_processed_value = ui8_torque_sensor_throttle_max_value; // store the max value on the output variable of this algorithm
ui8_torque_sensor_throttle_max_value = 0; // reset the max value
}
else
{
// store the max value
if (ui8_torque_sensor_throttle_value > ui8_torque_sensor_throttle_max_value)
{
ui8_torque_sensor_throttle_max_value = ui8_torque_sensor_throttle_value;
}
}
}
Code: Select all
void read_torque_sensor_throttle (void)
{
read_throttle (); // so we get regular processing of throttle signal
// if cadence is over 15 RPM, use the processed torque sensor value, otherwise, use ui8_throttle_value_filtered
if (ui8_pas_cadence_rpm <= 15)
{
ui8_throttle_value_filtered = ui8_throttle_value;
}
else
{
ui8_throttle_value_filtered = (uint8_t) (map (
ui8_torque_sensor_throttle_processed_value,
(uint8_t) ADC_THROTTLE_MIN_VALUE,
(uint8_t) ADC_THROTTLE_MAX_VALUE,
(uint8_t) THROTTLE_MIN_VALUE,
(uint8_t) THROTTLE_MAX_VALUE));
}
}
Code: Select all
ui8_throttle_value_filtered
Ah, yes, I didn't recognize the changes in the motor.c
Is the X4 pad used for somethings else with the BT-version?casainho wrote: ↑Feb 15 2018 8:34amI am using the S06S Bluetooth version and I think I will stick with that version, for later use with our mobile app. This means I connected the torque sensor signals to the thumb throttle connector and PAS and so I can't use in parallel a thumb throttle with this controller.
Go ahead an show the results on a similar graph as I don't believe will be a big difference.stancecoke wrote: ↑Feb 15 2018 9:09amAh, yes, I didn't recognize the changes in the motor.c
You will get less scatter with the averaged values, but of course it will work with the single maximum value of one crank revolution also. But you get a new torque value only once per revolution and not at every PAS event...
I don't know, I wish someone could see the hardware differencies...
OK, I'll do some logging of the raw ADC-values on a real ride, but this will take at least two weeks to prepare. I can try the "thumb-brake" with the BionX in "real life" then, too
About 1 month up to start spring season, so right on time (at least for me) to have the bicycles ready for family funstancecoke wrote: ↑Feb 15 2018 11:08amOK, I'll do some logging of the raw ADC-values on a real ride, but this will take at least two weeks to prepare. I can try the "thumb-brake" with the BionX in "real life" then, too![]()
I mean turning throttle to full position at standstill.
So you mean the S12S can't withstand his max current of 40A for a period of 2.5 seconds?
We can measure only twice per ERPs (at Id and -Id points on the image), but even like that didn't worked well when I tested:
Can you please make a graph with example values? (you can draw on paper and take a photo).honya96 wrote: ↑Feb 16 2018 7:10amOr the other way as I mentioned before, limiting battery current up to set erps should also do the job, maybe better.
Having "startup Amps" and "Max current eprs" values in java app will limit phase current and allow users to get higher battery amps without blowing the controller at startup.
Yes, actually not even 0.5 second with really fast motor, because 40A from battery can be 200A to motor. (=at mofets)
Not exactly, it has to be available when the wheel is spinning allready, and has to be limited when at speed and terrain slows your motor under the set speed, or something blocks your wheel.
Didn't know about that!! Now I recall Stancecoke and others telling that "motor current" on firmware is instead battery current but I always thought they were equal.
I think I got it. I hope to get back to this later.