PowerBroker2/pySerialTransfer

Send encoder data

w1ngedshadow opened this issue · 6 comments

Hello, I am building mobile robot based on nvidia jetson nano and arduino. I have two motor encoders connected to arduino so I need to send data to jetson nano (python) via uart. What is the best and right way to do it with this library? Approximate range of encoder values is -1000000 - 1000000. I will appreciate your help.

A good place to start is with these examples:

Arduino TX Data (C++)
Nano RX Data (Python)

You can find more examples here, too.

If you have questions on implementation, the doc strings should be able to answer most of them. For convenience, here's the pySerialTransfer doc strings for the tx_obj() and rx_obj() functions:

def tx_obj(self, val, start_pos=0, byte_format='', val_type_override=''):
'''
Description:
-----------
Insert an arbitrary variable's value into the TX buffer starting at the
specified index
:param val: n/a - value to be inserted into TX buffer
:param start_pos: int - index of TX buffer where the first byte
of the value is to be stored in
:param byte_format: str - byte order, size and alignment according to
https://docs.python.org/3/library/struct.html#struct-format-strings
:param val_type_override: str - manually specify format according to
https://docs.python.org/3/library/struct.html#format-characters
:return: int - index of the last byte of the value in the TX buffer + 1,
None if operation failed
'''

def rx_obj(self, obj_type, start_pos=0, obj_byte_size=0, list_format=None, byte_format=''):
'''
Description:
------------
Extract an arbitrary variable's value from the RX buffer starting at
the specified index. If object_type is list, it is assumed that the
list to be extracted has homogeneous element types where the common
element type can neither be list, dict, nor string longer than a
single char
:param obj_type: type or str - type of object to extract from the
RX buffer or format string as
defined by https://docs.python.org/3/library/struct.html#format-characters
:param start_pos: int - index of TX buffer where the first byte
of the value is to be stored in
:param obj_byte_size: int - number of bytes making up extracted object
:param list_format: char - array.array format char to represent the
common list element type as defined by
https://docs.python.org/3/library/array.html#module-array
:param byte_format: str - byte order, size and alignment according to
https://docs.python.org/3/library/struct.html#struct-format-strings
:return unpacked_response: obj - object extracted from the RX buffer,
None if operation failed
'''

I forgot to mention that I use not an usual Arduino like Nano but Arduino Zero. So I use SerialUSB instead of usual Serial. With examples given upper I have following error on python side: b'$'0.0 | @h is my output. I think its something similar to #51.
What is wrong ?)

Can you post your exact Python and Arduino sketches (with proper markdown) and the full error traceback?

Maybe I am mistaken in description, there arent any errors, I have wrong output on python side: b'$'0.0 | @h instead of b'$'4.5 | hello

Nano code:

from time import sleep
from pySerialTransfer import pySerialTransfer as txfer


class struct(object):
    z = ''
    y = 0.0


arr = ''


if __name__ == '__main__':
    try:
        testStruct = struct
        link = txfer.SerialTransfer('/dev/ttyACM0')
        
        link.open()
        sleep(5)
    
        while True:
            if link.available():
                recSize = 0
                
                testStruct.z = link.rx_obj(obj_type='c', start_pos=recSize)
                recSize += txfer.STRUCT_FORMAT_LENGTHS['c']
                
                testStruct.y = link.rx_obj(obj_type='f', start_pos=recSize)
                recSize += txfer.STRUCT_FORMAT_LENGTHS['f']
                
                arr = link.rx_obj(obj_type=str,
                                  start_pos=recSize,
                                  obj_byte_size=5)
                recSize += len(arr)
                
                print('{}{} | {}'.format(testStruct.z, testStruct.y, arr))
                
            elif link.status < 0:
                if link.status == txfer.CRC_ERROR:
                    print('ERROR: CRC_ERROR')
                elif link.status == txfer.PAYLOAD_ERROR:
                    print('ERROR: PAYLOAD_ERROR')
                elif link.status == txfer.STOP_BYTE_ERROR:
                    print('ERROR: STOP_BYTE_ERROR')
                else:
                    print('ERROR: {}'.format(link.status))
                
        
    except KeyboardInterrupt:
        link.close()

Arduino code:

#include "SerialTransfer.h"


SerialTransfer myTransfer;

struct __attribute__((packed)) STRUCT {
  char z;
  double y;
} testStruct;

char arr[] = "hello";


void setup()
{
  SerialUSB.begin(115200);
  myTransfer.begin(SerialUSB);

  testStruct.z = '$';
  testStruct.y = 4.5;
}


void loop()
{
  // use this variable to keep track of how many
  // bytes we're stuffing in the transmit buffer
  uint16_t sendSize = 0;

  ///////////////////////////////////////// Stuff buffer with struct
  sendSize = myTransfer.txObj(testStruct, sendSize);

  ///////////////////////////////////////// Stuff buffer with array
  sendSize = myTransfer.txObj(arr, sendSize, strlen(arr));

  ///////////////////////////////////////// Send buffer
  myTransfer.sendData(sendSize);
  delay(500);
}

Ok, I see. I don't know why it wouldn't work or why you wouldn't get errors if corrupted packets were received. I would suggest comparing the bytes sent by the Arduino and those received by the Nano. If both match, the issue is somehow with the parsing. You might get faster/better help using the Arduino forum

Ok, thanks a lot