MichaelJonker / HardwareSerialRS485

Arduino Software for RS485 support with collision detection and message handling capabilities
MIT License
107 stars 29 forks source link

Example for Arduino Leonardo #9

Closed filipek92 closed 3 years ago

filipek92 commented 6 years ago

Hello,

I have my own redesigned board based on Arduino Leonardo, but I have only one pin to control DE/RE. Could I use your library? Could you please show me some example of usage of your library on AtMega32U4?

Thank you very much Filip Richter

MichaelJonker commented 6 years ago

Hi Filip,

Thanks for you interest in my library.

To answer your question, yes you should be able to do so. You need two pins only if you want to use the USART and the RS485 communication independently. For the UNO the usage of two pins is a must, as the USB communication passes through the USART; the one pin solution described here leads to conflicts when reloading a new sketch. The Atmega32u4 based chips (Leonardo and Micro) have a dedicated USB interface on chip, so the USART is not used for the USB communication.

For your case I advise you to permanently enable the reading of the RS485 bus. You do this by pulling the RE* input of the RS485 interface IC permanently low with a ~10K resistor. Hence no output pin is needed for this. In this case reading from RS485 interface cannot be shut off anymore by hardware (but on the Leonardo or micro there is no need for this).

The WE pin of the RS485 interface IC still needs to be controlled by the library, as the library enables the RS485 interface only when writing. When not enabled the RS485 bus is tri-stated, such that the RS485 interface will not force the bus (otherwise this would inhibit other bus members to write correctly to the bus).

BTW, note that you should use an RS485 interface chip with independent WE and RE inputs as one needs to leave reading enabled also when writing so that the library can detect collision. There are certain RS485 interfaces which connects the WE and RE pins, these should not be used.

Though the library expects a pin number for both the RE and the WE, you may actually trick the library and specify the WE pin number for both the RE and WE pin. As an example: if bit 6 of Port B is used to control the Transmit Enable, then parametrize the TRxControl template class as TRxControl<'B', 6, 6 >. The library will only function properly when in RS485 mode Serial1.setMode(0x11);

See also https://github.com/MichaelJonker/HardwareSerialRS485/wiki/Leonardo-Micro-Support I use this library on a Micro (like the Leonardo based on a Atmega32u4), see the code: https://github.com/MichaelJonker/HardwareSerialRS485/blob/master/examples/RS485_USB/RS485_USB.ino However, I do not use it in a one pin configuration in here.

Please let me know if you face any problems. Please let me know if you have suggestions to improve the documentation (specifically related to Leonardo-Micro-Support)

Cheers

Michael Jonker

From: Filip Richter notifications@github.com Sent: 03 September 2018 17:01 To: MichaelJonker/HardwareSerialRS485 HardwareSerialRS485@noreply.github.com Cc: Subscribed subscribed@noreply.github.com Subject: [MichaelJonker/HardwareSerialRS485] Example for Arduino Leonardo (#9)

Hello,

I have my own redesigned board based on Arduino Leonardo, but I have only one pin to control DE/RE. Could I use your library? Could you please show me some example of usage of your library on AtMega32U4?

Thank you very much Filip Richter

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHubhttps://github.com/MichaelJonker/HardwareSerialRS485/issues/9, or mute the threadhttps://github.com/notifications/unsubscribe-auth/AJdhEm50YNae3HNBGT0WluKFnmgB-Z_Iks5uXUQggaJpZM4WXwqT.

filipek92 commented 6 years ago

What is the purpose of this example?

If I understand that well, It reads messages from USB in your format and send it to RS485 through Hardware serial to RS485. But reading from RS485 is done by simple reading bytes one by one and resend them to usb.

Thank you for your work and help Filip

MichaelJonker commented 6 years ago

The purpose of this example: I use it to provide a host interface (either a PC or an android device) to the RS485 bus over USB.

Motivation: The library provides collision avoidance and collision detection and recovery, this works well when all devices on the bus communicates using this library. However, when interfacing with a host computer (PC, android, …) over USB using e.g. the RS485-USB converter from FTDIchip (FTDIchip Products USBRS485http://www.ftdichip.com/Products/Cables/USBRS485.htm) or the Sparkfun BOB-09822https://www.sparkfun.com/products/9822 there is no proper collision handling. The host interface could seriously perturb the RS485 traffic on the bus. To mediate this I use an Arduino micro, an RS485 interface and the simple bridge code which is given in the example.

See also https://github.com/MichaelJonker/HardwareSerialRS485/wiki/host-interface

Indeed the example is as simple as you described it: From the host to RS485 it expect well formatted messages and send them out as messages on the RS485 bus (with collision detector and message sending retrial). For the reception in the other direction, however, I did not implement a message reception and filter. For diagnostic purposes, it was actually interesting to show what is happening on the bus (see collisions between two devices), hence the simple character by character forwarding. That said, I could have implemented a message filter, to filter out only certain (programmable) addresses to be relayed back to the host. Maybe some idea for the next version when I have some time. I also thought to integrate a simple scope to visualize the signal levels for diagnostic purposes.

But what may be of interest to you in this example is the implementation of the message oriented protocol with a host over USB (if you have a need such). Otherwise the code is not much different from the UNO (except that the USB communication is using the class Serial and RS485 communication uses the class Serial1).

Cheers Michael

filipek92 commented 6 years ago

Hello, I have good news from (and for) me :-D I have working example on Leonardo as RequestResponse device. It is great library, I have a plan to build upper layer of protocol (different types of messages, broadcasts, addressing schematic, and system of registering callbacks (to not have a list of elseifs))

I plan to use this in my home network of connected devices. First unit is used to watch level of water in well (using ultrasonic range sensor), flow rate of pumped water, and its temperature. If you want you can see it here https://github.com/filipek92/WellControll

But I have another question, what is the reason not to use parent class for your classes like HardwareSerialRS485_0, HardwareSerialRS485_1, MessageReader) which defines only common interface, sou you can youse reference to this common parent without knowledge of what is the implementation.

Maybe I messed something, I'm not an expert of template based classes in C++.

Thank you

MichaelJonker commented 6 years ago

Hi Filip,

Nice to hear you succeeded. Good news for me as well, that you have tested the single pin control option on the Leonardo/micro.

I would be very interested to see your upper layer of protocol. I know (and I use it) that this library allows single, and multicast messages by defining a proper addresses scheme and program the message filters of the clients as such (but I never advocated this explicitly).

If you need any advice or information on the library, do not hesitate to contact me.

Please be so kind to put a reference in your code/project to this library where applicable. So if you get famous, some of your fame may shine on me ;-). Likewise, once you consider your project mature enough, I would be very happy to provide (with your permission) a link to your project in a (yet to be created) “examples from external users” section of my documentation.

For your second question on the implementation: First a disclaimer: I did not have much of experience with templates when I started, but I learned quite a lot. I also discovered that templates are a great concept for replacing interfaces with virtual methods. When I looked at the classical HardwareSerial library, I noticed that this library has some complexity due to the multi-object/class implementation. Usart device resources such as register addresses, were not hard coded but referenced through member variables, which then (I reasoned) makes code slower and using more SRAM and ProgMem space. Since on the simple ATMEL devices every byte counts, I worked on optimising the single usart case. This lead to the singleton class implementation (i.e. one, or actually no, object per class). I then reasoned that devices with more usarts (the mega) also have more resources available so the impact of the overhead due to a dedicated class per usart would be minor. Moreover, because the usart resources are hardcoded in these classes, code will be smaller and can be in-lined much easier. Voila, in short the history which led to the implementation. I know that there are probably some opportunities to polish the code further in order to improve the efficiency and aesthetics. But I have to admit that I am sometime baffled myself by the implementation when I now look at it. I just have to find some time…

Cheers and good luck with your implementation.

Michael Jonker