lexus2k / tinyproto

Tiny Software Protocol for communication over UART, SPI, etc
GNU General Public License v3.0
240 stars 51 forks source link

Multidrop / Master+Slaves on RS485 or similar #26

Open hippyau opened 3 years ago

hippyau commented 3 years ago

Is there any possibility of using this between 2 or more nodes in a small network, with simple addressing? Or any suggestions of a protocol that is light and can support more than 2 nodes?

lexus2k commented 3 years ago

Hi,

Unfortunately, the full duplex version (tiny_fd) doesn't work out of the box with the RS485 physical channel, since RS485 is the half-duplex interface. Tinyproto implements only the ABM part of the HDLC protocol that can be used only with P2P connections. For your case NBM or ARM parts of HDLC must be implemented.

However, you can still write communication using tinyproto's hdlc_ll functions. The low level will provide you error checking and framing.

michcfr commented 3 years ago

Hello, I got the same kind of question but with classical UART like in the figure below: http://www.sampson-jeff.com/article/interface/as-mdd.gif Can I address 1 master and multiple slaves? thx

lexus2k commented 3 years ago

Hi @michcfr ,

According to your picture there are 2 diodes blocking TX line for 2 slave devices. ABM mode is the mode that requires confirmation, so any node in the network must have the ability both to read and send data asynchronously. Your scheme doesn't allow that, thus tiny_fd cannot be used in your case. So the best way with the current HDLC and hardware implementation is to use hdlc_ll API and to interpret the first byte of the buffer being sent at application protocol as an address field. On the slave devices, upon receiving the whole frame, you need just to check the first byte of the buffer to understand if the data are designated for a specific slave station.

изображение

PS. HDLC NBM and ARM modes have address fields, however in many HDLC implementations the field is not used and usually initialized to either 0xFF or 0x01/0x03. The tinyproto library initializes that field to 0xFF all the time.

michcfr commented 3 years ago

Hello Aleksei, Thank you for your response.

The diodes are not blocking the TX line for the 2 slave devices. Diode exists just for electrical protection reasons only. UART uses negative logic. So, if the Tx output is high the diode is reverse biased: it blocks. If Tx output is low the diode is forward biased: it is conducting. Consequently, any node have the ability to read and send data asynchronously. So I think tiny_fd can be used.

In the case of tiny_fd, can you please show me in the source code where I can get the address fields? I suppose this is also a fixed value of 0xFF?

hippyau commented 3 years ago

The diodes are not blocking the TX line for the 2 slave devices. Diode exists just for electrical protection reasons only.

This is my understanding also.

In the case of tiny_fd, can you please show me in the source code where I can get the address fields? I suppose this is also a fixed value of 0xFF?

tiny_fd_int.h line 51: ​        ​uint8_t​ address;

I'd like to have simple arrangement and coordinate where the master polls the slave, and only the addressed slave responds.

michcfr commented 3 years ago

ok I see. I have to do some test to see how it fits together. For information, I plan to connect together many ESP32 throught the UART with a multi-master architecture: no master ESP32, so that any ESP32 can communicate with each other. I think this is ABM mode? Can I add an extra field to put the source address, knowing that HDLC include only the destination address? Another question: do you have any plan to adapt your software to Arduino ?

lexus2k commented 3 years ago

Hi

The diodes are not blocking the TX line for the 2 slave devices

Oh, my bad. I was confused with the diagram.  Some of the hardware manufactures require pull-up resistors for the Tx-Rx line.  Absolutely agree with you

In the case of tiny_fd, can you please show me in the source code where I can get the address fields? I suppose this is also a fixed value of 0xFF?

You can check the file tiny_fd.c. Look for .address text.

I'd like to have a simple arrangement and coordinate where the master polls the slave, and only the addressed slave responds.

Good point, but that requires a different HDLC mode - not ABM, maybe NRM.

For information, I plan to connect together many ESP32 throught the UART with a multi-master architecture: no master ESP32, so that any ESP32 can communicate with each other. I think this is ABM mode?

ABM mode is usually invoked with async modes, when each station can send at any time, and there are no master and slave devices. Current implementation of the ABM HDLC mode can be used only in P2P connections. The user data is transferred in I-Frames, which need confirmation from the receiver, and there is only a single N(s) N(r) table in the current tinyproto implementation. For your case, the master needs separate N(s) N(r) tables and different frame pools for each slave station. I'm thinking of P2M support, but I have no solution right now for you. I'm sorry.

Can I add an extra field to put the source address, knowing that HDLC includes only the destination address?

The address field in the HDLC is exactly for the same purpose - it should contain a slave address, whenever the master sends to and receives from the packet.

Another question: do you have any plans to adapt your software to Arduino ?

Is this question for me? The library can be used in Arduino IDE as is.

michcfr commented 3 years ago

Hello Aleksei, About the diodes => don't worry, I was confused too at first time :-)

I'd like to have a simple arrangement.... => It was not my question, but your response is interesting

ABM mode is usually invoked with async mode.... => yes I need P2M support where each node needs separate N(s) N(r) tables and different frame pools. Can you please indicate part of the code that need to be changed?

thx

lexus2k commented 3 years ago

Can you please indicate part of the code that need to be changed?

That's not so easy to update that code to work with multiple stations. I mean tiny_fd.c

lexus2k commented 3 years ago

Here are the steps, which are required to reach the goal.

  1. Implement frame queue to keep as much frames on the master as required to support all slave.

For example, if you have window size (maximum number of unconfirmed frames) for each slave station equal to 4, then the master device must be able to keep 4 N unconfirmed framed. If we're talking about the picture, then 4 2 = 8. I'm working on this, and do not have ready solution yet.

This step also requires on the master side to have next_ns, confirm_ns, nr, last_ns counters for each slave station. And I'm working on this.

  1. Make the master to be able address each slave separately

This step required API change, because you need somehow to inform the protocol that specific data is for specific slave station only. There are 3 ways to implement that:

  1. Make the slave devices to understand, if the received frame addressed to specific section

Actually this can be easily implemented, for example, by adding the address field to initialization data for tinyproto.

  1. Update the tinyproto implementation to use P/F HDLC bit correctly in NRM mode.

In current implementation P/F bit is always set to 0 for I-Frames, and is always set to 1 for S and U-Frames. Because the protocol actually fully asynchronous, i.e. each station can transmit at any time it wants. But that plays a bad role in your case, because of the collisions, when 2 slave devices want to send data at the same time. So to solve this problem, the protocol should be significantly updated to use something like markers, and with specific timeouts, if some device doesn't respond.

lexus2k commented 2 years ago

@michcfr

Let me know how it goes.

lexus2k commented 2 years ago

Things to do to implement multiple devices support on a single serial interface:

lexus2k commented 2 years ago

Things to do to implement multiple devices support on a single serial interface:

lexus2k commented 2 years ago

Things to do to implement multiple devices support on a single serial interface:

lexus2k commented 2 years ago

Let me know if you want Multidrop feature to be implemented.

hippyau commented 2 years ago

I think it would be very useful :)

On Mon, 7 Feb 2022, 12:40 Aleksei, @.***> wrote:

Let me know if you want Multidrop feature to be implemented.

— Reply to this email directly, view it on GitHub https://github.com/lexus2k/tinyproto/issues/26#issuecomment-1031016780, or unsubscribe https://github.com/notifications/unsubscribe-auth/AIWBBRMY4OURH6XUF5V25LLUZ4WJLANCNFSM5IBBHDHQ . You are receiving this because you authored the thread.Message ID: @.***>

lexus2k commented 2 years ago

Basic implementation on NRM protocol (Multidrop support) is ready. There are new API's to use for NRM.

First of all tiny_fd_init() has new fields in init structure: on_read_cb, on_send_cb, peers_count, address, mode.

tiny_fd_register_peer must be used before sending something to remote client peers. This API tell the protocol the address of secondary station to talk to. Please, not that all registered secondary stations must be up to have primary station properly working.

Next new APIs tiny_fd_send_packet_to and tiny_fd_send_to accept also address of the peer station to send frame to.

Some old API's have changed, let me know if there are some issues with them. The protocol is not tested completely, there are only a couple of unit tests for NRM mode right now.