https://vesc-project.com/node/281
In VESC, the packet(payload) structure on UART communication
The packet is a uint8_t byte stream.
First byte(header):
0x02 for payload length of 256 bytes, the next one byte is for the payload length
0x03 for > 256 byte payload length, the next 2 bytes for the payload length
Payload(communication command + data)
The following 2 bytes after the payload are the checksum.
The byte stream it terminated with a 0x03 (footer).
"header(2 | 3) + 1-2 byte length + 2 byte crc + footer(3)"
The following function, packet_process_byte() shows how to process a packet stream.
packet.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | void packet_process_byte(uint8_t rx_data, int handler_num) { switch (handler_states[handler_num].rx_state) { case 0: if (rx_data == 2) { // 1 byte PL len handler_states[handler_num].rx_state += 2; handler_states[handler_num].rx_timeout = PACKET_RX_TIMEOUT; handler_states[handler_num].rx_data_ptr = 0; handler_states[handler_num].payload_length = 0; } else if (rx_data == 3) { // 2 byte PL len handler_states[handler_num].rx_state++; handler_states[handler_num].rx_timeout = PACKET_RX_TIMEOUT; handler_states[handler_num].rx_data_ptr = 0; handler_states[handler_num].payload_length = 0; } else { handler_states[handler_num].rx_state = 0; } break; case 1: handler_states[handler_num].payload_length = (unsigned int)rx_data << 8; handler_states[handler_num].rx_state++; handler_states[handler_num].rx_timeout = PACKET_RX_TIMEOUT; break; case 2: handler_states[handler_num].payload_length |= (unsigned int)rx_data; if (handler_states[handler_num].payload_length > 0 && handler_states[handler_num].payload_length <= PACKET_MAX_PL_LEN) { handler_states[handler_num].rx_state++; handler_states[handler_num].rx_timeout = PACKET_RX_TIMEOUT; } else { handler_states[handler_num].rx_state = 0; } break; case 3: handler_states[handler_num].rx_buffer[handler_states[handler_num].rx_data_ptr++] = rx_data; if (handler_states[handler_num].rx_data_ptr == handler_states[handler_num].payload_length) { handler_states[handler_num].rx_state++; } handler_states[handler_num].rx_timeout = PACKET_RX_TIMEOUT; break; case 4: handler_states[handler_num].crc_high = rx_data; handler_states[handler_num].rx_state++; handler_states[handler_num].rx_timeout = PACKET_RX_TIMEOUT; break; case 5: handler_states[handler_num].crc_low = rx_data; handler_states[handler_num].rx_state++; handler_states[handler_num].rx_timeout = PACKET_RX_TIMEOUT; break; case 6: if (rx_data == 3) { if (crc16(handler_states[handler_num].rx_buffer, handler_states[handler_num].payload_length) == ((unsigned short)handler_states[handler_num].crc_high << 8 | (unsigned short)handler_states[handler_num].crc_low)) { // Packet received! if (handler_states[handler_num].process_func) { handler_states[handler_num].process_func(handler_states[handler_num].rx_buffer, handler_states[handler_num].payload_length); } } } handler_states[handler_num].rx_state = 0; break; default: handler_states[handler_num].rx_state = 0; break; } } | cs |
First byte of payload is command. All commands(38) supported by VESC firmware is shown bellow:
datatypes.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | // Communication commands typedef enum { COMM_FW_VERSION = 0, COMM_JUMP_TO_BOOTLOADER, COMM_ERASE_NEW_APP, COMM_WRITE_NEW_APP_DATA, COMM_GET_VALUES, COMM_SET_DUTY, COMM_SET_CURRENT, COMM_SET_CURRENT_BRAKE, COMM_SET_RPM, COMM_SET_POS, COMM_SET_HANDBRAKE, COMM_SET_DETECT, COMM_SET_SERVO_POS, COMM_SET_MCCONF, COMM_GET_MCCONF, COMM_GET_MCCONF_DEFAULT, COMM_SET_APPCONF, COMM_GET_APPCONF, COMM_GET_APPCONF_DEFAULT, COMM_SAMPLE_PRINT, COMM_TERMINAL_CMD, COMM_PRINT, COMM_ROTOR_POSITION, COMM_EXPERIMENT_SAMPLE, COMM_DETECT_MOTOR_PARAM, COMM_DETECT_MOTOR_R_L, COMM_DETECT_MOTOR_FLUX_LINKAGE, COMM_DETECT_ENCODER, COMM_DETECT_HALL_FOC, COMM_REBOOT, COMM_ALIVE, COMM_GET_DECODED_PPM, COMM_GET_DECODED_ADC, COMM_GET_DECODED_CHUK, COMM_FORWARD_CAN, COMM_SET_CHUCK_DATA, COMM_CUSTOM_APP_DATA, COMM_NRF_START_PAIRING } COMM_PACKET_ID; | cs |
The processing for each command is excuted by 'commands_process_packet()' function in command.h and the following shows an example for 'COMM_GET_VALUES' command case.
commands.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | case COMM_GET_VALUES: ind = 0; send_buffer[ind++] = COMM_GET_VALUES; buffer_append_float16(send_buffer, mc_interface_temp_fet_filtered(), 1e1, &ind); buffer_append_float16(send_buffer, mc_interface_temp_motor_filtered(), 1e1, &ind); buffer_append_float32(send_buffer, mc_interface_read_reset_avg_motor_current(), 1e2, &ind); buffer_append_float32(send_buffer, mc_interface_read_reset_avg_input_current(), 1e2, &ind); buffer_append_float32(send_buffer, mc_interface_read_reset_avg_id(), 1e2, &ind); buffer_append_float32(send_buffer, mc_interface_read_reset_avg_iq(), 1e2, &ind); buffer_append_float16(send_buffer, mc_interface_get_duty_cycle_now(), 1e3, &ind); buffer_append_float32(send_buffer, mc_interface_get_rpm(), 1e0, &ind); buffer_append_float16(send_buffer, GET_INPUT_VOLTAGE(), 1e1, &ind); buffer_append_float32(send_buffer, mc_interface_get_amp_hours(false), 1e4, &ind); buffer_append_float32(send_buffer, mc_interface_get_amp_hours_charged(false), 1e4, &ind); buffer_append_float32(send_buffer, mc_interface_get_watt_hours(false), 1e4, &ind); buffer_append_float32(send_buffer, mc_interface_get_watt_hours_charged(false), 1e4, &ind); buffer_append_int32(send_buffer, mc_interface_get_tachometer_value(false), &ind); buffer_append_int32(send_buffer, mc_interface_get_tachometer_abs_value(false), &ind); send_buffer[ind++] = mc_interface_get_fault(); commands_send_packet(send_buffer, ind); break; | cs |
please refer to https://github.com/RollingGecko/VescUartControl
'Flight Controller 이해 > 전자속도제어기(ESC)' 카테고리의 다른 글
Mini VESC (v0.4) 하드웨어 회로도 (0) | 2018.02.17 |
---|---|
Mini VESC (v0.4) 하드웨어 스펙 (0) | 2018.02.17 |
VESC 6 하드웨어(v6.4) 회로도 (1) | 2018.02.01 |
VESC 하드웨어(v4.12) 회로도 (0) | 2018.02.01 |
VESC 하드웨어(v4.12)의 부품리스트 (0) | 2018.01.31 |