Motor current controller
Fork of CURRENT_CONTROL by
CURRENT_CONTROL.cpp@19:24605ba48462, 2017-02-07 (annotated)
- Committer:
- benson516
- Date:
- Tue Feb 07 09:52:56 2017 +0000
- Revision:
- 19:24605ba48462
- Parent:
- 18:76383af914dc
- Child:
- 20:559db13dc85a
test succeed
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
adam_z | 0:955aa05c968a | 1 | #include "mbed.h" |
adam_z | 0:955aa05c968a | 2 | #include "CURRENT_CONTROL.h" |
adam_z | 0:955aa05c968a | 3 | |
benson516 | 16:6e3bcd373f9d | 4 | /* |
benson516 | 5:7ccd2fb7ce7e | 5 | //=====================LPF ====================// |
benson516 | 5:7ccd2fb7ce7e | 6 | LPF::LPF(float samplingTime, float cutOff_freq_Hz_in) |
benson516 | 5:7ccd2fb7ce7e | 7 | { |
benson516 | 5:7ccd2fb7ce7e | 8 | Ts = samplingTime; |
benson516 | 5:7ccd2fb7ce7e | 9 | cutOff_freq_Hz = cutOff_freq_Hz_in; |
benson516 | 5:7ccd2fb7ce7e | 10 | alpha_Ts = (2*3.1415926)*cutOff_freq_Hz*Ts; |
benson516 | 9:d8157fbfcd2a | 11 | One_alpha_Ts = 1.0 - alpha_Ts; |
benson516 | 7:6794cfba3564 | 12 | output = 0.0; |
benson516 | 12:085f35babe21 | 13 | |
benson516 | 7:6794cfba3564 | 14 | // |
benson516 | 12:085f35babe21 | 15 | Flag_Init = false; |
benson516 | 5:7ccd2fb7ce7e | 16 | } |
adam_z | 0:955aa05c968a | 17 | |
benson516 | 5:7ccd2fb7ce7e | 18 | float LPF::filter(float input) |
benson516 | 5:7ccd2fb7ce7e | 19 | { |
benson516 | 7:6794cfba3564 | 20 | // Initialization |
benson516 | 7:6794cfba3564 | 21 | if (!Flag_Init){ |
benson516 | 7:6794cfba3564 | 22 | reset(input); |
benson516 | 7:6794cfba3564 | 23 | Flag_Init = true; |
benson516 | 7:6794cfba3564 | 24 | return output; |
benson516 | 7:6794cfba3564 | 25 | } |
benson516 | 12:085f35babe21 | 26 | |
benson516 | 9:d8157fbfcd2a | 27 | // output = One_alpha_Ts*output + alpha_Ts*input; |
benson516 | 5:7ccd2fb7ce7e | 28 | output += alpha_Ts*(input - output); |
benson516 | 12:085f35babe21 | 29 | |
benson516 | 5:7ccd2fb7ce7e | 30 | return output; |
benson516 | 5:7ccd2fb7ce7e | 31 | } |
benson516 | 7:6794cfba3564 | 32 | void LPF::reset(float input) |
benson516 | 7:6794cfba3564 | 33 | { |
benson516 | 7:6794cfba3564 | 34 | // output = (1.0 - alpha_Ts)*output + alpha_Ts*input; |
benson516 | 7:6794cfba3564 | 35 | output = input; |
benson516 | 7:6794cfba3564 | 36 | return; |
benson516 | 7:6794cfba3564 | 37 | } |
benson516 | 16:6e3bcd373f9d | 38 | */ |
benson516 | 5:7ccd2fb7ce7e | 39 | |
benson516 | 5:7ccd2fb7ce7e | 40 | //================== CURRENT_CONTROL =================// |
adam_z | 1:c5973a56d474 | 41 | CURRENT_CONTROL::CURRENT_CONTROL(PinName curChannel, |
adam_z | 1:c5973a56d474 | 42 | PinName PwmChannel1, |
adam_z | 1:c5973a56d474 | 43 | PinName PwmChannel2, |
adam_z | 1:c5973a56d474 | 44 | PWMIndex pwmIndex, |
benson516 | 8:fd6fb3cb12ec | 45 | PinName QEI_A, |
benson516 | 8:fd6fb3cb12ec | 46 | PinName QEI_B, |
benson516 | 8:fd6fb3cb12ec | 47 | float pulsesPerRev, |
benson516 | 8:fd6fb3cb12ec | 48 | int arraysize, |
benson516 | 12:085f35babe21 | 49 | float samplingTime) : |
benson516 | 5:7ccd2fb7ce7e | 50 | currentAnalogIn(curChannel), |
adam_z | 0:955aa05c968a | 51 | MotorPlus(PwmChannel1), |
adam_z | 0:955aa05c968a | 52 | MotorMinus(PwmChannel2), |
benson516 | 8:fd6fb3cb12ec | 53 | wheelSpeed(QEI_A, QEI_B, NC, pulsesPerRev, arraysize, samplingTime, QEI::X4_ENCODING), //(pin1, pin2, pin3, pulsesPerRev, arraysize, sampletime, pulses) |
benson516 | 8:fd6fb3cb12ec | 54 | pid(0.0,0.0,0.0,samplingTime), |
benson516 | 19:24605ba48462 | 55 | lpf_current(samplingTime, 400.0), // 1.5915 Hz = 10 rad/s |
benson516 | 19:24605ba48462 | 56 | lpf_wheelSpeed(samplingTime, 200.0, 2) // 2nd-order LPF, fc = 200.0 Hz |
benson516 | 8:fd6fb3cb12ec | 57 | |
benson516 | 12:085f35babe21 | 58 | |
adam_z | 0:955aa05c968a | 59 | { |
adam_z | 1:c5973a56d474 | 60 | pwmIndex_ = pwmIndex; |
adam_z | 1:c5973a56d474 | 61 | |
adam_z | 0:955aa05c968a | 62 | Ts = samplingTime; |
benson516 | 12:085f35babe21 | 63 | |
adam_z | 0:955aa05c968a | 64 | //setup motor PWM parameters |
benson516 | 12:085f35babe21 | 65 | MotorPlus.period_us(50); //set the pwm period = 50 us, where the frequency = 20kHz |
benson516 | 8:fd6fb3cb12ec | 66 | // |
benson516 | 8:fd6fb3cb12ec | 67 | SetPWMDuty(0.5); |
benson516 | 12:085f35babe21 | 68 | |
benson516 | 15:d9ccd6c92a21 | 69 | //Current-input limit |
benson516 | 15:d9ccd6c92a21 | 70 | current_limit_H = 1.3; |
benson516 | 15:d9ccd6c92a21 | 71 | current_limit_L = -1.3; |
benson516 | 7:6794cfba3564 | 72 | // |
benson516 | 7:6794cfba3564 | 73 | Flag_Init = false; |
benson516 | 7:6794cfba3564 | 74 | Init_count = 0; |
benson516 | 7:6794cfba3564 | 75 | Accumulated_offset = 0.0; |
benson516 | 12:085f35babe21 | 76 | |
benson516 | 5:7ccd2fb7ce7e | 77 | // |
benson516 | 5:7ccd2fb7ce7e | 78 | currentOffset = 0.0; |
benson516 | 7:6794cfba3564 | 79 | // |
benson516 | 5:7ccd2fb7ce7e | 80 | delta_output = 0.0; |
benson516 | 8:fd6fb3cb12ec | 81 | curFeedBack = 0.0; |
benson516 | 8:fd6fb3cb12ec | 82 | curFeedBack_filter = 0.0; |
benson516 | 14:67fc256efeb7 | 83 | curCommand = 0.0; |
benson516 | 8:fd6fb3cb12ec | 84 | voltage_out = 0.0; |
benson516 | 12:085f35babe21 | 85 | |
benson516 | 12:085f35babe21 | 86 | // Set PID's parameters |
benson516 | 6:bae35ca64f10 | 87 | ///////////////////// |
benson516 | 8:fd6fb3cb12ec | 88 | pid.Kp = 0.0; |
benson516 | 8:fd6fb3cb12ec | 89 | pid.Ki = 0.0; |
benson516 | 8:fd6fb3cb12ec | 90 | pid.Kd = 0.0; |
benson516 | 8:fd6fb3cb12ec | 91 | pid.Ka = 0.0; // Gain for anti-windup // Ka = 0.0017 |
benson516 | 12:085f35babe21 | 92 | |
benson516 | 8:fd6fb3cb12ec | 93 | // Speed |
benson516 | 8:fd6fb3cb12ec | 94 | angularSpeed = 0.0; |
benson516 | 8:fd6fb3cb12ec | 95 | Flag_SpeedCal_Iterated = false; |
benson516 | 12:085f35babe21 | 96 | |
benson516 | 9:d8157fbfcd2a | 97 | // Reverse flage for each signal |
benson516 | 9:d8157fbfcd2a | 98 | reverse_current = false; |
benson516 | 9:d8157fbfcd2a | 99 | reverse_rotationalSpeed = false; |
benson516 | 9:d8157fbfcd2a | 100 | reverse_voltage = false; |
benson516 | 8:fd6fb3cb12ec | 101 | } |
benson516 | 8:fd6fb3cb12ec | 102 | // |
benson516 | 9:d8157fbfcd2a | 103 | void CURRENT_CONTROL::SetParams(float Analog2Cur_in, float angSpeed2BackEmf, float voltage2Duty_in) |
benson516 | 8:fd6fb3cb12ec | 104 | { |
benson516 | 9:d8157fbfcd2a | 105 | analog2Cur = Analog2Cur_in;//LTS25-NP current sensor working with STM32F446RE : 3.3*8/0.6 |
benson516 | 8:fd6fb3cb12ec | 106 | Ke = angSpeed2BackEmf; |
benson516 | 14:67fc256efeb7 | 107 | Kt = Ke; |
benson516 | 14:67fc256efeb7 | 108 | Kt_inv = 1/Kt; |
benson516 | 12:085f35babe21 | 109 | voltage2Duty = voltage2Duty_in; |
benson516 | 9:d8157fbfcd2a | 110 | } |
benson516 | 9:d8157fbfcd2a | 111 | void CURRENT_CONTROL::SetReversal(bool reverse_current_in, bool reverse_rotationalSpeed_in, bool reverse_voltage_in) |
benson516 | 9:d8157fbfcd2a | 112 | { |
benson516 | 9:d8157fbfcd2a | 113 | reverse_current = reverse_current_in; |
benson516 | 9:d8157fbfcd2a | 114 | reverse_rotationalSpeed = reverse_rotationalSpeed_in; |
benson516 | 9:d8157fbfcd2a | 115 | reverse_voltage = reverse_voltage_in; |
benson516 | 8:fd6fb3cb12ec | 116 | } |
benson516 | 8:fd6fb3cb12ec | 117 | // |
benson516 | 8:fd6fb3cb12ec | 118 | void CURRENT_CONTROL::SetGain(float Kp, float Ki, float Kd, float Ka) |
benson516 | 8:fd6fb3cb12ec | 119 | { |
benson516 | 12:085f35babe21 | 120 | // Set PID's parameters |
benson516 | 8:fd6fb3cb12ec | 121 | ///////////////////// |
benson516 | 6:bae35ca64f10 | 122 | pid.Kp = Kp; |
benson516 | 6:bae35ca64f10 | 123 | pid.Ki = Ki; |
benson516 | 6:bae35ca64f10 | 124 | pid.Kd = Kd; |
benson516 | 6:bae35ca64f10 | 125 | pid.Ka = Ka; // Gain for anti-windup // Ka = 0.0017 |
benson516 | 5:7ccd2fb7ce7e | 126 | } |
benson516 | 8:fd6fb3cb12ec | 127 | // |
benson516 | 15:d9ccd6c92a21 | 128 | void CURRENT_CONTROL::setInputLimits(float current_limit_H_in, float current_limit_L_in){ |
benson516 | 15:d9ccd6c92a21 | 129 | current_limit_H = current_limit_H_in; |
benson516 | 15:d9ccd6c92a21 | 130 | current_limit_L = current_limit_L_in; |
benson516 | 15:d9ccd6c92a21 | 131 | } |
benson516 | 15:d9ccd6c92a21 | 132 | // |
benson516 | 7:6794cfba3564 | 133 | void CURRENT_CONTROL::OffsetInit(void){ |
benson516 | 7:6794cfba3564 | 134 | if (Flag_Init) return; |
benson516 | 7:6794cfba3564 | 135 | // |
benson516 | 12:085f35babe21 | 136 | |
benson516 | 7:6794cfba3564 | 137 | Init_count++; |
benson516 | 9:d8157fbfcd2a | 138 | /* |
benson516 | 7:6794cfba3564 | 139 | Accumulated_offset += GetAnalogIn(); |
benson516 | 12:085f35babe21 | 140 | |
benson516 | 7:6794cfba3564 | 141 | if (Init_count >= 500){ // Fixed time |
benson516 | 8:fd6fb3cb12ec | 142 | currentOffset = Accumulated_offset / float(Init_count); |
benson516 | 7:6794cfba3564 | 143 | Flag_Init = true; |
benson516 | 7:6794cfba3564 | 144 | } |
benson516 | 9:d8157fbfcd2a | 145 | */ |
benson516 | 12:085f35babe21 | 146 | |
benson516 | 9:d8157fbfcd2a | 147 | // |
benson516 | 9:d8157fbfcd2a | 148 | /* |
benson516 | 9:d8157fbfcd2a | 149 | if (Init_count <= 10){ |
benson516 | 9:d8157fbfcd2a | 150 | Accumulated_offset = GetAnalogIn(); |
benson516 | 9:d8157fbfcd2a | 151 | }else{ |
benson516 | 9:d8157fbfcd2a | 152 | // Accumulated_offset += 0.0063*(GetAnalogIn() - Accumulated_offset); // fc = 1 Hz |
benson516 | 9:d8157fbfcd2a | 153 | Accumulated_offset = 0.9937*Accumulated_offset + 0.0063*GetAnalogIn(); // fc = 1 Hz |
benson516 | 9:d8157fbfcd2a | 154 | } |
benson516 | 12:085f35babe21 | 155 | |
benson516 | 9:d8157fbfcd2a | 156 | if (Init_count >= 300){ // Fixed time: 500 samples |
benson516 | 9:d8157fbfcd2a | 157 | currentOffset = Accumulated_offset; |
benson516 | 9:d8157fbfcd2a | 158 | Flag_Init = true; |
benson516 | 9:d8157fbfcd2a | 159 | } |
benson516 | 9:d8157fbfcd2a | 160 | */ |
benson516 | 12:085f35babe21 | 161 | |
benson516 | 12:085f35babe21 | 162 | |
benson516 | 9:d8157fbfcd2a | 163 | // |
benson516 | 9:d8157fbfcd2a | 164 | if (Init_count >= 10){ // Fixed time: 10 samples |
benson516 | 9:d8157fbfcd2a | 165 | currentOffset = GetAnalogIn(); |
benson516 | 9:d8157fbfcd2a | 166 | Flag_Init = true; |
benson516 | 9:d8157fbfcd2a | 167 | } |
benson516 | 12:085f35babe21 | 168 | |
benson516 | 12:085f35babe21 | 169 | |
benson516 | 7:6794cfba3564 | 170 | } |
benson516 | 8:fd6fb3cb12ec | 171 | |
benson516 | 15:d9ccd6c92a21 | 172 | // Without delta output |
benson516 | 15:d9ccd6c92a21 | 173 | float CURRENT_CONTROL::saturation(float input_value, const float &limit_H, const float &limit_L){ |
benson516 | 15:d9ccd6c92a21 | 174 | if( input_value > limit_H ){ |
benson516 | 15:d9ccd6c92a21 | 175 | input_value = limit_H; |
benson516 | 15:d9ccd6c92a21 | 176 | }else if( input_value < limit_L ){ |
benson516 | 15:d9ccd6c92a21 | 177 | input_value = limit_L; |
benson516 | 15:d9ccd6c92a21 | 178 | }else{ |
benson516 | 15:d9ccd6c92a21 | 179 | // Nothing |
benson516 | 15:d9ccd6c92a21 | 180 | } |
benson516 | 15:d9ccd6c92a21 | 181 | return input_value; |
benson516 | 15:d9ccd6c92a21 | 182 | } |
benson516 | 15:d9ccd6c92a21 | 183 | // With delta output |
benson516 | 5:7ccd2fb7ce7e | 184 | float CURRENT_CONTROL::saturation(float input_value, float &delta, const float &limit_H, const float &limit_L){ |
benson516 | 5:7ccd2fb7ce7e | 185 | if( input_value > limit_H ){ |
benson516 | 5:7ccd2fb7ce7e | 186 | delta = limit_H - input_value; |
benson516 | 5:7ccd2fb7ce7e | 187 | input_value = limit_H; |
benson516 | 12:085f35babe21 | 188 | }else if( input_value < limit_L ){ |
benson516 | 5:7ccd2fb7ce7e | 189 | delta = limit_L - input_value; |
benson516 | 12:085f35babe21 | 190 | input_value = limit_L; |
benson516 | 5:7ccd2fb7ce7e | 191 | }else{ |
benson516 | 5:7ccd2fb7ce7e | 192 | delta = 0.0; |
benson516 | 5:7ccd2fb7ce7e | 193 | } |
benson516 | 5:7ccd2fb7ce7e | 194 | return input_value; |
adam_z | 4:1a6ba05e7736 | 195 | } |
benson516 | 9:d8157fbfcd2a | 196 | // Speed_IterateOnce |
benson516 | 9:d8157fbfcd2a | 197 | //////////////////////////////// |
benson516 | 8:fd6fb3cb12ec | 198 | float CURRENT_CONTROL::Speed_IterateOnce(void){ |
benson516 | 8:fd6fb3cb12ec | 199 | // The flag "Flag_SpeedCal_Iterated" will be resetted at the end of function Control() |
benson516 | 12:085f35babe21 | 200 | if(Flag_SpeedCal_Iterated) return; |
benson516 | 12:085f35babe21 | 201 | |
benson516 | 8:fd6fb3cb12ec | 202 | // Speed |
benson516 | 8:fd6fb3cb12ec | 203 | wheelSpeed.Calculate(); |
benson516 | 12:085f35babe21 | 204 | |
benson516 | 9:d8157fbfcd2a | 205 | // |
benson516 | 9:d8157fbfcd2a | 206 | if (reverse_rotationalSpeed) |
benson516 | 9:d8157fbfcd2a | 207 | angularSpeed = -wheelSpeed.getAngularSpeed(); |
benson516 | 9:d8157fbfcd2a | 208 | else |
benson516 | 9:d8157fbfcd2a | 209 | angularSpeed = wheelSpeed.getAngularSpeed(); |
benson516 | 9:d8157fbfcd2a | 210 | // |
benson516 | 12:085f35babe21 | 211 | |
benson516 | 8:fd6fb3cb12ec | 212 | // Flag |
benson516 | 8:fd6fb3cb12ec | 213 | Flag_SpeedCal_Iterated = true; |
benson516 | 12:085f35babe21 | 214 | |
benson516 | 8:fd6fb3cb12ec | 215 | return angularSpeed; |
benson516 | 8:fd6fb3cb12ec | 216 | } |
benson516 | 8:fd6fb3cb12ec | 217 | float CURRENT_CONTROL::getAngularSpeed(void){ |
benson516 | 8:fd6fb3cb12ec | 218 | // return wheelSpeed.getAngularSpeed(); |
benson516 | 8:fd6fb3cb12ec | 219 | return angularSpeed; |
benson516 | 8:fd6fb3cb12ec | 220 | } |
benson516 | 8:fd6fb3cb12ec | 221 | float CURRENT_CONTROL::getAngularSpeed_deg_s(void){ |
benson516 | 12:085f35babe21 | 222 | |
benson516 | 9:d8157fbfcd2a | 223 | if (reverse_rotationalSpeed) |
benson516 | 9:d8157fbfcd2a | 224 | return -wheelSpeed.getAngularSpeed_deg_s(); |
benson516 | 9:d8157fbfcd2a | 225 | else |
benson516 | 9:d8157fbfcd2a | 226 | return wheelSpeed.getAngularSpeed_deg_s(); |
benson516 | 9:d8157fbfcd2a | 227 | // |
benson516 | 9:d8157fbfcd2a | 228 | // return wheelSpeed.getAngularSpeed_deg_s(); |
benson516 | 8:fd6fb3cb12ec | 229 | } |
benson516 | 9:d8157fbfcd2a | 230 | //////////////////////////////// end Speed_IterateOnce |
benson516 | 9:d8157fbfcd2a | 231 | |
benson516 | 10:9f5f4a22346c | 232 | |
benson516 | 9:d8157fbfcd2a | 233 | // Control |
benson516 | 10:9f5f4a22346c | 234 | /////////////////////////////////////////////////////////// |
benson516 | 14:67fc256efeb7 | 235 | void CURRENT_CONTROL::TorqueControl(float TorqueRef, bool enable){ |
benson516 | 14:67fc256efeb7 | 236 | Control(Kt_inv*TorqueRef, enable); |
benson516 | 14:67fc256efeb7 | 237 | } |
benson516 | 11:31cd02611cd0 | 238 | void CURRENT_CONTROL::Control(float curRef, bool enable) |
adam_z | 0:955aa05c968a | 239 | { |
benson516 | 15:d9ccd6c92a21 | 240 | // Input saturation |
benson516 | 15:d9ccd6c92a21 | 241 | curCommand = saturation(curRef,current_limit_H,current_limit_L); |
benson516 | 15:d9ccd6c92a21 | 242 | |
benson516 | 7:6794cfba3564 | 243 | // Init check |
benson516 | 7:6794cfba3564 | 244 | OffsetInit(); |
benson516 | 12:085f35babe21 | 245 | if (!Flag_Init) return; |
benson516 | 7:6794cfba3564 | 246 | ////////////////////////////////////// |
benson516 | 12:085f35babe21 | 247 | |
benson516 | 7:6794cfba3564 | 248 | // Get measurement |
benson516 | 8:fd6fb3cb12ec | 249 | // Speed |
benson516 | 8:fd6fb3cb12ec | 250 | Speed_IterateOnce(); |
benson516 | 8:fd6fb3cb12ec | 251 | // Motor current |
benson516 | 7:6794cfba3564 | 252 | GetCurrent(); |
benson516 | 12:085f35babe21 | 253 | |
benson516 | 7:6794cfba3564 | 254 | //--------------------------------// |
benson516 | 12:085f35babe21 | 255 | |
benson516 | 12:085f35babe21 | 256 | if (enable){ |
benson516 | 12:085f35babe21 | 257 | // PID |
benson516 | 12:085f35babe21 | 258 | pid.Compute_noWindUP(curRef, curFeedBack_filter); |
benson516 | 12:085f35babe21 | 259 | |
benson516 | 12:085f35babe21 | 260 | // Voltage output with back-emf compensation |
benson516 | 12:085f35babe21 | 261 | voltage_out = pid.output + func_back_emf(angularSpeed); |
benson516 | 12:085f35babe21 | 262 | // voltage_out = 0.0 + func_back_emf(angularSpeed); |
benson516 | 12:085f35babe21 | 263 | |
benson516 | 12:085f35babe21 | 264 | // Controlller output |
benson516 | 11:31cd02611cd0 | 265 | SetVoltage(voltage_out); |
benson516 | 12:085f35babe21 | 266 | }else{ |
benson516 | 12:085f35babe21 | 267 | pid.Reset(); |
benson516 | 13:b5f85f926f22 | 268 | voltage_out = 0.0; |
benson516 | 11:31cd02611cd0 | 269 | SetVoltage(0.0); |
benson516 | 12:085f35babe21 | 270 | } |
benson516 | 7:6794cfba3564 | 271 | //--------------------------------// |
benson516 | 12:085f35babe21 | 272 | |
benson516 | 5:7ccd2fb7ce7e | 273 | // Anti-windup |
benson516 | 5:7ccd2fb7ce7e | 274 | pid.Anti_windup(delta_output); |
benson516 | 12:085f35babe21 | 275 | |
benson516 | 8:fd6fb3cb12ec | 276 | /////////////////////////////////////// |
benson516 | 8:fd6fb3cb12ec | 277 | // Reset flag |
benson516 | 8:fd6fb3cb12ec | 278 | Flag_SpeedCal_Iterated = false; |
adam_z | 1:c5973a56d474 | 279 | } |
benson516 | 10:9f5f4a22346c | 280 | /////////////////////////////////////////////////////////// end Control |
benson516 | 10:9f5f4a22346c | 281 | |
benson516 | 10:9f5f4a22346c | 282 | |
benson516 | 5:7ccd2fb7ce7e | 283 | // Back emf as the function of rotational speed |
benson516 | 5:7ccd2fb7ce7e | 284 | float CURRENT_CONTROL::func_back_emf(const float &W_in){ |
benson516 | 5:7ccd2fb7ce7e | 285 | return (Ke*W_in); |
adam_z | 1:c5973a56d474 | 286 | } |
adam_z | 3:c787d1c5ad6a | 287 | |
benson516 | 15:d9ccd6c92a21 | 288 | // Elementary function (building block) |
adam_z | 1:c5973a56d474 | 289 | void CURRENT_CONTROL::SetPWMDuty(float ratio) |
adam_z | 1:c5973a56d474 | 290 | { |
adam_z | 1:c5973a56d474 | 291 | MotorPlus = ratio; |
benson516 | 7:6794cfba3564 | 292 | if(pwmIndex_ == PWM1){ |
benson516 | 7:6794cfba3564 | 293 | TIM1->CCER |= 4; |
benson516 | 7:6794cfba3564 | 294 | }else if(pwmIndex_ == PWM2){ |
benson516 | 7:6794cfba3564 | 295 | TIM1->CCER |= 64; |
benson516 | 7:6794cfba3564 | 296 | } |
adam_z | 2:562bd14dfd3a | 297 | } |
benson516 | 9:d8157fbfcd2a | 298 | void CURRENT_CONTROL::SetVoltage(float volt) |
benson516 | 9:d8157fbfcd2a | 299 | { |
benson516 | 9:d8157fbfcd2a | 300 | // Output saturation and unit changing |
benson516 | 9:d8157fbfcd2a | 301 | if (reverse_voltage) |
benson516 | 9:d8157fbfcd2a | 302 | SetPWMDuty( 0.5 - saturation( volt*voltage2Duty, delta_output, 0.5, -0.5) ); |
benson516 | 9:d8157fbfcd2a | 303 | else |
benson516 | 9:d8157fbfcd2a | 304 | SetPWMDuty( 0.5 + saturation( volt*voltage2Duty, delta_output, 0.5, -0.5) ); |
benson516 | 9:d8157fbfcd2a | 305 | } |
benson516 | 9:d8157fbfcd2a | 306 | // |
adam_z | 2:562bd14dfd3a | 307 | float CURRENT_CONTROL::GetAnalogIn(void) |
adam_z | 2:562bd14dfd3a | 308 | { |
benson516 | 7:6794cfba3564 | 309 | analogInValue = currentAnalogIn.read(); |
benson516 | 7:6794cfba3564 | 310 | return analogInValue; |
adam_z | 2:562bd14dfd3a | 311 | } |
adam_z | 2:562bd14dfd3a | 312 | |
adam_z | 2:562bd14dfd3a | 313 | float CURRENT_CONTROL::GetCurrent(void) |
adam_z | 2:562bd14dfd3a | 314 | { |
benson516 | 7:6794cfba3564 | 315 | // Init check |
benson516 | 12:085f35babe21 | 316 | if (!Flag_Init) return 0.0; |
benson516 | 12:085f35babe21 | 317 | |
benson516 | 7:6794cfba3564 | 318 | //-----------------------------------------// |
benson516 | 9:d8157fbfcd2a | 319 | GetAnalogIn(); |
benson516 | 12:085f35babe21 | 320 | |
benson516 | 7:6794cfba3564 | 321 | // Unit transformation |
benson516 | 9:d8157fbfcd2a | 322 | if (reverse_current){ |
benson516 | 9:d8157fbfcd2a | 323 | curFeedBack = -1*(analogInValue - currentOffset)*analog2Cur; |
benson516 | 9:d8157fbfcd2a | 324 | }else{ |
benson516 | 9:d8157fbfcd2a | 325 | curFeedBack = (analogInValue - currentOffset)*analog2Cur; |
benson516 | 9:d8157fbfcd2a | 326 | } |
benson516 | 9:d8157fbfcd2a | 327 | // |
benson516 | 12:085f35babe21 | 328 | |
benson516 | 7:6794cfba3564 | 329 | // Low-pass filter |
benson516 | 19:24605ba48462 | 330 | curFeedBack_filter = lpf_current.filter(curFeedBack); |
benson516 | 12:085f35babe21 | 331 | |
benson516 | 12:085f35babe21 | 332 | return curFeedBack_filter; //curFeedBack; |
adam_z | 3:c787d1c5ad6a | 333 | } |