Fork and fix for mwork
Dependencies: mbed-dev-f303 FastPWM3 millis
main.cpp@59:568e7be5232f, 2020-06-29 (annotated)
- Committer:
- annhandt09
- Date:
- Mon Jun 29 09:36:26 2020 +0000
- Revision:
- 59:568e7be5232f
- Parent:
- 58:fb799e99a5f7
add controller.p_des = controller.theta_mech - (controller.t_ff / controller.kp) ; for first enable.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
benkatz | 22:60276ba87ac6 | 1 | /// high-bandwidth 3-phase motor control, for robots |
benkatz | 45:26801179208e | 2 | /// Written by benkatz, with much inspiration from Bayley Wang, Nick Kirkby, Shane Colton, David Otten, and others |
benkatz | 22:60276ba87ac6 | 3 | /// Hardware documentation can be found at build-its.blogspot.com |
benkatz | 22:60276ba87ac6 | 4 | /// Written for the STM32F446, but can be implemented on other STM32 MCU's with some further register-diddling |
benkatz | 47:e1196a851f76 | 5 | /// Version for the TI DRV8323 Everything Chip |
annhandt09 | 57:c26b0093783b | 6 | #define mWorkDebug |
benkatz | 23:2adf23ee0305 | 7 | #define REST_MODE 0 |
benkatz | 23:2adf23ee0305 | 8 | #define CALIBRATION_MODE 1 |
benkatz | 26:2b865c00d7e9 | 9 | #define MOTOR_MODE 2 |
benkatz | 23:2adf23ee0305 | 10 | #define SETUP_MODE 4 |
benkatz | 23:2adf23ee0305 | 11 | #define ENCODER_MODE 5 |
benkatz | 22:60276ba87ac6 | 12 | |
bdring | 54:3e056b097c52 | 13 | #define VERSION_NUM "2.0.0" |
benkatz | 26:2b865c00d7e9 | 14 | |
bdring | 54:3e056b097c52 | 15 | // this sets up the 2 IO modes of the UART connector (UART and Step/Dir) |
annhandt09 | 55:fee62d8fd8fb | 16 | |
bdring | 54:3e056b097c52 | 17 | #define UART_TX PA_2 // define the pins on the connector |
bdring | 54:3e056b097c52 | 18 | #define UART_RX PA_3 // define the pins on the connector |
bdring | 54:3e056b097c52 | 19 | #define UART_BAUD 230400 |
annhandt09 | 55:fee62d8fd8fb | 20 | // Ints stored in flash. Includes position sensor calibration lookup table |
benkatz | 17:3c5df2982199 | 21 | |
benkatz | 0:4e1c4df6aabd | 22 | #include "mbed.h" |
benkatz | 0:4e1c4df6aabd | 23 | #include "PositionSensor.h" |
benkatz | 20:bf9ea5125d52 | 24 | #include "structs.h" |
benkatz | 20:bf9ea5125d52 | 25 | #include "foc.h" |
benkatz | 22:60276ba87ac6 | 26 | #include "calibration.h" |
benkatz | 20:bf9ea5125d52 | 27 | #include "hw_setup.h" |
benkatz | 23:2adf23ee0305 | 28 | #include "math_ops.h" |
benkatz | 20:bf9ea5125d52 | 29 | #include "current_controller_config.h" |
benkatz | 20:bf9ea5125d52 | 30 | #include "hw_config.h" |
benkatz | 20:bf9ea5125d52 | 31 | #include "motor_config.h" |
benkatz | 23:2adf23ee0305 | 32 | #include "stm32f4xx_flash.h" |
benkatz | 23:2adf23ee0305 | 33 | #include "FlashWriter.h" |
benkatz | 23:2adf23ee0305 | 34 | #include "user_config.h" |
benkatz | 23:2adf23ee0305 | 35 | #include "PreferenceWriter.h" |
benkatz | 42:738fa01b0346 | 36 | #include "CAN_com.h" |
benkatz | 44:8040fa2fcb0d | 37 | #include "DRV.h" |
annhandt09 | 55:fee62d8fd8fb | 38 | #include "mode.h" |
annhandt09 | 58:fb799e99a5f7 | 39 | |
annhandt09 | 55:fee62d8fd8fb | 40 | int io_mode = IO_MODE_NONE; // the default mode is serial |
annhandt09 | 55:fee62d8fd8fb | 41 | |
annhandt09 | 55:fee62d8fd8fb | 42 | float __float_reg[64]; // Floats stored in flash |
annhandt09 | 55:fee62d8fd8fb | 43 | int __int_reg[256]; |
benkatz | 23:2adf23ee0305 | 44 | PreferenceWriter prefs(6); |
benkatz | 9:d7eb815cb057 | 45 | |
benkatz | 20:bf9ea5125d52 | 46 | GPIOStruct gpio; |
annhandt09 | 57:c26b0093783b | 47 | ControllerStruct controller = { |
annhandt09 | 59:568e7be5232f | 48 | .kp = 250.0 , |
annhandt09 | 59:568e7be5232f | 49 | .kd = 2.5 , |
annhandt09 | 57:c26b0093783b | 50 | .t_ff = -17.0 |
annhandt09 | 57:c26b0093783b | 51 | }; |
benkatz | 48:74a40481740c | 52 | ObserverStruct observer; |
benkatz | 20:bf9ea5125d52 | 53 | COMStruct com; |
bdring | 54:3e056b097c52 | 54 | |
bdring | 54:3e056b097c52 | 55 | |
bdring | 54:3e056b097c52 | 56 | Serial *pc = NULL; |
bdring | 54:3e056b097c52 | 57 | InterruptIn *step = NULL; |
bdring | 54:3e056b097c52 | 58 | DigitalIn *dir = NULL; |
benkatz | 9:d7eb815cb057 | 59 | |
benkatz | 17:3c5df2982199 | 60 | |
benkatz | 45:26801179208e | 61 | CAN can(PB_8, PB_9, 1000000); // CAN Rx pin name, CAN Tx pin name |
benkatz | 26:2b865c00d7e9 | 62 | CANMessage rxMsg; |
benkatz | 26:2b865c00d7e9 | 63 | CANMessage txMsg; |
benkatz | 23:2adf23ee0305 | 64 | |
benkatz | 44:8040fa2fcb0d | 65 | SPI drv_spi(PA_7, PA_6, PA_5); |
benkatz | 44:8040fa2fcb0d | 66 | DigitalOut drv_cs(PA_4); |
benkatz | 44:8040fa2fcb0d | 67 | DRV832x drv(&drv_spi, &drv_cs); |
benkatz | 8:10ae7bc88d6e | 68 | |
benkatz | 26:2b865c00d7e9 | 69 | PositionSensorAM5147 spi(16384, 0.0, NPP); |
benkatz | 20:bf9ea5125d52 | 70 | |
benkatz | 23:2adf23ee0305 | 71 | volatile int count = 0; |
benkatz | 23:2adf23ee0305 | 72 | volatile int state = REST_MODE; |
benkatz | 23:2adf23ee0305 | 73 | volatile int state_change; |
benkatz | 20:bf9ea5125d52 | 74 | |
annhandt09 | 57:c26b0093783b | 75 | volatile bool state_Led = false; |
annhandt09 | 57:c26b0093783b | 76 | volatile uint32_t timeSche = 0; |
annhandt09 | 57:c26b0093783b | 77 | |
bdring | 54:3e056b097c52 | 78 | |
bdring | 54:3e056b097c52 | 79 | void serial_interrupt(void); |
bdring | 54:3e056b097c52 | 80 | void stepInt(); |
annhandt09 | 58:fb799e99a5f7 | 81 | extern void cond_printf(const char *format, ...); |
bdring | 54:3e056b097c52 | 82 | |
bdring | 54:3e056b097c52 | 83 | // set the current mode of the UART connector |
bdring | 54:3e056b097c52 | 84 | void set_io_mode(int new_io_mode) { |
bdring | 54:3e056b097c52 | 85 | if (new_io_mode == IO_MODE_SERIAL) { |
annhandt09 | 57:c26b0093783b | 86 | |
bdring | 54:3e056b097c52 | 87 | io_mode = IO_MODE_SERIAL; |
bdring | 54:3e056b097c52 | 88 | if (step != NULL) |
bdring | 54:3e056b097c52 | 89 | step->rise(NULL); |
bdring | 54:3e056b097c52 | 90 | delete step; |
bdring | 54:3e056b097c52 | 91 | delete dir; |
bdring | 54:3e056b097c52 | 92 | pc = new Serial(UART_TX, UART_RX); |
bdring | 54:3e056b097c52 | 93 | pc->baud(UART_BAUD); |
bdring | 54:3e056b097c52 | 94 | pc->attach(&serial_interrupt); |
bdring | 54:3e056b097c52 | 95 | wait(100); |
annhandt09 | 57:c26b0093783b | 96 | cond_printf("UART Mode\n\r"); |
bdring | 54:3e056b097c52 | 97 | } |
bdring | 54:3e056b097c52 | 98 | else if (new_io_mode == IO_MODE_STEP_DIR){ |
annhandt09 | 57:c26b0093783b | 99 | |
bdring | 54:3e056b097c52 | 100 | wait(1000); |
bdring | 54:3e056b097c52 | 101 | |
bdring | 54:3e056b097c52 | 102 | io_mode = IO_MODE_STEP_DIR; |
bdring | 54:3e056b097c52 | 103 | |
bdring | 54:3e056b097c52 | 104 | if (pc != NULL) { |
bdring | 54:3e056b097c52 | 105 | pc->attach(NULL); |
bdring | 54:3e056b097c52 | 106 | } |
bdring | 54:3e056b097c52 | 107 | delete pc; |
bdring | 54:3e056b097c52 | 108 | |
bdring | 54:3e056b097c52 | 109 | step = new InterruptIn(UART_RX); |
bdring | 54:3e056b097c52 | 110 | step->rise(&stepInt); |
bdring | 54:3e056b097c52 | 111 | dir = new DigitalIn(UART_TX); |
annhandt09 | 57:c26b0093783b | 112 | cond_printf("STEP/DIR Mode\n\r"); |
bdring | 54:3e056b097c52 | 113 | } |
bdring | 54:3e056b097c52 | 114 | |
bdring | 54:3e056b097c52 | 115 | |
bdring | 54:3e056b097c52 | 116 | } |
bdring | 54:3e056b097c52 | 117 | |
annhandt09 | 55:fee62d8fd8fb | 118 | /* |
bdring | 54:3e056b097c52 | 119 | // Checks to see if in Serial mode before printing |
bdring | 54:3e056b097c52 | 120 | void cond_printf(const char *format, ...) |
bdring | 54:3e056b097c52 | 121 | { |
bdring | 54:3e056b097c52 | 122 | if (io_mode != IO_MODE_SERIAL) { |
bdring | 54:3e056b097c52 | 123 | return; |
bdring | 54:3e056b097c52 | 124 | } |
bdring | 54:3e056b097c52 | 125 | char loc_buf[64]; |
bdring | 54:3e056b097c52 | 126 | char * temp = loc_buf; |
bdring | 54:3e056b097c52 | 127 | va_list arg; |
bdring | 54:3e056b097c52 | 128 | va_list copy; |
bdring | 54:3e056b097c52 | 129 | va_start(arg, format); |
bdring | 54:3e056b097c52 | 130 | va_copy(copy, arg); |
bdring | 54:3e056b097c52 | 131 | size_t len = vsnprintf(NULL, 0, format, arg); |
bdring | 54:3e056b097c52 | 132 | va_end(copy); |
bdring | 54:3e056b097c52 | 133 | if(len >= sizeof(loc_buf)){ |
bdring | 54:3e056b097c52 | 134 | temp = new char[len+1]; |
bdring | 54:3e056b097c52 | 135 | if(temp == NULL) { |
bdring | 54:3e056b097c52 | 136 | return; |
bdring | 54:3e056b097c52 | 137 | } |
bdring | 54:3e056b097c52 | 138 | } |
bdring | 54:3e056b097c52 | 139 | len = vsnprintf(temp, len+1, format, arg); |
bdring | 54:3e056b097c52 | 140 | pc->printf( temp); |
bdring | 54:3e056b097c52 | 141 | va_end(arg); |
bdring | 54:3e056b097c52 | 142 | if(len > 64){ |
bdring | 54:3e056b097c52 | 143 | delete[] temp; |
bdring | 54:3e056b097c52 | 144 | } |
bdring | 54:3e056b097c52 | 145 | } |
bdring | 54:3e056b097c52 | 146 | |
annhandt09 | 55:fee62d8fd8fb | 147 | */ |
annhandt09 | 55:fee62d8fd8fb | 148 | |
bdring | 54:3e056b097c52 | 149 | // Interupt function for receiving step signal |
bdring | 54:3e056b097c52 | 150 | void stepInt() { |
annhandt09 | 57:c26b0093783b | 151 | state_Led = !state_Led ; |
annhandt09 | 57:c26b0093783b | 152 | gpio.led->write(state_Led); |
bdring | 54:3e056b097c52 | 153 | if (dir) { |
bdring | 54:3e056b097c52 | 154 | controller.p_des += RADS_PER_STEP; |
bdring | 54:3e056b097c52 | 155 | } else { |
bdring | 54:3e056b097c52 | 156 | controller.p_des -= RADS_PER_STEP; |
bdring | 54:3e056b097c52 | 157 | } |
bdring | 54:3e056b097c52 | 158 | } |
bdring | 54:3e056b097c52 | 159 | |
annhandt09 | 57:c26b0093783b | 160 | void sendSche() { |
annhandt09 | 57:c26b0093783b | 161 | if (timeSche > 40000){ |
annhandt09 | 57:c26b0093783b | 162 | timeSche = 0 ; |
annhandt09 | 57:c26b0093783b | 163 | state_Led = !state_Led ; |
annhandt09 | 57:c26b0093783b | 164 | gpio.led->write(state_Led); |
annhandt09 | 57:c26b0093783b | 165 | /* replySche(&txMsg, controller.p_des, 0, 0); |
annhandt09 | 57:c26b0093783b | 166 | can.write(txMsg); */ |
annhandt09 | 57:c26b0093783b | 167 | } |
annhandt09 | 57:c26b0093783b | 168 | } |
bdring | 54:3e056b097c52 | 169 | // CAN message received |
annhandt09 | 56:eaf75bcad361 | 170 | /* |
annhandt09 | 56:eaf75bcad361 | 171 | FD REST_MODE |
annhandt09 | 56:eaf75bcad361 | 172 | FC MOTORMODE |
annhandt09 | 56:eaf75bcad361 | 173 | FE ZeroPosition |
annhandt09 | 56:eaf75bcad361 | 174 | FB SteoDir |
annhandt09 | 56:eaf75bcad361 | 175 | FA Serial |
annhandt09 | 56:eaf75bcad361 | 176 | F0 Calib |
annhandt09 | 56:eaf75bcad361 | 177 | */ |
benkatz | 26:2b865c00d7e9 | 178 | void onMsgReceived() { |
annhandt09 | 55:fee62d8fd8fb | 179 | //msgAvailable = true; //0A FF FF FF FF FF |
bdring | 54:3e056b097c52 | 180 | //cond_printf("%df\n\r", rxMsg.id); |
benkatz | 26:2b865c00d7e9 | 181 | can.read(rxMsg); |
benkatz | 28:8c7e29f719c5 | 182 | if((rxMsg.id == CAN_ID)){ |
benkatz | 28:8c7e29f719c5 | 183 | controller.timeout = 0; |
benkatz | 28:8c7e29f719c5 | 184 | if(((rxMsg.data[0]==0xFF) & (rxMsg.data[1]==0xFF) & (rxMsg.data[2]==0xFF) & (rxMsg.data[3]==0xFF) & (rxMsg.data[4]==0xFF) & (rxMsg.data[5]==0xFF) & (rxMsg.data[6]==0xFF) & (rxMsg.data[7]==0xFC))){ |
benkatz | 28:8c7e29f719c5 | 185 | state = MOTOR_MODE; |
benkatz | 28:8c7e29f719c5 | 186 | state_change = 1; |
benkatz | 28:8c7e29f719c5 | 187 | } |
benkatz | 28:8c7e29f719c5 | 188 | else if(((rxMsg.data[0]==0xFF) & (rxMsg.data[1]==0xFF) & (rxMsg.data[2]==0xFF) & (rxMsg.data[3]==0xFF) * (rxMsg.data[4]==0xFF) & (rxMsg.data[5]==0xFF) & (rxMsg.data[6]==0xFF) & (rxMsg.data[7]==0xFD))){ |
benkatz | 28:8c7e29f719c5 | 189 | state = REST_MODE; |
benkatz | 28:8c7e29f719c5 | 190 | state_change = 1; |
annhandt09 | 56:eaf75bcad361 | 191 | gpio.led->write(0); |
annhandt09 | 56:eaf75bcad361 | 192 | } |
annhandt09 | 56:eaf75bcad361 | 193 | else if(((rxMsg.data[0]==0xFF) & (rxMsg.data[1]==0xFF) & (rxMsg.data[2]==0xFF) & (rxMsg.data[3]==0xFF) * (rxMsg.data[4]==0xFF) & (rxMsg.data[5]==0xFF) & (rxMsg.data[6]==0xFF) & (rxMsg.data[7]==0xF0))){ |
annhandt09 | 56:eaf75bcad361 | 194 | state = CALIBRATION_MODE; |
annhandt09 | 56:eaf75bcad361 | 195 | state_change = 1; |
annhandt09 | 56:eaf75bcad361 | 196 | //gpio.led->write(0); |
benkatz | 28:8c7e29f719c5 | 197 | } |
benkatz | 28:8c7e29f719c5 | 198 | else if(((rxMsg.data[0]==0xFF) & (rxMsg.data[1]==0xFF) & (rxMsg.data[2]==0xFF) & (rxMsg.data[3]==0xFF) * (rxMsg.data[4]==0xFF) & (rxMsg.data[5]==0xFF) & (rxMsg.data[6]==0xFF) & (rxMsg.data[7]==0xFE))){ |
benkatz | 28:8c7e29f719c5 | 199 | spi.ZeroPosition(); |
benkatz | 28:8c7e29f719c5 | 200 | } |
bdring | 54:3e056b097c52 | 201 | // new commands .... |
bdring | 54:3e056b097c52 | 202 | else if(((rxMsg.data[0]==0xFF) & (rxMsg.data[1]==0xFF) & (rxMsg.data[2]==0xFF) & (rxMsg.data[3]==0xFF) * (rxMsg.data[4]==0xFF) & (rxMsg.data[5]==0xFF) & (rxMsg.data[6]==0xFF) & (rxMsg.data[7]==0xFB))){ |
bdring | 54:3e056b097c52 | 203 | io_mode = IO_MODE_STEP_DIR; |
bdring | 54:3e056b097c52 | 204 | //if (pc != NULL) { |
bdring | 54:3e056b097c52 | 205 | pc->attach(NULL); |
bdring | 54:3e056b097c52 | 206 | //} |
bdring | 54:3e056b097c52 | 207 | step = new InterruptIn(UART_RX); |
bdring | 54:3e056b097c52 | 208 | step->rise(&stepInt); |
bdring | 54:3e056b097c52 | 209 | dir = new DigitalIn(UART_TX); |
bdring | 54:3e056b097c52 | 210 | } |
bdring | 54:3e056b097c52 | 211 | else if(((rxMsg.data[0]==0xFF) & (rxMsg.data[1]==0xFF) & (rxMsg.data[2]==0xFF) & (rxMsg.data[3]==0xFF) * (rxMsg.data[4]==0xFF) & (rxMsg.data[5]==0xFF) & (rxMsg.data[6]==0xFF) & (rxMsg.data[7]==0xFA))){ |
bdring | 54:3e056b097c52 | 212 | io_mode = IO_MODE_SERIAL; |
bdring | 54:3e056b097c52 | 213 | if (step != NULL) |
bdring | 54:3e056b097c52 | 214 | step->rise(NULL); |
bdring | 54:3e056b097c52 | 215 | delete step; |
bdring | 54:3e056b097c52 | 216 | delete dir; |
bdring | 54:3e056b097c52 | 217 | pc = new Serial(UART_TX, UART_RX); |
bdring | 54:3e056b097c52 | 218 | pc->baud(UART_BAUD); |
bdring | 54:3e056b097c52 | 219 | pc->attach(&serial_interrupt); |
annhandt09 | 57:c26b0093783b | 220 | wait_ms(100); |
bdring | 54:3e056b097c52 | 221 | } |
benkatz | 28:8c7e29f719c5 | 222 | else if(state == MOTOR_MODE){ |
benkatz | 28:8c7e29f719c5 | 223 | unpack_cmd(rxMsg, &controller); |
annhandt09 | 55:fee62d8fd8fb | 224 | } |
annhandt09 | 55:fee62d8fd8fb | 225 | cond_printf("CAN BUS: %f ,%f, %f\n\r", rxMsg.data[0], rxMsg.data[1], rxMsg.data[2]); |
benkatz | 37:c0f352d6e8e3 | 226 | pack_reply(&txMsg, controller.theta_mech, controller.dtheta_mech, controller.i_q_filt*KT_OUT); |
benkatz | 37:c0f352d6e8e3 | 227 | can.write(txMsg); |
bdring | 54:3e056b097c52 | 228 | } |
benkatz | 26:2b865c00d7e9 | 229 | } |
benkatz | 26:2b865c00d7e9 | 230 | |
benkatz | 23:2adf23ee0305 | 231 | void enter_menu_state(void){ |
benkatz | 44:8040fa2fcb0d | 232 | drv.disable_gd(); |
benkatz | 47:e1196a851f76 | 233 | //gpio.enable->write(0); |
bdring | 54:3e056b097c52 | 234 | cond_printf("\n\r\n\r\n\r"); |
bdring | 54:3e056b097c52 | 235 | cond_printf(" Commands:\n\r"); |
benkatz | 44:8040fa2fcb0d | 236 | wait_us(10); |
bdring | 54:3e056b097c52 | 237 | cond_printf(" m - Motor Mode\n\r"); |
benkatz | 44:8040fa2fcb0d | 238 | wait_us(10); |
bdring | 54:3e056b097c52 | 239 | cond_printf(" c - Calibrate Encoder\n\r"); |
benkatz | 44:8040fa2fcb0d | 240 | wait_us(10); |
bdring | 54:3e056b097c52 | 241 | cond_printf(" s - Setup\n\r"); |
benkatz | 44:8040fa2fcb0d | 242 | wait_us(10); |
bdring | 54:3e056b097c52 | 243 | cond_printf(" e - Display Encoder\n\r"); |
benkatz | 44:8040fa2fcb0d | 244 | wait_us(10); |
bdring | 54:3e056b097c52 | 245 | cond_printf(" z - Set Zero Position\n\r"); |
benkatz | 44:8040fa2fcb0d | 246 | wait_us(10); |
bdring | 54:3e056b097c52 | 247 | cond_printf(" f - Move Forward\n\r"); |
bdring | 53:349304b6d937 | 248 | wait_us(10); |
bdring | 54:3e056b097c52 | 249 | cond_printf(" b - Move Back\n\r"); |
bdring | 53:349304b6d937 | 250 | wait_us(10); |
bdring | 54:3e056b097c52 | 251 | cond_printf(" p - current posiiton\n\r"); |
bdring | 52:cf8b2abf811d | 252 | wait_us(10); |
bdring | 54:3e056b097c52 | 253 | cond_printf(" esc - Exit to Menu\n\r"); |
benkatz | 44:8040fa2fcb0d | 254 | wait_us(10); |
benkatz | 23:2adf23ee0305 | 255 | state_change = 0; |
benkatz | 37:c0f352d6e8e3 | 256 | gpio.led->write(0); |
benkatz | 23:2adf23ee0305 | 257 | } |
benkatz | 24:58c2d7571207 | 258 | |
benkatz | 24:58c2d7571207 | 259 | void enter_setup_state(void){ |
bdring | 54:3e056b097c52 | 260 | cond_printf("\n\r\n\r Configuration Options \n\r\n\n"); |
benkatz | 44:8040fa2fcb0d | 261 | wait_us(10); |
bdring | 54:3e056b097c52 | 262 | cond_printf(" %-4s %-31s %-5s %-6s %-2s\n\r\n\r", "prefix", "parameter", "min", "max", "current value"); |
benkatz | 44:8040fa2fcb0d | 263 | wait_us(10); |
bdring | 54:3e056b097c52 | 264 | cond_printf(" %-4s %-31s %-5s %-6s %.1f\n\r", "b", "Current Bandwidth (Hz)", "100", "2000", I_BW); |
benkatz | 44:8040fa2fcb0d | 265 | wait_us(10); |
bdring | 54:3e056b097c52 | 266 | cond_printf(" %-4s %-31s %-5s %-6s %-5i\n\r", "i", "CAN ID", "0", "127", CAN_ID); |
benkatz | 44:8040fa2fcb0d | 267 | wait_us(10); |
bdring | 54:3e056b097c52 | 268 | cond_printf(" %-4s %-31s %-5s %-6s %-5i\n\r", "m", "CAN Master ID", "0", "127", CAN_MASTER); |
benkatz | 44:8040fa2fcb0d | 269 | wait_us(10); |
bdring | 54:3e056b097c52 | 270 | cond_printf(" %-4s %-31s %-5s %-6s %.1f\n\r", "l", "Current Limit (A)", "0.0", "40.0", I_MAX); |
benkatz | 51:6cd89bd6fcaa | 271 | wait_us(10); |
bdring | 54:3e056b097c52 | 272 | cond_printf(" %-4s %-31s %-5s %-6s %.1f\n\r", "f", "FW Current Limit (A)", "0.0", "33.0", I_FW_MAX); |
benkatz | 44:8040fa2fcb0d | 273 | wait_us(10); |
bdring | 54:3e056b097c52 | 274 | cond_printf(" %-4s %-31s %-5s %-6s %d\n\r", "t", "CAN Timeout (cycles)(0 = none)", "0", "100000", CAN_TIMEOUT); |
benkatz | 44:8040fa2fcb0d | 275 | wait_us(10); |
bdring | 54:3e056b097c52 | 276 | cond_printf("\n\r To change a value, type 'prefix''value''ENTER'\n\r i.e. 'b1000''ENTER'\n\r\n\r"); |
benkatz | 44:8040fa2fcb0d | 277 | wait_us(10); |
benkatz | 24:58c2d7571207 | 278 | state_change = 0; |
benkatz | 24:58c2d7571207 | 279 | } |
annhandt09 | 58:fb799e99a5f7 | 280 | void printFirmwareVer(){ |
annhandt09 | 58:fb799e99a5f7 | 281 | cond_printf("\n\r\n\r Hobby King Cheetah\n\r\n\r"); |
annhandt09 | 58:fb799e99a5f7 | 282 | wait_us(10); |
annhandt09 | 58:fb799e99a5f7 | 283 | cond_printf("\n\r Debug Info:\n\r"); |
annhandt09 | 58:fb799e99a5f7 | 284 | cond_printf(" Firmware Version: %s\n\r", VERSION_NUM); |
annhandt09 | 58:fb799e99a5f7 | 285 | cond_printf(" ADC1 Offset: %d ADC2 Offset: %d\n\r", controller.adc1_offset, controller.adc2_offset); |
annhandt09 | 58:fb799e99a5f7 | 286 | cond_printf(" Position Sensor Electrical Offset: %.4f\n\r", E_OFFSET); |
annhandt09 | 58:fb799e99a5f7 | 287 | cond_printf(" Output Zero Position: %.4f\n\r", M_OFFSET); |
annhandt09 | 58:fb799e99a5f7 | 288 | cond_printf(" Gear Ratio %.4f:1\r\n", GR); |
annhandt09 | 58:fb799e99a5f7 | 289 | cond_printf(" Mapped Position %.4f to %.4f Radians\n\r", P_MIN, P_MAX); |
annhandt09 | 58:fb799e99a5f7 | 290 | cond_printf(" PHASE_ORDER %d \r\n", PHASE_ORDER); |
annhandt09 | 59:568e7be5232f | 291 | cond_printf(" alpha: %.4f Kd: %.4f\n\r", controller.alpha, controller.k_d); |
annhandt09 | 59:568e7be5232f | 292 | cond_printf(" theta_mech: %.4f theta_elec: %.4f\n\r", controller.theta_mech, controller.theta_elec); |
annhandt09 | 59:568e7be5232f | 293 | cond_printf(" dtheta_mech: %.4f Dtheta_elec: %.4f\n\r", controller.dtheta_mech, controller.dtheta_elec); |
annhandt09 | 59:568e7be5232f | 294 | cond_printf(" pdes: %.4f vdes: %.4f\n\r", controller.p_des, controller.v_des); |
annhandt09 | 59:568e7be5232f | 295 | cond_printf("%.3f %.3f %.3f\n\r", (float)observer.temperature, (float)observer.temperature2, observer.resistance); |
annhandt09 | 59:568e7be5232f | 296 | cond_printf("%.3f %.3f %.3f %.3f %.3f\n\r", controller.v_d, controller.v_q, controller.i_d_filt, controller.i_q_filt, controller.dtheta_elec); |
annhandt09 | 58:fb799e99a5f7 | 297 | cond_printf(" CAN ID: %d\n\r", CAN_ID); |
annhandt09 | 58:fb799e99a5f7 | 298 | } |
benkatz | 23:2adf23ee0305 | 299 | void enter_torque_mode(void){ |
benkatz | 44:8040fa2fcb0d | 300 | drv.enable_gd(); |
benkatz | 47:e1196a851f76 | 301 | //gpio.enable->write(1); |
benkatz | 37:c0f352d6e8e3 | 302 | controller.ovp_flag = 0; |
benkatz | 28:8c7e29f719c5 | 303 | reset_foc(&controller); // Tesets integrators, and other control loop parameters |
benkatz | 28:8c7e29f719c5 | 304 | wait(.001); |
benkatz | 23:2adf23ee0305 | 305 | controller.i_d_ref = 0; |
benkatz | 50:ba72df25d10f | 306 | controller.i_q_ref = 0; // Current Setpoints |
benkatz | 37:c0f352d6e8e3 | 307 | gpio.led->write(1); // Turn on status LED |
benkatz | 25:f5741040c4bb | 308 | state_change = 0; |
bdring | 54:3e056b097c52 | 309 | cond_printf("\n\r Entering Motor Mode \n\r"); |
benkatz | 23:2adf23ee0305 | 310 | } |
benkatz | 22:60276ba87ac6 | 311 | |
benkatz | 23:2adf23ee0305 | 312 | void calibrate(void){ |
benkatz | 44:8040fa2fcb0d | 313 | drv.enable_gd(); |
benkatz | 47:e1196a851f76 | 314 | //gpio.enable->write(1); |
benkatz | 37:c0f352d6e8e3 | 315 | gpio.led->write(1); // Turn on status LED |
benkatz | 25:f5741040c4bb | 316 | order_phases(&spi, &gpio, &controller, &prefs); // Check phase ordering |
benkatz | 25:f5741040c4bb | 317 | calibrate(&spi, &gpio, &controller, &prefs); // Perform calibration procedure |
benkatz | 37:c0f352d6e8e3 | 318 | gpio.led->write(0);; // Turn off status LED |
benkatz | 23:2adf23ee0305 | 319 | wait(.2); |
bdring | 54:3e056b097c52 | 320 | cond_printf("\n\r Calibration complete. Press 'esc' to return to menu\n\r"); |
benkatz | 44:8040fa2fcb0d | 321 | drv.disable_gd(); |
benkatz | 47:e1196a851f76 | 322 | //gpio.enable->write(0); |
benkatz | 23:2adf23ee0305 | 323 | state_change = 0; |
benkatz | 23:2adf23ee0305 | 324 | } |
benkatz | 23:2adf23ee0305 | 325 | |
benkatz | 23:2adf23ee0305 | 326 | void print_encoder(void){ |
bdring | 54:3e056b097c52 | 327 | cond_printf(" Mechanical Angle: %f Electrical Angle: %f Raw: %d\n\r", spi.GetMechPosition(), spi.GetElecPosition(), spi.GetRawPosition()); |
bdring | 54:3e056b097c52 | 328 | //cond_printf("%d\n\r", spi.GetRawPosition()); |
benkatz | 47:e1196a851f76 | 329 | wait(.001); |
benkatz | 22:60276ba87ac6 | 330 | } |
benkatz | 20:bf9ea5125d52 | 331 | |
benkatz | 23:2adf23ee0305 | 332 | /// Current Sampling Interrupt /// |
benkatz | 23:2adf23ee0305 | 333 | /// This runs at 40 kHz, regardless of of the mode the controller is in /// |
benkatz | 2:8724412ad628 | 334 | extern "C" void TIM1_UP_TIM10_IRQHandler(void) { |
benkatz | 2:8724412ad628 | 335 | if (TIM1->SR & TIM_SR_UIF ) { |
benkatz | 23:2adf23ee0305 | 336 | |
benkatz | 23:2adf23ee0305 | 337 | ///Sample current always /// |
benkatz | 25:f5741040c4bb | 338 | ADC1->CR2 |= 0x40000000; // Begin sample and conversion |
benkatz | 22:60276ba87ac6 | 339 | //volatile int delay; |
benkatz | 20:bf9ea5125d52 | 340 | //for (delay = 0; delay < 55; delay++); |
benkatz | 45:26801179208e | 341 | |
benkatz | 47:e1196a851f76 | 342 | spi.Sample(DT); // sample position sensor |
benkatz | 37:c0f352d6e8e3 | 343 | controller.adc2_raw = ADC2->DR; // Read ADC Data Registers |
benkatz | 23:2adf23ee0305 | 344 | controller.adc1_raw = ADC1->DR; |
benkatz | 37:c0f352d6e8e3 | 345 | controller.adc3_raw = ADC3->DR; |
benkatz | 37:c0f352d6e8e3 | 346 | controller.theta_elec = spi.GetElecPosition(); |
benkatz | 37:c0f352d6e8e3 | 347 | controller.theta_mech = (1.0f/GR)*spi.GetMechPosition(); |
benkatz | 37:c0f352d6e8e3 | 348 | controller.dtheta_mech = (1.0f/GR)*spi.GetMechVelocity(); |
benkatz | 37:c0f352d6e8e3 | 349 | controller.dtheta_elec = spi.GetElecVelocity(); |
benkatz | 51:6cd89bd6fcaa | 350 | controller.v_bus = 0.95f*controller.v_bus + 0.05f*((float)controller.adc3_raw)*V_SCALE; //filter the dc link voltage measurement |
benkatz | 23:2adf23ee0305 | 351 | /// |
annhandt09 | 57:c26b0093783b | 352 | timeSche = timeSche +1 ; |
benkatz | 23:2adf23ee0305 | 353 | /// Check state machine state, and run the appropriate function /// |
benkatz | 23:2adf23ee0305 | 354 | switch(state){ |
benkatz | 37:c0f352d6e8e3 | 355 | case REST_MODE: // Do nothing |
benkatz | 23:2adf23ee0305 | 356 | if(state_change){ |
benkatz | 23:2adf23ee0305 | 357 | enter_menu_state(); |
benkatz | 23:2adf23ee0305 | 358 | } |
benkatz | 23:2adf23ee0305 | 359 | break; |
benkatz | 22:60276ba87ac6 | 360 | |
benkatz | 23:2adf23ee0305 | 361 | case CALIBRATION_MODE: // Run encoder calibration procedure |
benkatz | 23:2adf23ee0305 | 362 | if(state_change){ |
benkatz | 23:2adf23ee0305 | 363 | calibrate(); |
benkatz | 23:2adf23ee0305 | 364 | } |
benkatz | 23:2adf23ee0305 | 365 | break; |
benkatz | 23:2adf23ee0305 | 366 | |
benkatz | 26:2b865c00d7e9 | 367 | case MOTOR_MODE: // Run torque control |
benkatz | 25:f5741040c4bb | 368 | if(state_change){ |
annhandt09 | 59:568e7be5232f | 369 | controller.p_des = controller.theta_mech - (controller.t_ff / controller.kp) ; |
benkatz | 25:f5741040c4bb | 370 | enter_torque_mode(); |
benkatz | 28:8c7e29f719c5 | 371 | count = 0; |
benkatz | 25:f5741040c4bb | 372 | } |
benkatz | 28:8c7e29f719c5 | 373 | else{ |
benkatz | 37:c0f352d6e8e3 | 374 | /* |
benkatz | 37:c0f352d6e8e3 | 375 | if(controller.v_bus>28.0f){ //Turn of gate drive if bus voltage is too high, to prevent FETsplosion if the bus is cut during regen |
benkatz | 47:e1196a851f76 | 376 | gpio. |
benkatz | 47:e1196a851f76 | 377 | ->write(0); |
benkatz | 37:c0f352d6e8e3 | 378 | controller.ovp_flag = 1; |
benkatz | 37:c0f352d6e8e3 | 379 | state = REST_MODE; |
benkatz | 37:c0f352d6e8e3 | 380 | state_change = 1; |
bdring | 54:3e056b097c52 | 381 | cond_printf("OVP Triggered!\n\r"); |
benkatz | 37:c0f352d6e8e3 | 382 | } |
benkatz | 37:c0f352d6e8e3 | 383 | */ |
benkatz | 37:c0f352d6e8e3 | 384 | |
benkatz | 28:8c7e29f719c5 | 385 | if((controller.timeout > CAN_TIMEOUT) && (CAN_TIMEOUT > 0)){ |
benkatz | 28:8c7e29f719c5 | 386 | controller.i_d_ref = 0; |
benkatz | 28:8c7e29f719c5 | 387 | controller.i_q_ref = 0; |
benkatz | 37:c0f352d6e8e3 | 388 | controller.kp = 0; |
benkatz | 37:c0f352d6e8e3 | 389 | controller.kd = 0; |
benkatz | 37:c0f352d6e8e3 | 390 | controller.t_ff = 0; |
benkatz | 28:8c7e29f719c5 | 391 | } |
benkatz | 47:e1196a851f76 | 392 | |
benkatz | 50:ba72df25d10f | 393 | torque_control(&controller); |
benkatz | 49:83d83040ea51 | 394 | commutate(&controller, &observer, &gpio, controller.theta_elec); // Run current loop |
benkatz | 49:83d83040ea51 | 395 | |
benkatz | 49:83d83040ea51 | 396 | controller.timeout++; |
benkatz | 49:83d83040ea51 | 397 | count++; |
benkatz | 37:c0f352d6e8e3 | 398 | |
benkatz | 37:c0f352d6e8e3 | 399 | } |
benkatz | 23:2adf23ee0305 | 400 | break; |
benkatz | 23:2adf23ee0305 | 401 | case SETUP_MODE: |
benkatz | 23:2adf23ee0305 | 402 | if(state_change){ |
benkatz | 24:58c2d7571207 | 403 | enter_setup_state(); |
benkatz | 23:2adf23ee0305 | 404 | } |
benkatz | 23:2adf23ee0305 | 405 | break; |
benkatz | 23:2adf23ee0305 | 406 | case ENCODER_MODE: |
benkatz | 23:2adf23ee0305 | 407 | print_encoder(); |
benkatz | 23:2adf23ee0305 | 408 | break; |
benkatz | 37:c0f352d6e8e3 | 409 | } |
benkatz | 2:8724412ad628 | 410 | } |
benkatz | 23:2adf23ee0305 | 411 | TIM1->SR = 0x0; // reset the status register |
benkatz | 2:8724412ad628 | 412 | } |
benkatz | 0:4e1c4df6aabd | 413 | |
benkatz | 25:f5741040c4bb | 414 | |
benkatz | 24:58c2d7571207 | 415 | char cmd_val[8] = {0}; |
benkatz | 24:58c2d7571207 | 416 | char cmd_id = 0; |
benkatz | 25:f5741040c4bb | 417 | char char_count = 0; |
benkatz | 24:58c2d7571207 | 418 | |
benkatz | 25:f5741040c4bb | 419 | /// Manage state machine with commands from serial terminal or configurator gui /// |
benkatz | 25:f5741040c4bb | 420 | /// Called when data received over serial /// |
bdring | 54:3e056b097c52 | 421 | |
benkatz | 23:2adf23ee0305 | 422 | void serial_interrupt(void){ |
bdring | 54:3e056b097c52 | 423 | while(pc->readable()){ |
bdring | 54:3e056b097c52 | 424 | char c = pc->getc(); |
benkatz | 25:f5741040c4bb | 425 | if(c == 27){ |
benkatz | 25:f5741040c4bb | 426 | state = REST_MODE; |
benkatz | 25:f5741040c4bb | 427 | state_change = 1; |
benkatz | 25:f5741040c4bb | 428 | char_count = 0; |
benkatz | 25:f5741040c4bb | 429 | cmd_id = 0; |
benkatz | 37:c0f352d6e8e3 | 430 | gpio.led->write(0);; |
benkatz | 25:f5741040c4bb | 431 | for(int i = 0; i<8; i++){cmd_val[i] = 0;} |
benkatz | 25:f5741040c4bb | 432 | } |
annhandt09 | 59:568e7be5232f | 433 | if(c == 't'){cond_printf("Pos: %.3f Vel: %.3f Cur: %.3f\r\n", controller.theta_mech, controller.theta_elec, controller.i_q_filt*KT_OUT);} |
annhandt09 | 59:568e7be5232f | 434 | else if(c == 'y'){printFirmwareVer();} |
benkatz | 24:58c2d7571207 | 435 | if(state == REST_MODE){ |
benkatz | 23:2adf23ee0305 | 436 | switch (c){ |
benkatz | 23:2adf23ee0305 | 437 | case 'c': |
benkatz | 23:2adf23ee0305 | 438 | state = CALIBRATION_MODE; |
benkatz | 23:2adf23ee0305 | 439 | state_change = 1; |
benkatz | 23:2adf23ee0305 | 440 | break; |
benkatz | 26:2b865c00d7e9 | 441 | case 'm': |
benkatz | 26:2b865c00d7e9 | 442 | state = MOTOR_MODE; |
benkatz | 23:2adf23ee0305 | 443 | state_change = 1; |
benkatz | 23:2adf23ee0305 | 444 | break; |
benkatz | 23:2adf23ee0305 | 445 | case 'e': |
benkatz | 23:2adf23ee0305 | 446 | state = ENCODER_MODE; |
benkatz | 23:2adf23ee0305 | 447 | state_change = 1; |
bdring | 53:349304b6d937 | 448 | break; |
benkatz | 23:2adf23ee0305 | 449 | case 's': |
benkatz | 23:2adf23ee0305 | 450 | state = SETUP_MODE; |
benkatz | 23:2adf23ee0305 | 451 | state_change = 1; |
benkatz | 23:2adf23ee0305 | 452 | break; |
benkatz | 37:c0f352d6e8e3 | 453 | case 'z': |
benkatz | 37:c0f352d6e8e3 | 454 | spi.SetMechOffset(0); |
benkatz | 47:e1196a851f76 | 455 | spi.Sample(DT); |
benkatz | 37:c0f352d6e8e3 | 456 | wait_us(20); |
benkatz | 37:c0f352d6e8e3 | 457 | M_OFFSET = spi.GetMechPosition(); |
benkatz | 37:c0f352d6e8e3 | 458 | if (!prefs.ready()) prefs.open(); |
benkatz | 37:c0f352d6e8e3 | 459 | prefs.flush(); // Write new prefs to flash |
benkatz | 37:c0f352d6e8e3 | 460 | prefs.close(); |
benkatz | 37:c0f352d6e8e3 | 461 | prefs.load(); |
benkatz | 37:c0f352d6e8e3 | 462 | spi.SetMechOffset(M_OFFSET); |
bdring | 54:3e056b097c52 | 463 | cond_printf("\n\r Saved new zero position: %.4f\n\r\n\r", M_OFFSET); |
benkatz | 37:c0f352d6e8e3 | 464 | |
benkatz | 37:c0f352d6e8e3 | 465 | break; |
benkatz | 37:c0f352d6e8e3 | 466 | } |
benkatz | 37:c0f352d6e8e3 | 467 | |
benkatz | 24:58c2d7571207 | 468 | } |
benkatz | 24:58c2d7571207 | 469 | else if(state == SETUP_MODE){ |
benkatz | 25:f5741040c4bb | 470 | if(c == 13){ |
benkatz | 24:58c2d7571207 | 471 | switch (cmd_id){ |
benkatz | 24:58c2d7571207 | 472 | case 'b': |
benkatz | 24:58c2d7571207 | 473 | I_BW = fmaxf(fminf(atof(cmd_val), 2000.0f), 100.0f); |
benkatz | 24:58c2d7571207 | 474 | break; |
benkatz | 24:58c2d7571207 | 475 | case 'i': |
benkatz | 24:58c2d7571207 | 476 | CAN_ID = atoi(cmd_val); |
benkatz | 24:58c2d7571207 | 477 | break; |
benkatz | 26:2b865c00d7e9 | 478 | case 'm': |
benkatz | 26:2b865c00d7e9 | 479 | CAN_MASTER = atoi(cmd_val); |
benkatz | 26:2b865c00d7e9 | 480 | break; |
benkatz | 24:58c2d7571207 | 481 | case 'l': |
benkatz | 51:6cd89bd6fcaa | 482 | I_MAX = fmaxf(fminf(atof(cmd_val), 40.0f), 0.0f); |
benkatz | 51:6cd89bd6fcaa | 483 | break; |
benkatz | 51:6cd89bd6fcaa | 484 | case 'f': |
benkatz | 51:6cd89bd6fcaa | 485 | I_FW_MAX = fmaxf(fminf(atof(cmd_val), 33.0f), 0.0f); |
benkatz | 24:58c2d7571207 | 486 | break; |
benkatz | 28:8c7e29f719c5 | 487 | case 't': |
benkatz | 28:8c7e29f719c5 | 488 | CAN_TIMEOUT = atoi(cmd_val); |
benkatz | 28:8c7e29f719c5 | 489 | break; |
benkatz | 24:58c2d7571207 | 490 | default: |
bdring | 54:3e056b097c52 | 491 | cond_printf("\n\r '%c' Not a valid command prefix\n\r\n\r", cmd_id); |
benkatz | 24:58c2d7571207 | 492 | break; |
benkatz | 24:58c2d7571207 | 493 | } |
benkatz | 24:58c2d7571207 | 494 | |
benkatz | 24:58c2d7571207 | 495 | if (!prefs.ready()) prefs.open(); |
benkatz | 24:58c2d7571207 | 496 | prefs.flush(); // Write new prefs to flash |
benkatz | 24:58c2d7571207 | 497 | prefs.close(); |
benkatz | 24:58c2d7571207 | 498 | prefs.load(); |
benkatz | 24:58c2d7571207 | 499 | state_change = 1; |
benkatz | 24:58c2d7571207 | 500 | char_count = 0; |
benkatz | 24:58c2d7571207 | 501 | cmd_id = 0; |
benkatz | 24:58c2d7571207 | 502 | for(int i = 0; i<8; i++){cmd_val[i] = 0;} |
benkatz | 24:58c2d7571207 | 503 | } |
benkatz | 24:58c2d7571207 | 504 | else{ |
benkatz | 24:58c2d7571207 | 505 | if(char_count == 0){cmd_id = c;} |
benkatz | 24:58c2d7571207 | 506 | else{ |
benkatz | 24:58c2d7571207 | 507 | cmd_val[char_count-1] = c; |
benkatz | 24:58c2d7571207 | 508 | |
benkatz | 24:58c2d7571207 | 509 | } |
bdring | 54:3e056b097c52 | 510 | pc->putc(c); |
benkatz | 24:58c2d7571207 | 511 | char_count++; |
benkatz | 23:2adf23ee0305 | 512 | } |
benkatz | 23:2adf23ee0305 | 513 | } |
benkatz | 24:58c2d7571207 | 514 | else if (state == ENCODER_MODE){ |
benkatz | 24:58c2d7571207 | 515 | switch (c){ |
benkatz | 24:58c2d7571207 | 516 | case 27: |
benkatz | 24:58c2d7571207 | 517 | state = REST_MODE; |
benkatz | 24:58c2d7571207 | 518 | state_change = 1; |
benkatz | 24:58c2d7571207 | 519 | break; |
benkatz | 24:58c2d7571207 | 520 | } |
benkatz | 24:58c2d7571207 | 521 | } |
benkatz | 49:83d83040ea51 | 522 | else if (state == MOTOR_MODE){ |
benkatz | 49:83d83040ea51 | 523 | switch (c){ |
benkatz | 49:83d83040ea51 | 524 | case 'd': |
benkatz | 49:83d83040ea51 | 525 | controller.i_q_ref = 0; |
benkatz | 49:83d83040ea51 | 526 | controller.i_d_ref = 0; |
bdring | 53:349304b6d937 | 527 | break; |
bdring | 53:349304b6d937 | 528 | case 'f': // move forward |
annhandt09 | 57:c26b0093783b | 529 | controller.p_des += 0.02f; |
bdring | 54:3e056b097c52 | 530 | cond_printf("p_des: %.3f\r\n", controller.p_des); |
bdring | 53:349304b6d937 | 531 | break; |
annhandt09 | 55:fee62d8fd8fb | 532 | case 'b': // move back |
annhandt09 | 57:c26b0093783b | 533 | controller.p_des -= 0.02f; |
bdring | 54:3e056b097c52 | 534 | cond_printf("p_des: %.3f\r\n", controller.p_des); |
bdring | 53:349304b6d937 | 535 | break; |
bdring | 53:349304b6d937 | 536 | case 'p': // show posiiton |
annhandt09 | 57:c26b0093783b | 537 | cond_printf("Kp: %.3f Kd: %.3f ff: %.3f\r\n", controller.kp, controller.kd, controller.t_ff); |
bdring | 53:349304b6d937 | 538 | break; |
annhandt09 | 55:fee62d8fd8fb | 539 | case 's': // show posiiton |
annhandt09 | 55:fee62d8fd8fb | 540 | pack_reply(&txMsg, 0, 0 ,1); |
annhandt09 | 55:fee62d8fd8fb | 541 | can.write(txMsg); |
annhandt09 | 55:fee62d8fd8fb | 542 | break; |
benkatz | 49:83d83040ea51 | 543 | } |
bdring | 53:349304b6d937 | 544 | |
benkatz | 49:83d83040ea51 | 545 | } |
benkatz | 24:58c2d7571207 | 546 | |
benkatz | 24:58c2d7571207 | 547 | } |
benkatz | 22:60276ba87ac6 | 548 | } |
annhandt09 | 58:fb799e99a5f7 | 549 | /* |
annhandt09 | 58:fb799e99a5f7 | 550 | Khi |
annhandt09 | 58:fb799e99a5f7 | 551 | Controller.P_des = Controller.theta_mech + ( - 0.710) |
bdring | 54:3e056b097c52 | 552 | |
annhandt09 | 58:fb799e99a5f7 | 553 | -0.710 là ??? |
annhandt09 | 58:fb799e99a5f7 | 554 | |
annhandt09 | 58:fb799e99a5f7 | 555 | -> khi enable motor set controller.p_des = |
annhandt09 | 58:fb799e99a5f7 | 556 | |
annhandt09 | 58:fb799e99a5f7 | 557 | |
annhandt09 | 58:fb799e99a5f7 | 558 | |
annhandt09 | 58:fb799e99a5f7 | 559 | |
annhandt09 | 58:fb799e99a5f7 | 560 | */ |
annhandt09 | 58:fb799e99a5f7 | 561 | |
benkatz | 0:4e1c4df6aabd | 562 | |
benkatz | 0:4e1c4df6aabd | 563 | int main() { |
benkatz | 20:bf9ea5125d52 | 564 | controller.v_bus = V_BUS; |
benkatz | 22:60276ba87ac6 | 565 | controller.mode = 0; |
benkatz | 23:2adf23ee0305 | 566 | Init_All_HW(&gpio); // Setup PWM, ADC, GPIO |
benkatz | 44:8040fa2fcb0d | 567 | wait(.1); |
benkatz | 44:8040fa2fcb0d | 568 | |
benkatz | 44:8040fa2fcb0d | 569 | gpio.enable->write(1); |
benkatz | 44:8040fa2fcb0d | 570 | wait_us(100); |
benkatz | 45:26801179208e | 571 | drv.calibrate(); |
benkatz | 45:26801179208e | 572 | wait_us(100); |
benkatz | 44:8040fa2fcb0d | 573 | drv.write_DCR(0x0, 0x0, 0x0, PWM_MODE_3X, 0x0, 0x0, 0x0, 0x0, 0x1); |
benkatz | 44:8040fa2fcb0d | 574 | wait_us(100); |
benkatz | 46:2d4b1dafcfe3 | 575 | drv.write_CSACR(0x0, 0x1, 0x0, CSA_GAIN_40, 0x0, 0x0, 0x0, 0x0, SEN_LVL_1_0); |
benkatz | 44:8040fa2fcb0d | 576 | wait_us(100); |
benkatz | 49:83d83040ea51 | 577 | drv.write_OCPCR(TRETRY_4MS, DEADTIME_200NS, OCP_RETRY, OCP_DEG_8US, VDS_LVL_1_88); |
benkatz | 45:26801179208e | 578 | |
benkatz | 45:26801179208e | 579 | //drv.enable_gd(); |
benkatz | 44:8040fa2fcb0d | 580 | zero_current(&controller.adc1_offset, &controller.adc2_offset); // Measure current sensor zero-offset |
benkatz | 47:e1196a851f76 | 581 | drv.disable_gd(); |
benkatz | 20:bf9ea5125d52 | 582 | |
benkatz | 9:d7eb815cb057 | 583 | wait(.1); |
benkatz | 44:8040fa2fcb0d | 584 | /* |
benkatz | 26:2b865c00d7e9 | 585 | gpio.enable->write(1); |
benkatz | 26:2b865c00d7e9 | 586 | TIM1->CCR3 = 0x708*(1.0f); // Write duty cycles |
benkatz | 26:2b865c00d7e9 | 587 | TIM1->CCR2 = 0x708*(1.0f); |
benkatz | 26:2b865c00d7e9 | 588 | TIM1->CCR1 = 0x708*(1.0f); |
benkatz | 26:2b865c00d7e9 | 589 | gpio.enable->write(0); |
benkatz | 44:8040fa2fcb0d | 590 | */ |
benkatz | 23:2adf23ee0305 | 591 | reset_foc(&controller); // Reset current controller |
benkatz | 48:74a40481740c | 592 | reset_observer(&observer); // Reset observer |
benkatz | 26:2b865c00d7e9 | 593 | TIM1->CR1 ^= TIM_CR1_UDIS; |
benkatz | 26:2b865c00d7e9 | 594 | //TIM1->CR1 |= TIM_CR1_UDIS; //enable interrupt |
benkatz | 20:bf9ea5125d52 | 595 | |
benkatz | 20:bf9ea5125d52 | 596 | wait(.1); |
benkatz | 37:c0f352d6e8e3 | 597 | NVIC_SetPriority(TIM1_UP_TIM10_IRQn, 2); // commutation > communication |
benkatz | 43:dfb72608639c | 598 | |
benkatz | 37:c0f352d6e8e3 | 599 | NVIC_SetPriority(CAN1_RX0_IRQn, 3); |
benkatz | 26:2b865c00d7e9 | 600 | can.filter(CAN_ID<<21, 0xFFE00004, CANStandard, 0); |
benkatz | 43:dfb72608639c | 601 | |
benkatz | 28:8c7e29f719c5 | 602 | txMsg.id = CAN_MASTER; |
benkatz | 28:8c7e29f719c5 | 603 | txMsg.len = 6; |
benkatz | 26:2b865c00d7e9 | 604 | rxMsg.len = 8; |
benkatz | 43:dfb72608639c | 605 | can.attach(&onMsgReceived); // attach 'CAN receive-complete' interrupt handler |
benkatz | 23:2adf23ee0305 | 606 | |
benkatz | 48:74a40481740c | 607 | // If preferences haven't been user configured yet, set defaults |
benkatz | 25:f5741040c4bb | 608 | prefs.load(); // Read flash |
benkatz | 37:c0f352d6e8e3 | 609 | if(isnan(E_OFFSET)){E_OFFSET = 0.0f;} |
benkatz | 37:c0f352d6e8e3 | 610 | if(isnan(M_OFFSET)){M_OFFSET = 0.0f;} |
benkatz | 48:74a40481740c | 611 | if(isnan(I_BW) || I_BW==-1){I_BW = 1000;} |
benkatz | 51:6cd89bd6fcaa | 612 | if(isnan(I_MAX) || I_MAX ==-1){I_MAX=40;} |
benkatz | 51:6cd89bd6fcaa | 613 | if(isnan(I_FW_MAX) || I_FW_MAX ==-1){I_FW_MAX=0;} |
benkatz | 48:74a40481740c | 614 | if(isnan(CAN_ID) || CAN_ID==-1){CAN_ID = 1;} |
benkatz | 48:74a40481740c | 615 | if(isnan(CAN_MASTER) || CAN_MASTER==-1){CAN_MASTER = 0;} |
benkatz | 48:74a40481740c | 616 | if(isnan(CAN_TIMEOUT) || CAN_TIMEOUT==-1){CAN_TIMEOUT = 0;} |
benkatz | 25:f5741040c4bb | 617 | spi.SetElecOffset(E_OFFSET); // Set position sensor offset |
benkatz | 37:c0f352d6e8e3 | 618 | spi.SetMechOffset(M_OFFSET); |
benkatz | 23:2adf23ee0305 | 619 | int lut[128] = {0}; |
benkatz | 23:2adf23ee0305 | 620 | memcpy(&lut, &ENCODER_LUT, sizeof(lut)); |
benkatz | 25:f5741040c4bb | 621 | spi.WriteLUT(lut); // Set potision sensor nonlinearity lookup table |
benkatz | 45:26801179208e | 622 | init_controller_params(&controller); |
benkatz | 45:26801179208e | 623 | |
bdring | 54:3e056b097c52 | 624 | |
annhandt09 | 57:c26b0093783b | 625 | set_io_mode(IO_MODE_SERIAL); |
annhandt09 | 57:c26b0093783b | 626 | //set_io_mode(IO_MODE_STEP_DIR); |
annhandt09 | 58:fb799e99a5f7 | 627 | wait_us(1000); |
annhandt09 | 58:fb799e99a5f7 | 628 | printFirmwareVer(); |
benkatz | 23:2adf23ee0305 | 629 | state_change = 1; |
annhandt09 | 57:c26b0093783b | 630 | timeSche = 0 ; |
benkatz | 0:4e1c4df6aabd | 631 | while(1) { |
annhandt09 | 57:c26b0093783b | 632 | drv.print_faults(); |
annhandt09 | 57:c26b0093783b | 633 | //sendSche(); |
annhandt09 | 59:568e7be5232f | 634 | wait(.1); |
benkatz | 0:4e1c4df6aabd | 635 | } |
benkatz | 0:4e1c4df6aabd | 636 | } |