Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

custom transport RS458 UART for portenta machine control #832

Closed
Jenifen opened this issue Mar 16, 2022 · 5 comments
Closed

custom transport RS458 UART for portenta machine control #832

Jenifen opened this issue Mar 16, 2022 · 5 comments

Comments

@Jenifen
Copy link
Contributor

Jenifen commented Mar 16, 2022

Description:
I create a new transport mechanism to communicate through RS485 in Portenta machine control H7, and i run ros-agent in jetson.
below the rs485_transport.cpp :

#include <Arduino.h>
#include <Arduino_MachineControl.h>


extern "C"
{
  #include <stdio.h>
  #include <stdbool.h>
  #include <sys/time.h>
  



  int clock_gettime(clockid_t unused, struct timespec *tp) __attribute__ ((weak));
  bool uart_rs485_transport_open(struct uxrCustomTransport * transport) __attribute__ ((weak));
  bool uart_rs485_transport_close(struct uxrCustomTransport * transport) __attribute__ ((weak));
  size_t uart_rs485_transport_write(struct uxrCustomTransport * transport, uint8_t *buf, size_t len, uint8_t *errcode) __attribute__ ((weak));
  size_t uart_rs485_transport_read(struct uxrCustomTransport * transport, uint8_t *buf, size_t len, int timeout, uint8_t *errcode) __attribute__ ((weak));

  #define micro_rollover_useconds 4294967295

  int clock_gettime(clockid_t unused, struct timespec *tp)
  {
    (void)unused;
    static uint32_t rollover = 0;
    static uint32_t last_measure = 0;

    uint32_t m = micros();
    rollover += (m < last_measure) ? 1 : 0;

    uint64_t real_us = (uint64_t) (m + rollover * micro_rollover_useconds);
    tp->tv_sec = real_us / 1000000;
    tp->tv_nsec = (real_us % 1000000) * 1000;
    last_measure = m;

    return 0;
  }

  bool uart_rs485_transport_open(struct uxrCustomTransport * transport)
  {
    // Set the PMC Communication Protocols to default config
    machinecontrol::comm_protocols.init();
    // Enable the RS485/RS232 system
    machinecontrol::comm_protocols.rs485Enable(true);
    // Specify baudrate, and preamble and postamble times for RS485 communication
    machinecontrol::comm_protocols.rs485.begin(115200, 0, 500);

    machinecontrol::comm_protocols.rs485.receive();
    return true;
  }

  bool uart_rs485_transport_close(struct uxrCustomTransport * transport)
  {
    machinecontrol::comm_protocols.rs485.end();
    return true;
  }

  size_t uart_rs485_transport_write(struct uxrCustomTransport * transport, uint8_t *buf, size_t len, uint8_t *errcode)
  {
    (void)errcode;
    machinecontrol::comm_protocols.rs485.noReceive();
    machinecontrol::comm_protocols.rs485.beginTransmission();
    size_t sent =  machinecontrol::comm_protocols.rs485.write(buf, len);
    machinecontrol::comm_protocols.rs485.endTransmission();
    return sent;
  }

  size_t uart_rs485_transport_read(struct uxrCustomTransport * transport, uint8_t *buf, size_t len, int timeout, uint8_t *errcode)
  {

    (void)errcode;
    machinecontrol::comm_protocols.rs485.receive();
    machinecontrol::comm_protocols.rs485.setTimeout(timeout);
    if (machinecontrol::comm_protocols.rs485.available())
      return machinecontrol::comm_protocols.rs485.readBytes((char *)buf, len);
    else 
      return 0;
  
    
  }
}

// ---- Build fixes -----

// TODO: This should be fixed
#if defined(ARDUINO_TEENSY31) || defined(ARDUINO_TEENSY32) || defined(ARDUINO_TEENSY35) || defined(ARDUINO_TEENSY36)

extern "C" void _write(){
}

#endif
// ----------------------
  • Version :
    i use foxy version of micro-ROS

Steps to reproduce the issue

when i run ros2 run micro_ros_agent micro_ros_agent serial --dev /dev/ttyTHS0 -b 115200 -v6, node doesn't display
image

Thanks !

@Acuadros95
Copy link
Contributor

Acuadros95 commented Mar 16, 2022

Check your uart_rs485_transport_read method, it looks like the board is not getting the response messages from the Agent.
You can see on the agent log how the board is sending a session establish message periodically, as its not getting the confirmation from the agent.

@Jenifen
Copy link
Contributor Author

Jenifen commented Mar 17, 2022

thank you for your response,
yes i check it, but now when i run the agent nothing showing up in log !:
image

@Acuadros95
Copy link
Contributor

How are you using rmw_uros_set_custom_transport?
Check that the first argument is set to true to enable transport framing, as in the default method:

static inline void set_microros_transports(){
	rmw_uros_set_custom_transport(
		true,
		NULL,
		arduino_transport_open,
		arduino_transport_close,
		arduino_transport_write,
		arduino_transport_read
	);
}

More info about this here.

Apart from that detail, I am afraid we can't help here without more info. Try to debug your custom transport methods and check that they are actually sending/receiving the expected payloads.

@Jenifen
Copy link
Contributor Author

Jenifen commented Mar 19, 2022

I test it, but it doesn't work,
I think the problem related with encoding and decoding, because when i tried a sample code (standalone test) without uROS, just send and receive there's some problem in decoding appeared !

I modified the microros library to support native Ethernet transport in portenta machine control, and it works now

I already created a pull request for that
you can find it here #852

Thanks

@Acuadros95
Copy link
Contributor

Okey! I am closing for now, reopen if you encounter problems on uROS side.

I think the problem related with encoding and decoding,

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants