arduino-libraries / Arduino_MachineControl

GNU Lesser General Public License v2.1
38 stars 29 forks source link

RS-485 full duplex example disables the receiver when sending data #110

Closed marcocipriani01 closed 10 months ago

marcocipriani01 commented 11 months ago

Hello, At the moment, the RS-485 full duplex example disables the receiver when sending data. This defeats the purpose of full duplex:

comm_protocols.rs485.noReceive();

comm_protocols.rs485.beginTransmission();

comm_protocols.rs485.print("hello ");
comm_protocols.rs485.println(counter++);

comm_protocols.rs485.endTransmission();

// Re-enable receive mode after transmission
comm_protocols.rs485.receive();

If this is not necessary, the example should be changed to leaving the receiver enabled.

If this is necessary (perhaps due to a physical limitation of the Portenta Machine Control that requires the receiver to be disabled when sending data???) then the limitation should be clearly documented.

manchoz commented 10 months ago

Hi @marcocipriani01, Yes, it is necessary and depends on the fact that the RS485 transceiver in use still has a half-duplex UART (with flow control) facing the microcontroller (please see pag. 7 of Portenta Machine Control Schematics).

So, while you are transmitting and receiving on two separate pairs of lines on the fieldbus side, you need to deal with having just a single UART (TX/RX + RTS/CTS) for both transmitting and receiving on the Arduino side.

The behavior you see in the sketch is to accommodate this architecture.

marcocipriani01 commented 10 months ago

Hi @manchoz, Sorry, something doesn't add up with the documents you linked:

image

image

image

image

image

Please let me know if I'm missing something, Marco Cipriani

manchoz commented 10 months ago

Hi @marcocipriani01, If you feel the RS422 management can be improved, please feel free to provide a PR to the corresponding code bases involved.

In the end, even using threads, the PMC is still a single-core machine so that you can read or write in mutual exclusion from the RS422 at any given step.

marcocipriani01 commented 10 months ago

I don't have an issue with the code or the library, all I'm saying is that the full-duplex example probably doesn't need comm_protocols.rs485.noReceive() and comm_protocols.rs485.receive(), which physically disable and enable the RX transceiver inside the SP335E. I will make some tests this week to confirm (or eventually deny) that the Portenta Machine Control can send and receive at the same time using the RS-422 port, like any other UART interface. In theory, it should behave like an Arduino UNO's UART interface, so sending data any time without stopping the reception on the RX pin. UART interfaces have buffers that operate without the need for a second core.