You are here

Getting IMU Data over UART

8 posts / 0 new
Last post
Mido
Offline
Last seen: 2 months 2 weeks ago
VESC Original
Joined: 2021-04-13 11:17
Posts: 6
Getting IMU Data over UART

Hello,

Recently i got a VESC 6 for a diy project, and now i can see that it has a built-in imu so i was thinking there must be a way to get the data from this imu via UART comm. I can successfully get other infos displayed on my Serial monitor since i m using an esp32. But can not figure out a way to do it for the IMU.

I would like to thank you in advance for your help.

vadicus
Offline
Last seen: 1 month 3 weeks ago
VESC Free
Joined: 2018-08-17 07:26
Posts: 431

The same way you get anything else, just send the COMM_GET_IMU_DATA command and process the response.

The format of the response is below.

 

https://github.com/vedderb/bldc/blob/31a313129ded1d355a921c572854820921d...

case COMM_GET_IMU_DATA: {
  int32_t ind = 0;
  uint8_t send_buffer[70];
  send_buffer[ind++] = packet_id;
   
  int32_t ind2 = 0;
  uint32_t mask = buffer_get_uint16(data, &ind2);
   
  float rpy[3], acc[3], gyro[3], mag[3], q[4];
  imu_get_rpy(rpy);
  imu_get_accel(acc);
  imu_get_gyro(gyro);
  imu_get_mag(mag);
  imu_get_quaternions(q);
   
  buffer_append_uint16(send_buffer, mask, &ind);
   
  if (mask & ((uint32_t)1 << 0)) {
  buffer_append_float32_auto(send_buffer, rpy[0], &ind);
  }
  if (mask & ((uint32_t)1 << 1)) {
  buffer_append_float32_auto(send_buffer, rpy[1], &ind);
  }
  if (mask & ((uint32_t)1 << 2)) {
  buffer_append_float32_auto(send_buffer, rpy[2], &ind);
  }
   
  if (mask & ((uint32_t)1 << 3)) {
  buffer_append_float32_auto(send_buffer, acc[0], &ind);
  }
  if (mask & ((uint32_t)1 << 4)) {
  buffer_append_float32_auto(send_buffer, acc[1], &ind);
  }
  if (mask & ((uint32_t)1 << 5)) {
  buffer_append_float32_auto(send_buffer, acc[2], &ind);
  }
   
  if (mask & ((uint32_t)1 << 6)) {
  buffer_append_float32_auto(send_buffer, gyro[0], &ind);
  }
  if (mask & ((uint32_t)1 << 7)) {
  buffer_append_float32_auto(send_buffer, gyro[1], &ind);
  }
  if (mask & ((uint32_t)1 << 8)) {
  buffer_append_float32_auto(send_buffer, gyro[2], &ind);
  }
   
  if (mask & ((uint32_t)1 << 9)) {
  buffer_append_float32_auto(send_buffer, mag[0], &ind);
  }
  if (mask & ((uint32_t)1 << 10)) {
  buffer_append_float32_auto(send_buffer, mag[1], &ind);
  }
  if (mask & ((uint32_t)1 << 11)) {
  buffer_append_float32_auto(send_buffer, mag[2], &ind);
  }
   
  if (mask & ((uint32_t)1 << 12)) {
  buffer_append_float32_auto(send_buffer, q[0], &ind);
  }
  if (mask & ((uint32_t)1 << 13)) {
  buffer_append_float32_auto(send_buffer, q[1], &ind);
  }
  if (mask & ((uint32_t)1 << 14)) {
  buffer_append_float32_auto(send_buffer, q[2], &ind);
  }
  if (mask & ((uint32_t)1 << 15)) {
  buffer_append_float32_auto(send_buffer, q[3], &ind);
  }
   
  reply_func(send_buffer, ind);
  } break;

 

 

 

 

 

NextGen FOC High voltage 144v/34s, 30kw (https://vesc-project.com/node/1477)

Mido
Offline
Last seen: 2 months 2 weeks ago
VESC Original
Joined: 2021-04-13 11:17
Posts: 6

Thanks vadicus for your help. I am using this library : https://github.com/Peemouse/VescUart

And i already sent the command i get a response of 35 length and this what i ve done to process the info : 

		case COMM_GET_IMU_DATA:
			ind1 = 0;
			imudata.roll = buffer_get_int32(message, &ind1);
			imudata.pitch = buffer_get_int32(message, &ind1);
			imudata.yaw = buffer_get_int32(message, &ind1);
			imudata.accX = buffer_get_int32(message, &ind1);
			imudata.accY = buffer_get_int32(message, &ind1);
			imudata.accZ = buffer_get_int32(message, &ind1);
			imudata.gyrX = buffer_get_int32(message, &ind1);
			imudata.gyrY = buffer_get_int32(message, &ind1);
			imudata.gyrZ = buffer_get_int32(message, &ind1);

but i still get wrong data. This is an example of the packet received : 2 35 65 88 229 60 155 182 179 190 108 139 169 63 132 176 0 189 122 0 0 63 28 64 0 0 0 0 0 63 126 72 77 184 239 203 26 90 209 3 0

Mido

Mido
Offline
Last seen: 2 months 2 weeks ago
VESC Original
Joined: 2021-04-13 11:17
Posts: 6

Also in the code of commands.c there is this line : imu_get_accel(acc); that memcpy the array of accel. I can not figure out how i can include it in my code too.

Mido

vadicus
Offline
Last seen: 1 month 3 weeks ago
VESC Free
Joined: 2018-08-17 07:26
Posts: 431

It looks like  imu_get_accel(acc), etc. functions simply load data first into arrays before sending it over UART: 

These rpy[3], acc[3], gyro[3], mag[3], q[4] tell you how many elements there are in each array. You don't need to do anything on the receiving for this specifically, you only care about parsing the data you are already getting correctly.

Then you can see the sequence each element is sent in. For example: 

buffer_append_float32_auto(send_buffer, gyro[0], &ind);
buffer_append_float32_auto(send_buffer, gyro[1], &ind);
buffer_append_float32_auto(send_buffer, gyro[2], &ind);

You would need to modify your default/outdated code in the uart library to map and interpret this data correctly. Don't forget about leading and trailing meta data (short/long message flag, length, and CRC) but I think the library is already handling that. I would verify though as it's old.

 

 

 

NextGen FOC High voltage 144v/34s, 30kw (https://vesc-project.com/node/1477)

Igor Shapovalov
Offline
Last seen: 1 year 2 months ago
Joined: 2023-02-02 14:22
Posts: 1

I had the same issue with getting IMU data over a UART. Finally, I've found out that we need to put COMM_GET_IMU_DATA (ID=65) and two bytes of "1" (xFFFF) in the send_buffer in order to get a proper data packet from a VESC. The reason for this is the logic of the function "commands_process_packet" (file "commands.c" in the bldc git repo) which processes requests to VESC from external devices. This function uses a 2-byte mask (which goes next to the ID of a processed packet) to process the case COMM_GET_IMU_DATA and puts values from the imu data structure when encounters "1" in the corresponding position of the mask.   

 

MrFobwatch
Offline
Last seen: 8 months 1 week ago
Joined: 2024-01-24 22:42
Posts: 2

Did anyone here have finished code for this they could share? I'm currently working on trying to extend this library: https://github.com/SolidGeek/VescUart to be able to process IMU data.

MrFobwatch
Offline
Last seen: 8 months 1 week ago
Joined: 2024-01-24 22:42
Posts: 2

I've since gotten my code to work. I opened a pull request to @SolidGeek 's Library but in the meantime it can be found at https://github.com/MrFobwatch/VescUart/tree/IMUdata