SkillAgentSearch skills...

RSbus

This Arduino library sends feedback information from a decoder to the master station via the (Lenz) RS-bus.

Install / Use

/learn @aikopras/RSbus
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

<a name="RSbus"></a>RSbus (Version 2.4.6)

This Arduino library can be used to send feedback information from a decoder to the master station via the (LENZ) RS-bus. The RS-bus is the standard feedback bus used for Lenz products, and supported by several other vendors. As opposed to some other feedback systems, the RS-Bus implements a current loop (instead of voltage levels) for signalling, making the transmission less susceptible to noise and interference. RS-Bus packets also include a parity bit to provide some form of error detection, and the command station notifies the feedback decoders if it has detected such parity error. For more information on the RS-bus see the der-moba website (in German) and https://sites.google.com/site/dcctrains/rs-bus-feed. To understand the design decisions behind, and implementation of this library, see the file Basic operation for further details.

The RS-bus supports a maximum of 128 feedback addresses, numbered 1 to 128. The master polls all 128 addresses in a sequential order to ask if they have data to send. Per address 8 bits of feedback data can be send; individual feedback messages carry only 4 of these bits (a nibble), so 2 messages are needed to send all 8 bits. Note that this library allows a decoder to have multiple RS-bus addresses. For each address a separate RS-Bus connection should be established.

If no feedback module sends information, one complete polling cycle takes 33,1 ms. On the other hand, if all feedback modules send information, one polling cycle takes 33,1 + 128 * 1,875 = 273,1 ms. Since feedback modules can only send half of their data (one nibble) during one polling cycle, roughly 550 ms may be needed to send 8 bits.

Used hardware and software

Two Arduino pins are needed for this library, as well as some software:

  • A receive pin rxPin: needed to receive RS-bus polling pulses from the command station
  • A transmit pin (and USART): needed to send RS-bus messages to the command station
  • The timer associated with the Arduino micros() function
  • In case of a AtMega 2560 processor, Timer 5 is used to update the address being polled.
  • Optional (depends on micro-controller and decoding approach, see below): Real Time Clock or one of the TCB timers. Installation of a MightyCore, MegaCore, MegaTinyCore, MegaCoreX or DxCore board may be necessary (see for the URL the references below).

Receive pin

The choice of receive pin depends on the micro-controller being used, as well as decoding variant. See also the respective board info to determine the Arduino pin number that belongs to the (External Interrupt) port being used.

  • For traditional ATMega processors, such as the 8535, 16 and the 328 (used by the Arduino UNO and Nano), rxPin must be one of the two External Interrupt pins: INT0 or INT1. INT0 is generally PD2, INT1 is generally PD3.
  • The ATMega 2560 has eight External Interrupt pins: INT0 - INT7. rxPin must be one of these pins.
  • The MegaCoreX processors, such as the 4808 (Nano Thinary) and 4809 (Nano Every) can use all digital pins as rxPin. However, due to the higher number of external interrupt pins, determining which pin raised the interrupt routine takes several microseconds extra (compared to the traditional ATMega processors). For these micro controllers a better approach is therefore to use the RTC decoding variant. See Basic operation for further details.
  • The same holds for DxCore processors, such as the AVR-DA and AVR-DB series. In addition, DxCore processors also support the use of one of the Timer-Counters B to count RS-bus pulses. Using a TCB has as advantage that basically any pin can be used as rxPin, but the disadvantage is that TCB timers may be scarce resources. Again see Basic operation for further details.

Transmit pin

The transmit pin must be one of the USART TX-pins. However, for this library we should not provide the Arduino pin number, but the USART number. Most traditional ATMega processors support a single USART only. More powerful processors, such as the 2560 and newer MegaCoreX and DxCore processors support 4 or even more USARTS. See src/sup_usart.cpp for details. Below an overview of (some) processors that support multiple USARTs.

  • 2 USARTS: 64, 128, 162, 164, 324, 328PB, 644, 1281, 1284, 2561, ATtiny Series-2
  • 4 USARTS: 640, 1280, 2560, 4808, 4809
  • 6 USARTS: AVR-DA, AVR-DB

Decoding approaches

Version 2 (V2) of the RS-bus library supports different RS-bus routines for different ATMega controllers and software. To select a different approach, modify the file src/RSbusVariants.h.

  • RSBUS_USES_SW: the default approach for traditional AtMega 328 processors (V2): The default approach for traditional AtMega processors with a limited number of timers (Uno, Nano, ...) is the software-based approach, where a pin interrupt is raised after each RS-bus transition. The advantage of this approach is that it works with all controllers, but the disadvantage is that it puts more load on the CPU and may therefore interfere with other timing sensitive code. See Basic operation for details. => works on all ATMega micro-processors.

  • RSBUS_USES_SW_T3: the default approach for AtMega 2560 processors (V2.4): The default approach for AtMega processors with a higher number of timers (Mega, ...) is the software-based approach, where a pin interrupt is raised after each RS-bus transition, combined with an extra timer that resets the RS-Bus address being polled. Using this extra timer not only offloads the CPU, but it also makes operation more reliable in cases where other software (such as the LCD library) blocks the CPU for longer periods of time (longer is more than 2ms).
    By default Timer 3 is used, but if this timer is used in other parts of the sketch Timer 1, Timer 4 or Timer 5 may be selected as alternative. Note that the Timer 1 variant may also be selected for other AtMega processors, such as the 328 or 16, if that timer is not used by any other library. => works on ATMega 2560 micro-processors.

  • The default approach for new AtMega processors (V2): The default approach for new AtMega processors with 40 pins or more is also a software-based approach. Examples of such new AtMega processors are the 4809 (which is used on the Nano Every) and the AVR128DA48. The boards needed for these newer processors are MegaCoreX and DxCore. Also in this approach an interrupt is raised after each RS-bus transition. However, this approach is more efficient and reliable, since the standard external pin interrupt (which is initialised using attachInterrupt()) is replaced by a TCB interrupt that gets triggered via the Event System. Such interrupts are considerably faster than the external pin interrupts used in the previous approach. In addition, the TCB timer can efficiently measure the precise duration of each RS-bus pulse, and thereby improve reliability. Finally noise cancelation is possible if the TCB is configured as Event user. Short spikes on the RS-Bus RX pin will than be filtered, and reliability will again be improved. Depending on the board, TCB2 is used as default (MegaCoreX) or TCB3 (DxCore).

  • RSBUS_USES_RTC (V2): An alternative approach is to use the Real Time Clock (RTC) of the modern ATMegaX and DxCore processors (such as 4808, 4809, 128DA48 etc). This code puts less load on the CPU but has as disadvantage that the RS-Bus input signal MUST be connected to pin PA0 (ExtClk). This approach requires installation of the MegaCoreX or DxCore board software. => recommended for newer processors on MegaCoreX / DxCore boards. Requires pin PA0!

  • RSBUS_USES_HW_TCBx (V2): A similar approach is to use one of the TCBs of a ATtiny Series 2 or DxCore processor as event counter. For that purpose the TCB should be used in the "Input capture on Event" mode. That mode exists on novel DxCore (such as the 128DA48) processors, but not on MegaCoreX (such as 4808, 4809) or earlier processors. Like the RTC approach, this approach puts limited load on the CPU, but as opposed to the RTC approach we have (more) freedom in choosing the RS-bus input pin. This approach requires installation of the DxCore board software. => Supported only on DxCore boards. Useful if pin PA0 is not available.

  • RSBUS_USES_SW_4MS (V1): This was the default version in the previous release (V1) of the RS-bus library. Instead of checking every 2ms for a period of silence, we check every 4ms. This may be slightly more efficient, but doesn't allow the detection of parity errors. => included for compatibility reasons.

The RSbusHardware class

The RSbusHardware class initialises the USART for sending the RS-bus messages, and the Interrupt Service Routine (ISR) used for receiving the RS-bus pulses send by the master.

  • void attach(uint8_t usartNumber, uint8_t rxPin)

Should be called at the start of the program to select the USART (0...5) and connect the RS-bus Receive pin (Arduino pin number) to the RS-bus Interrupt Service Routine (ISR). The attach() functions checks two additional parameters: interruptModeRising and swapUsartPin.

  • void detach(void)

Should be called before of a (soft)reset of the decoder, to stop the ISR.

  • void checkPolling(void)

Should be called as often as possible from the program's main loop. The RS-bus master sequentially polls each decoder. After all decoders have been polled, a new polling cycle will start. checkPolling() keeps the polling administration up-to-date. Note: on AtMega 2560 processors checkPolling() is replaced by a Timer 5 interrupt and therefore doesn't need to be called anymore.

  • bool rsSignalIsOK

A flag maintained

View on GitHub
GitHub Stars10
CategoryDevelopment
Updated3mo ago
Forks0

Languages

C++

Security Score

92/100

Audited on Dec 19, 2025

No findings