Casainho, forget this, looks like my laptop software installation has got corrupted, I've cocked-up somewhere.
No more time now, will re-install it later, sorry to bother you.
Casainho, forget this, looks like my laptop software installation has got corrupted, I've cocked-up somewhere.
There isn't yet. On my S06S, I did measured each 8 bits ADC step (20mV) to be equal to 0.5A: 5V / 256 = 0.02V.
The electric unicycles I did ride, had motors similar to Q11 and the same PWM control scheme our firmware uses, and they do break almost at to spto point -- it must, other Segways, hoverboards and electric unicycles could not exist.
You might want to read this reply by AmberWolf to my question about regen.
On my KT S12SN controller, there is an option, C13, that is described in the manual as:--complex and more common way is the controller repeatedly "shorts" the motor windings to create pulses of much higher voltage to be able to cause current flow even at motor speeds which would not otherwise be able to do it, so it can brake down to much lower speeds. Some are better at this than others, and some are more efficient at it (the less efficient ones make the motor and controller hotter from the waste heat than the more efficient ones).
Code: Select all
C13 ABS brakes of the controller and parameters of anti-charge control
C13 parameter definition table:
C13 Value ABS braking strength Energy recovery efficiency
0 None None
1 Class 1 braking strength Best energy recovery efficiency
2 Class 2 braking strength General energy recovery efficiency
3 Class 3 braking strength Weaker energy recovery efficiency
4 Class 4 braking strength Poor energy recovery efficiency
5 Class 5 braking strength Bad energy recovery efficiency
The recommended value of C13 is 1; other values need to be chosen with caution for
use.
Be sure to note: the higher is the braking intensity level, and the braking strength
will be greater, the greater damage to the motor shaft accordingly.
I do not understand this, I think you just need to know that there will be 4 of them. Or a mOhm value setting will be good also or just any value i can change by trial and error to get the amps I have set?casainho wrote: ↑Jan 12 2018 12:37pmThere isn't yet. On my S06S, I did measured each 8 bits ADC step (20mV) to be equal to 0.5A: 5V / 256 = 0.02V.
My S12S had 2 shunts but I cut one, so I can't now measure the real value for S12S.
Please measure for your controller and say the value, then I can put on the firmware as an option.
Therefore the torque is avaraged over one crank revolution in the torque simulation fork...
Ok, how can you do it? Try to run the motor at a fixed battery current, like on a bike training roller, like 3 amps (measure with an amperimeter). At the same time, measure the voltage on the STM8 pin 23: PE7 (ADC_AIN8) | motor_total_current_filtered. Repeat for other current values, more samples of the measures, the better.
It runs forever when duty_cycle increases but never decreases again. I got that when this condition on motor.c code runs:honya96 wrote: ↑Jan 12 2018 6:03pmOn the testbike I am still having problems with the zero current. Once the motor starts it runs forever. I think some offset of the zero value will help here also but now for me its easier to do hardware repair of shunt and see if it helps. I will add brake lever and try a little ride tomorow![]()
Code: Select all
// verify if there is regen current > 0 (if there is happening regen) and
// if battery voltage is over or equal to absolute battery max voltage, and if so
// reduce regen current
else if ((ui8_adc_motor_total_current < ui8_motor_total_current_offset) &&
(UI8_ADC_BATTERY_VOLTAGE >= ((uint8_t) ADC_BATTERY_VOLTAGE_MAX)))
{
if (ui8_duty_cycle < 255)
{
ui8_duty_cycle++;
}
}
I just added a small offset at github. You can try, with my testbench it works.
What do you mean with "repair"?
Thank you, will try. With repair I mean get exactly to the original resistance, maybe just desolder and put new one. It was covered with solder to get from 20 to 25A on original firmware and then recovered back to like 20.5 maybe but as I see now here its a problem. But the offset will come in handy for more people I believestancecoke wrote: ↑Jan 13 2018 4:42amI just added a small offset at github. You can try, with my testbench it works.
What do you mean with "repair"?
regards
stancecoke
So If I understand, it will not be only an offset, maube an offset + diferent ADC step... -- and If so, I think will be hard for people, for instance, let's see how can you deal with that.
Thats no problem, as the firmware reads in the zero current value at every start up of the system. The problem is, that the delta between setpoint and actual value of battery current has to be quite big to make the i16_output value bigger than 1 respectivly smaller than -1.
Code: Select all
i16_error = ((int16_t) ui16_target_current_10b) - i16_motor_current;
i16_output = i16_error * MOTOR_CURRENT_CONTROLLER_KP;
// limit max output value
if (i16_output > MOTOR_CURRENT_CONTROLLER_OUTPUT_MAX) i16_output = MOTOR_CURRENT_CONTROLLER_OUTPUT_MAX;
else if (i16_output < (-MOTOR_CURRENT_CONTROLLER_OUTPUT_MAX)) i16_output = -MOTOR_CURRENT_CONTROLLER_OUTPUT_MAX;
i16_output >>= 5; // divide to 64, avoid using floats
stancecoke, I remember when I did that, I tried hard to do a code not using floats as it is very slow... but, maybe we need that code.stancecoke wrote: ↑Jan 13 2018 6:44amThats no problem, as the firmware reads in the zero current value at every start up of the system. The problem is, that the delta between setpoint and actual value of battery current has to be quite big to make the i16_output value bigger than 1 respectivly smaller than -1.
As there is no "classical" integral part with floating point arithmetic in the control loop, the delta can't be controlled completely by summig up the error by the time.Code: Select all
i16_error = ((int16_t) ui16_target_current_10b) - i16_motor_current; i16_output = i16_error * MOTOR_CURRENT_CONTROLLER_KP; // limit max output value if (i16_output > MOTOR_CURRENT_CONTROLLER_OUTPUT_MAX) i16_output = MOTOR_CURRENT_CONTROLLER_OUTPUT_MAX; else if (i16_output < (-MOTOR_CURRENT_CONTROLLER_OUTPUT_MAX)) i16_output = -MOTOR_CURRENT_CONTROLLER_OUTPUT_MAX; i16_output >>= 5; // divide to 64, avoid using floats i16_output = ui8_duty_cycle + i16_output;
Setting the zero current value to a slightly negative value is just a trick to make the delta bigger.
I don't know, if we can do a "real" PI-Control like in the torque-simulation fork in the fast loop, or if the floating point operation is to slow...
The user won't have to tune the PI coefficients. I think we will find a setting that works for most Motor/Battery/Controller combinations.casainho wrote: ↑Jan 13 2018 7:17amI wasn't motivated to do something complex, because if that will be a PI controller and will need user to tune the coefficients... more complexity while the original don't have that need for user tune!! I think we should simplify in a way to have no more options for user to tune, like the original firmware.
I think you need mainly to play with MOTOR_ROTOR_OFFSET_ANGLE.honya96 wrote: ↑Jan 13 2018 1:18pmGuys I think my testbike motor fails to switch to FOC, when motor start interpolatiom 60 degrees set to 200 it runs up to high speed and then starts coughing when set 40 it starts sooner. Is it related with only FOC ID angle or also rotor offset? This motor needed the C2 parameter set at 5 with stock fw.
Edit: Thanks stancecoke, motor stopping is improved.
FOC_READ_ID_CURRENT_ANGLE_ADJUST can't take negative values, only from 0 up to 255. 127 is considered the "zero" value, and less than 127 are negative values...
How did you measured to verify it is about 30% high? -- if we agree, I can just reduce that 25% or 30%, etc.
Code: Select all
void calc_motor_current_filtered (void)
{
// low pass filter the current readed value, to avoid possible fast spikes/noise
ui16_adc_motor_current_accumulated_10b -= ui16_adc_motor_current_accumulated_10b >> 2;
ui16_adc_motor_current_accumulated_10b += ui16_adc_read_motor_total_current_10b ();
ui16_adc_motor_current_filtered_10b = ui16_adc_motor_current_accumulated_10b >> 2;
i8_motor_current_filtered_10b = ui16_adc_motor_current_filtered_10b - ui16_motor_total_current_offset_10b;
}
I just looked at the code and I found I could do some variable type optimizations -- can you please test?
I have no idea.geofft wrote: ↑Jan 13 2018 11:57amEventually found that deleting the entire firmware folder on the laptop (BMSBattery_S.....) then re-installing a new copy restored normal operation. This worked every time, so it seems that when LVC was triggered something was being flagged in the firmware folder to lock it. Any ideas?
All just details really, have to say the bike rode really well....![]()
My estimate here is not scientific, the power maximum the motor draws (indicated on display) with the stock firmware is 800w, but the new firmware is showing 1150w. I can do some better tests with an ammeter in the battery supply if you prefer..?
I'm beginning to think that the battery state-of-charge voltage figure (as reported from controller to display) is an imprecise number which varies with different controllers. This is maybe why the LCD3 provides for a large range of adjustment via the P5 parameter? So maybe we already have the solution by adjusting the voltage figures in the main.h lookup table. This works well enough for me, but will checkout your changes and let you know.I just looked at the code and I found I could do some variable type optimizations -- can you please test?
I must say I tested by looking at my display and changing the lab power supply, and seems ti works well but I never verified in details.
I always use this table, seems to give a very accurate state-of-charge indication.Can you please write the SOC table, for what would be the correct values? And provide a link your references??
That would be great, if you can confirm with an external meter.
I just updated the table on main.h but I also had to update the code that calc the number of bars:
Code: Select all
// calc battery pack state of charge (SOC)
ui16_battery_volts = ((uint16_t) motor_get_ADC_battery_voltage_filtered ()) * ((uint16_t) ADC_BATTERY_VOLTAGE_K);
if (ui16_battery_volts > ((uint16_t) BATTERY_PACK_VOLTS_80)) { ui8_battery_soc = 16; } // 4 bars | full
else if (ui16_battery_volts > ((uint16_t) BATTERY_PACK_VOLTS_60)) { ui8_battery_soc = 12; } // 3 bars
else if (ui16_battery_volts > ((uint16_t) BATTERY_PACK_VOLTS_40)) { ui8_battery_soc = 8; } // 2 bars
else if (ui16_battery_volts > ((uint16_t) BATTERY_PACK_VOLTS_20)) { ui8_battery_soc = 4; } // 1 bar
else { ui8_battery_soc = 3; } // empty