You are here

PYVESC UART Issues

14 posts / 0 new
Last post
goethe
Offline
Last seen: 9 months 4 weeks ago
Joined: 2017-12-15 14:54
Posts: 2
PYVESC UART Issues

Hi!

 

I'm new to VESC and have some troubles to get the right data when using PYVESC over UART. When I loop thru the GET_VALUE response package I get ok variable names but the data seems wrong. Could some one please make sense out of this?!

 

{'measurement': 'temp_mos1', 'fields': {'value': 27.0}}
{'measurement': 'watt_hours_charged', 'fields': {'value': 6.5535}}
{'measurement': 'temp_mos6', 'fields': {'value': 2.7}}
{'measurement': 'mc_fault_code', 'fields': {'value': b'B'}}
{'measurement': 'temp_mos5', 'fields': {'value': 0.0}}
{'measurement': 'amp_hours', 'fields': {'value': 117.9648}}
{'measurement': 'current_motor', 'fields': {'value': 655.35}}
{'measurement': 'temp_mos2', 'fields': {'value': -85.6}}
{'measurement': 'tachometer_abs', 'fields': {'value': 1661796352.0}}
{'measurement': 'tachometer', 'fields': {'value': -739835904.0}}
{'measurement': 'temp_mos3', 'fields': {'value': 0.0}}
{'measurement': 'temp_mos4', 'fields': {'value': 7.4}}
{'measurement': 'amp_hours_charged', 'fields': {'value': 0.0}}
{'measurement': 'v_in', 'fields': {'value': 0.0}}
{'measurement': 'current_in', 'fields': {'value': -47845.52}}
{'measurement': 'temp_pcb', 'fields': {'value': 0.0}}
{'measurement': 'rpm', 'fields': {'value': -249364175.0}}
{'measurement': 'duty_now', 'fields': {'value': -0.001}}
{'measurement': 'watt_hours', 'fields': {'value': 3722.4448}}

 

            while True:

                # Request the current measurement from the vesc
                ser.write(pyvesc.encode_request(GetValues))

                # Check if there is enough data back for a measurement
                if ser.in_waiting > 63:
                    (response, consumed) = pyvesc.decode(ser.read(63))

                    packets = []

                    for sensor, value in response.__dict__.items():
                        data = {}
                        data['measurement'] = sensor
                        data['fields'] = {}
                        data['fields']['value'] = value
                        packets.append(data)
                        print(data)

 

Cheers

Göran Jonasson

wdaehn
Offline
Last seen: 2 years 6 months ago
Joined: 2017-09-12 17:26
Posts: 65

In the VESC6 firmware the read response seem to have changed, in case the question is related to that. 

see https://github.com/vedderb/bldc/blob/master/commands.c

	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;

 

goethe
Offline
Last seen: 9 months 4 weeks ago
Joined: 2017-12-15 14:54
Posts: 2

Thanks for the info!

I have sorted out the most important signal mapping now. Some from looking at the commands.c but the rest had to be reverse engineered. I don´t fully understand how the message is created and how the variables end up in a certain order in the message?!

wdaehn
Offline
Last seen: 2 years 6 months ago
Joined: 2017-09-12 17:26
Posts: 65

This is from my source code. You have the packet structure and above buffer_append_.... fill the payload.

Note: As any network code it is MSB-first.

To get the actual decimal value you have to divide by the factor, e.g. v_in_10 might have the int16_t value of 113, divided by 10 returns the correct 11.3Volt.

That is how far I got. It is working though.

 

// VESC Types
// Example Packet:
// 02 3a 04 01 1a 00 f3 00 00 01 ba 00 00 00 66 00 00 00 00 ff ff fe 46 fe f8 ff ff e0 2c 00 71 00 00 00 2e 00 00 00 00 00 00 02 12 00 00 00 00 ff ff e0 bb 00 00 3c 2f 00 09 69 58 d0 cc 6f 03

// 02: Packet Start Byte
// 3a: 58 bytes of payload starting with the next byte '04'
// 04: The command COMM_GET_VALUES
// payload mapping to the structure below
// cc6f: The 2 byte CRC
// 03: Packet End Byte

struct getvalues_s {
    int16_t         temp_fet_10;                // 0x011a
	int16_t         temp_motor_10;              // 0x00f3
	int32_t         avg_motor_current_100;      // 0x000001ba (7-10)
	int32_t         avg_input_current_100;      // 0x00000066 (11-14)
    int32_t         avg_id_100;                 // 0x00000000 (15-18)
    int32_t         avg_iq_100;                 // 0xfffffe46 (19-22)
    int16_t         duty_now_1000;              // 0xfef8
    int32_t         rpm_1;                      // 0xffffe02c (25-28)
	int16_t         v_in_10;                    // 0x0071
    int32_t         amp_hours_10000;            // 0x0000002e (31-34)
    int32_t         amp_hours_charged_10000;    // 0x00000000 (35-38)
    int32_t         watt_hours_10000;           // 0x00000212 (39-42)
    int32_t         watt_hours_charged_10000;   // 0x00000000 (43-46)
    int32_t         tachometer;                 // 0xffffe0bb (47-50)
    int32_t         tachometer_abs;             // 0x00003c2f (51-54)
    int8_t          fault_code;                 // 00
    int32_t         unknown;                    // 0x096958d0 purpose unknown
} __attribute__ ((__packed__));

 

 

https://github.com/wernerdaehn/CC3D-CableCam-Controller/blob/master/inc/...

https://github.com/wernerdaehn/CC3D-CableCam-Controller/blob/master/src/...

mwd467
Offline
Last seen: 6 years 2 months ago
Joined: 2018-01-30 14:25
Posts: 6

@whdaehn  In that list of bytes your sending the first 01 1a after com_get_values' 04 is that for getting the temp_fet value to be sent back from the vesc? So include the corresponding byte in the payload from that struct you have there to get a desired value back? or will a raw data set automatically be sent back if just 04 is sent as the payload? I'm having trouble getting a response from the VESC and this it may be an incorrect request on my part. Your detailed source code is sort of clearing things up.

Thanks

wdaehn
Offline
Last seen: 2 years 6 months ago
Joined: 2017-09-12 17:26
Posts: 65

The com_get_values command requests all values. You cannot tell which parts to return, it returns the full data. Hence I load that into that struct and then I pick the variable I want.

You got the point that above example lists the response only, not what I am sending.

 

Does that answer it?

mwd467
Offline
Last seen: 6 years 2 months ago
Joined: 2018-01-30 14:25
Posts: 6

Yes, that was my interpretation of how it works. I am sending 02 01 04 40 84 03 but am not getting anything back form the VESC when checking my receive buffer. Any thoughts?

wdaehn
Offline
Last seen: 2 years 6 months ago
Joined: 2017-09-12 17:26
Posts: 65

Looks good, checksum I can't tell. The only idea I have is big endian/little endian. Can you send 02 01 04 84 40 03  (CRC bytes swapped) for a test? The VESC does not respond if anything is wrong, hence we don't know what it is. Could also be hardware, TX versus RX, VESC configuration (Uart activated??)...

mwd467
Offline
Last seen: 6 years 2 months ago
Joined: 2018-01-30 14:25
Posts: 6

UPDATE: The packet I am sending was correct and I receive a similar 58 byte packet back to what ou posted above. My receive buffer was/is not triggering correctly but from the VESC end it is transmitting perfectly. I have an arduino piggy backing on the tx so I can see the output and the problem is rx on my nxp board. Thanks for the guidance.

mwd467
Offline
Last seen: 6 years 2 months ago
Joined: 2018-01-30 14:25
Posts: 6

Hey @whdaehn, another follow up question regarding the UART.

The packets that are Tx from the VESC end with a 3, but do they contain a \0 \r or \n after that? I cannot pick up either and can only catch the com values correctly when hardcoding my buffer to stop at 63 bytes (58 payload plus the 5 info bytes), this does work fine but the same would have to be done with each other get command individually.

Can it be confirmed there are no interrupting chars sent after the stop byte, or am I just missing them somehow?

Also I'm looking to use the set_rpm command for control of my motor, I should be able to set 12000 rpm for example and if correctly tuned the vesc should vary its amperage to hold that value correct?

Thanks

wdaehn
Offline
Last seen: 2 years 6 months ago
Joined: 2017-09-12 17:26
Posts: 65

This is all binary communication. So no \r \n or \0 chars are being sent. (At least I am not aware of and I have not noticed any.)

My logic is primarily timing driven:

  1. If the byte received in the interrupt has a time gap of  >500ms since the last byte was received, this is a new packet. Reset the buffer position to zero.
  2. Decode the packet based on its position. So start byte has to be first, when the length byte is read set the high watermark, when the high water mark is reached check if that is the end byte.
  3. If all true, copy the buffer into the structure so it can be read more easily and the buffer is free to receive the next bytes.
  4. If not, throw away the data.

The point is, the VESC never sends any data unless you request it by sending a command. So as long as you are not sending commands faster than 500ms, above works. And many commands like the set_rpm do not return anything even.

Above logic should cope with all issues like an accidental correct byte due to noise, data loss and the such.

 

Regarding your second point., yes, I control the VESC with rpm commands as well (with the exception of rpm=0, which I translate into brake_current and handbrake commands for now. Still testing though.). There is an enhancement request to let the VESC handle rpm=0 as well, so it should do everything that is needed to stop and stay at speed=0. Would appreciate if you would support this request by raising your voice there. http://vesc-project.com/node/146

 

arshhh
Offline
Last seen: 6 years 3 weeks ago
Joined: 2018-03-03 07:13
Posts: 1

Hello, 

I tried to get all the data from VESC 6.0 too. I am getting no good data at all. However I can set RPM and duty cycles. 

 

Can you please tell me what should I change in PyVESC files? 

Thanks 

Addy
Offline
Last seen: 19 hours 30 min ago
VESC Free
Joined: 2017-09-06 01:53
Posts: 13

Thanks for the information wdaehn. I updated pyvesc/messages/getters.py and now the GetValues message appears to be working. I don't use all the other messages though, so they may still need tweaking.

To update pyvesc, in getters.py in the GetValues class, change "fields" to the following:

    fields = [
            ('temp_fet', 'h', 10),
            ('temp_motor', 'h', 10),
            ('current_motor', 'i', 100),
            ('current_in', 'i', 100),
            ('avg_id', 'i', 100),
            ('avg_iq', 'i', 100),
            ('duty_now', 'h', 1000),
            ('rpm', 'i', 1),
            ('v_in', 'h', 10),
            ('amp_hours', 'i', 10000),
            ('amp_hours_charged', 'i', 10000),
            ('watt_hours', 'i', 10000),
            ('watt_hours_charged', 'i', 10000),
            ('tachometer', 'i', 1),
            ('tachometer_abs', 'i', 1),
            ('mc_fault_code', 'c'),
            ('unknown', 'i', 1)            
    ]

 

petertaylor
Offline
Last seen: 3 years 1 week ago
Joined: 2018-02-19 07:01
Posts: 18

PS, i've been using these new values on Firmware 3.4, and it's been working well for me too. Should get updated in the github repo.