AN8 is the battery current. When I wrote Ibat / duty it's really a divide operation, duty being the PWM's duty cycle but, as you pointed out, this is FOC and the current waveform is different from the "flat phase current" of non FOC.
i16_temp = (((int16_t) ui16_ADC_iq_current_filtered) - 511) * ADC_PHASE_B_CURRENT_FACTOR_MA;
i16_temp1 = (((int16_t) ui16_ADC_id_current_filtered) - 511) * ADC_PHASE_B_CURRENT_FACTOR_MA;
printf("%d, %d, %d\n", ui16_motor_speed_erps, i16_temp, i16_temp1);
I wanted to look at all the bits of motor control, including seeing the oscilloscope signals. Next I will look at your speed controller before implement anything for the troque-speed throttle.stancecoke said:I've just updated the TORQUESENSOR_EXPERIMENTING branch with the 10 bit resolution for battery current (ADC8)
The calibration is deziAmps = 1 * ADC8 - 312 for 10bit resolution.
But I think we should stop working in parallel now. I don't know how to merge the best parts of each branch to master....
casainho said:So, I looked with oscilloscope to AN8 and seems to me that follows the shape of phase B current, but with much more noise!!
casainho said:stancecoke, can you please test with your motor, power supply and load??
Yes because I put it very high, please look at main.h. That value should be to protect the controller and the torque controller should use Id current, at least is how I see it.stancecoke said:casainho said:stancecoke, can you please test with your motor, power supply and load??
I've tested the recent SVM7 branch (I don't know how to load an earlier commit to eclipse :? )
The motor runs fine, but current limitation does not work....
#define ADC_MOTOR_TOTAL_CURRENT_ZERO_AMPS 81 // 1.59V; 325 (10bits) = 81 (8bits)
#define ADC_MOTOR_TOTAL_CURRENT_MAX 32 // 32 (8bits) ~ 2 Amps
#define ADC_MOTOR_TOTAL_CURRENT_MAX_POSITIVE 95 // +2A
#define ADC_MOTOR_TOTAL_CURRENT_MIN_NEGATIVE 76//76 // -2A
I am sorry, next I need to explain the changes you need to do/prepare so you can use. The values I used were:stancecoke said:so again: It would be nice, if you would put some more comments to your code.
Of course I had a look at the main.h, but my interpretation was that the current limit is set to 2 amps :? .
if (ui8_motor_state == MOTOR_STATE_RUNNING_INTERPOLATION_360_DEGREES)
{
adc_select_channel (ADC1_CHANNEL_PHASE_CURRENT_B);
ui16_ADC_id_current = adc_read ();
if (ui16_ADC_id_current > 511)
{
ui32_ADC_id_current_sum += ui16_ADC_id_current;
ui16_ADC_id_current_sum_counter++;
}
}
Thanks, I will remember this.stancecoke said:What about the idea to read in the adc value into an array each pwm cycle and do the evaluation of the array in the slow main loop. I did this already in one commit of the old feature_torque_sensor branch,
This worked for me.
void hall_sensors_read_and_action (void)
{
(...)
switch (hall_sensors)
{
case 3:
// read here the phase B current: FOC Iq current
adc_select_channel (ADC1_CHANNEL_PHASE_CURRENT_B);
ui8_ADC_iq_current = ui8_adc_read ();
(...)
break;
case 1:
if (ui16_motor_speed_erps > 7)
{
if (ui8_ADC_iq_current > 127)
{
ui8_position_correction_value++;
}
else if (ui8_ADC_iq_current < 125)
{
ui8_position_correction_value--;
}
}
(...)
break;
ui16_ADC_iq_current_accumulated -= ui16_ADC_iq_current_accumulated >> 2;
ui16_ADC_iq_current_accumulated += ui8_ADC_iq_current;
ui8_ADC_iq_current_filtered = ui16_ADC_iq_current_accumulated >> 2;
casainho said:have one big question: which signal use to find current motor torque?? so we can use it to finally implement the throttle using mode "torque + speed"!!
I can try read Id from the very low resolution FOC but looking at oscilloscope I can see it will be very noise, because the phase B current signal is not a perfect sinewave (always changing) -- but on the FOC algorithm, the Id is the torque!!
Thank you to point this out. I am a fan of David Wilson videos from TI!!kiwifiat said:casainho said:have one big question: which signal use to find current motor torque?? so we can use it to finally implement the throttle using mode "torque + speed"!!
I can try read Id from the very low resolution FOC but looking at oscilloscope I can see it will be very noise, because the phase B current signal is not a perfect sinewave (always changing) -- but on the FOC algorithm, the Id is the torque!!
Id is not the torque producing vector in FOC, you want Id to be zero, unless you want field weakening or are controlling an internal magnet motor, and Iq is the torque producing vector that you need to control. Take a look at this excellent Texas Instruments video on FOC: https://www.youtube.com/watch?v=cdiZUszYLiA
For the torque/current control you tested, I used ADC/battery current signal and did the control every PWM duty_cycle but still there are some oscillations on the motor speed!! I would say that a slower control loop like you propose would increase the oscillations.stancecoke said:I testet your commit 894eb52. The current limitation worked, but caused much noise, I agree, we have to improve the control loop. iq (torque) measurement from phaseBcurrent did not work.
I still don't understand, why you want to read in the "peripheral" signals so often. I think for torque (battery current from ADC8), Battery Voltage and Throttle it is absolutely sufficient to read only in the slow main loop. I think the difference between iq (taken from phaseB current) and the low pass filtered current on ADC8 will be just academic... (peak value vs. average value).
https://e2e.ti.com/blogs_/b/motordrivecontrol/archive/2011/12/20/the-ten-commandments-of-digital-control-part-28. Sample often.
Unlike an analog control system, a digital controller only gets discrete moments in time to observe and respond to the system’s behavior. This can reduce system performance if your sampling frequency is too low. Imagine driving your car while texting, and you only look up once every 10 seconds to sample your surroundings! The same effect can happen with your motor control processor. If it is too busy doing other tasks, and not looking at your motor feedback signals frequently enough, your motor will crash! For position and velocity loops, the minimum sampling frequency is dictated by the mechanical poles of your system. It is common to find position and velocity loops running at sampling frequencies of around 2-5 KHz. However, most motor control designs also include current loops. The electrical poles are much higher than the mechanical poles, so sampling frequencies for the current loops are typically between 10-20 KHz. For low inductance motors, this figure can be even higher!
ui8_temp = ui8_adc_read_phase_B_current ();
if (ui8_temp > 127)
{
ui8_ADC_id_current = (ui8_ADC_id_current >> 1) + (ui8_temp >> 1);
}
ui16_ADC_id_current_accumulated -= ui16_ADC_id_current_accumulated >> 4;
ui16_ADC_id_current_accumulated += ui8_temp1;
ui8_ADC_id_current_filtered = ui16_ADC_id_current_accumulated >> 4;
printf("%d, %d, %d\n", ui16_motor_speed_erps, ui8_temp1, ui8_ADC_id_current_filtered);
I think the oscillation can be avoided with less proportional part and more integral part of a PI-control.casainho said:I would say that a slower control loop like you propose would increase the oscillations.
For FOC of course it makes sense to do the control in the fast loop. The fast loop should concentrate on proper driving the motor phases. Everything else should be done in a slower loop. Therefore I wrote "peripheral signals".casainho said:For instance, the control loop for Id current/FOC was done before on the slow main loop and after going to the PWM cycle loop, seems to me the motor/higher eRPM increased without seeing short-circuit signal on the lab power supply.
I went on a different path (controlling the motor current every PWM cycle) and tested the current control from battery (which I prefer to call motor current). The results are ok, seems to me. Next I hope to add speed controller that would superimpose to this current controller, when the load is very low. But this are all almost experiences, for instance, the startup almost always fail now...stancecoke said:For FOC of course it makes sense to do the control in the fast loop. The fast loop should concentrate on proper driving the motor phases. Everything else should be done in a slower loop. Therefore I wrote "peripheral signals".casainho said:For instance, the control loop for Id current/FOC was done before on the slow main loop and after going to the PWM cycle loop, seems to me the motor/higher eRPM increased without seeing short-circuit signal on the lab power supply.
I suggest three timings:
1. fast loop for PWM control
2. slow loop (about 50 Hz) for control of current/torque or speed
3. very slow loop (about 10 Hz) for communication (uart for debugging or display comunication)
Yes and it does not work!! Even the startup is almost always failing... the FOC does not work with stopped motor, just 6 steps... I need to play and think about all this.Njay said:Have you already tried sudden full throttle with a blocked rotor?
Ok, I saw your code for the speed controller, PAS, etc. It seems ok to me and modular. I see it uses speed from the external sensor and I wonder if it can be avoided for the correct motor function, as you know the motor works on original firmware without that speed sensor.stancecoke said:I think the oscillation can be avoided with less proportional part and more integral part of a PI-control.casainho said:I would say that a slower control loop like you propose would increase the oscillations.
For FOC of course it makes sense to do the control in the fast loop. The fast loop should concentrate on proper driving the motor phases. Everything else should be done in a slower loop. Therefore I wrote "peripheral signals".casainho said:For instance, the control loop for Id current/FOC was done before on the slow main loop and after going to the PWM cycle loop, seems to me the motor/higher eRPM increased without seeing short-circuit signal on the lab power supply.
I suggest three timings:
1. fast loop for PWM control
2. slow loop (about 50 Hz) for control of current/torque or speed
3. very slow loop (about 10 Hz) for communication (uart for debugging or display comunication)
This may work with a direct drive, but with a geared motor with a freewheel, you get no speedsignal if motor is not running while your bike is rolling. Serveral geared motors have an "extern" speedsensor internally already (white wire of the hall-sensor connector)casainho said:I see it uses speed from the external sensor and I wonder if it can be avoided for the correct motor function, as you know the motor works on original firmware without that speed sensor.
stancecoke said:I think I will take a break at this point until somebody implements the display communication....
I was looking for that file and it does not exist.stancecoke said:I've uploaded an .ods file to github.casainho said:I would like to have that files and images there