Skip to content

Arduino library for (NMRA) Digital Command Control (DCC) messages. Primarily intended for accessory and function Decoders. Based on OpenDecoder 2 software. Source code includes many comments.

License

Notifications You must be signed in to change notification settings

aikopras/AP_DCC_library

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

44 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

AP_DCC_library

This Arduino library decodes (NMRA) Digital Command Control (DCC) messages. It is primarily intended for accessory Decoders and runs on ATMega processors.

Relation to the NmraDcc library

Like the NmraDcc library, this library runs on ATMega processors, such as the ATMega 328, which is used on the Arduino UNO board. Whereas the NmraDcc library also runs on other microcontrollers, such as the ESP-32 and the Raspberry Pi Pico, this library only runs ATMega processors. However, on newer ATMega processors, such as the 4809 (Arduino Nano Every, MegaCoreX) and the AVR128DA (DxCore), this library provides better performance and reliability. In addition, it is believed that this library is better structured and documented, making modifications easier. See History and Differences to understand the motivation why this library has been developed and how it compares to the NmraDcc library.


The Dcc Class

This is the main class to receive and analyse DCC messages. It has three methods: attach(), detach() and input().

void attach(uint8_t dccPin, uint8_t ackPin=255)

Starts the timer T2 and initialises the DCC Interrupt Service Routine (ISR).

  • dccPin is the interrupt pin for the DCC signal. Basically any available AVR interrupt pin may be selected.
  • ackPin is an optional parameter to specify the pin for the DCC Service Mode Acknowledgement signal (of 6ms). If this parameter is omitted, no DCC acknowledegements will be generated.

The interrupt routine that reads the value of the dccPin must be fast. The traditional Arduino digitalRead() function is relatively slow, certainly when compared to direct port reading, which can be done (for example) as follows: DccBitVal = !(PIND & (1<<PD3); However, direct port reading has as disadvantage that the port and mask should be hardcoded, and can not be set by the main sketch, thus the user of this library. Therefore we take a slightly slower approach, and use a variable called portInputRegister, which points to the correct input port with the right bitmask. With tis approach we actually split the Arduino digitalRead() function into a slow initialisation part, which maps dccPin to portInputRegister, and a fast reading part, which grabs data from that port.

void detach(void)