This page presents a project that will capture and display on the monitor the activity on the NCE bus.
This project is known as NCE_Bus_Probe_1. Later projects NCE_Bus_Probe_2 etc will enhance the C-code developed in this project.
-----------------------------------
This project captures the activity on the NCE bus. For initial testing a NCE DCC Twin controller will be used. This is a simple controller that will control two locos at address 3 and 4 on a DCC track. NCE know this as a throttle.
The NCE DCC Twin also has an RS485 interface (the NCE Bus) where additional controllers may be added to enhance its capability. Twin. This project simply captures the activity on the NCE bus.
NCE DCC Twin. Two knobs plus switches to control locos at address 3 and 4.
Rear of NDE DCC Twin showing on the left the RS495 connector for the NCE DCC Bus
The project is illustrated in the following figure.
A flow chart of the activity on the NCE bus is shown below. Looking ahead it is assumed this project will have the address 85.
The NCE DCC Twin will ping the addresses 80 through 8A in turn checking for a response from the addressed device. If it receives no response it moves to the next address.
At address 80, the broadcast address should be listened to by all devices. The NCE Twin will broadcast messages every 100 or so cycles.
The project uses a TTL to RS485 breakout board to perform the interface between the Arduino and the NCE Bus. On one side of the board are the two RS485 signals "A" and "B" or "+" and "-" (**) plus a ground. On the other side there are 4 pins that include the power (Vcc) and Ground plus the Receive and Transmit TTL pins that are wired directly to the Arduino I/O pins.
** Examples on the internet indicate that the manufacturers definitions are not consistent, and it may be necessary to swap the wiring to A/B.
Once a TTL to RS485 interface board is powered the received signal at RO may be observed with a mixed signal oscilloscope (MSO). The first trace below shows a typical result (**). By using the timing features of the MSO the signal can be determined to be 9600 baud and the time between each byte approximately 3.88 mS (See cursors). Further the data may be deduced/read as 0x80, 0x82, 0x83 through 0x8A. That is the NCE Bus first pings address 80, the broadcast address, it misses device 1, but then pings/addresses devices "2" through "10" before repeating.
Every so often the broadcast address (0x80) is followed by a string of data. With much patience this can be captured. (!!)
** To synchronise the trace the trigger has been set for a negative pulse of greater than 800uS which synchronises on the 0x80 or broadcast ping address.
!! In this example the resultant trace was captured after 84 attempts.
The above trace has captured the signal on the NCE bus. Note it goes through the sequence 0x80, 0x82, 0x83 through 0x8A and then repeats. Each byte is 9600 baud and the time between each byte is 3.88mS,
Occasionally following the 0x80 Broadcast ping/command a burst of activity is inserted before the 0x82 ping. It will be the job of the project firmware to capture this string and take the appropriate action,
In this example the scan was repeated 84 times before this stretched sequence was captured.
The first step is to generate 3 files DCC_NCE_Probe with extensions ino, cpp and h
1. Create a new project with the label DCC_NCE_Probe. This will present a new file NCE_Bus_Probe with the extension .ino.
2. Using the inverted triangle in the Arduino IDE to create two new tabs. Give these the labels NCE_Bus_Probe.cpp and NCE_Bus_Probe.h
It is possible to start generating the files at either end.
For example, in the *ino file there needs to be a function/method to read the bytes on the NCE bus. That is a method of the form handleByte(). (In this example it is wait_for_myaddress( ) which handles all the bytes).
Alternatively, starting with the *.h file there needs to be a class NCE_Bus_Probe that ultimately performs all the underlining detailed work and provides functions available to the client (*.ino) code.
Possible client or *ino code must:
(1) Create an object bus of type NCE_Bus_Probe. For flexiility this can include as a parameter the address of the object. In example address 5 is used
NCE_Bus_Probe bus(5);
(2) Initialise the serial port and write a message to the monitor. The serial port will be used for debugging.
Serial.begin(115200); Serial.println("\n-NCE Twin Probe-");(3)The setup( ) method/function will also initialise the new class NCE_Bus_Probe.
The begin method will include a parameter that determines the amount of information displayed. This is illustrated below
With parameter = 0 all pieces of captured information will be displays plus any messages generated by the code
With parameter = 1 no reads of the data bytes are sent to the serial monitor
(4) Since the basic operation of the project will be to wait until a ping of my address is received and then do something similer to a method bus.wait_for_myaddress() is required,
The implementation code will need to
Specify the pins to which the RS485 bus is attached:
SoftwareSerial RS485(12,11); //Rx Tx
Create NCE_BusProbe object at the address specified by the parameter
NCE_Bus_Probe :: NCE_Bus_Probe ( uint8_t my_address)
{_my_address = 0x80+my_address; };
Implement the begin method
void NCE_Bus_Probe::begin (uint8_t tt )
The begin will in turn initialise the RS485 device{
RS485.begin(9600);
Wait for the RS485 to become available
while (!RS485.available( ))
Implement the method that contiually reads the RS485 bus until my_address occurs
void NCE_Bus_Probe ::wait_for_myaddress()
while (rxByte != _my_address)
rxByte = get_NCE_Byte( );
Implement the method that reads each byte on the bus
uint8_t NCE_Bus_Probe::get_NCE_Byte( )
while (!RS485.available( ));
rxByte = RS485.read();
To handle the NCE data a method wait_for_myaddress() is included in the NCE_Bus_Probe class. This calls the get_NCE_Byte( ) which performs the nuts and bolts operation of reading the data on the RS485 or NCE bus. This returns the data byte to the wait_for_myaddress() that loops until my_address (0x85) is received.
To display the bus activity Serial.print( ) statements are included. Note this display is conditional depending on the variable _trace which is determined by the parameter in the set up begin( ) method.
Also for clarity of the display a new line is created at the broadcast address (0x80) and spaces are added between each byte.
Two traces of the bus activity to illustrate the parameter in the begin method are shown below.
With begin(1) the monitor will display all bus activity. The monitor display following reset. After the messages the code has captured the data 0x80, 0x82, 0x83 .... 0x8A. For clarity the program adds a new line prior to printing each 0x80, the broadcast ping.
With begin(0) the byte activity is not displayed. Only information of the users choosing.
With the NCE bus the controller will occasionally output messages at the broadcast address 0x80. This trace is part of a later project that displys the messages. With begin(0) these messages are not swamped by all the byte reads.
Notes:
The first trace shows the start up code with a number of dots while the RS485 bus synchronizes.
In general the captured data will be the pings to addresses 0x80 through 0x8A (less address 0x81.) as per the above.
Occasionally in the Broadcast state there will be a message. This message could be 2 bytes starting with D4 (telling all controllers to turn on a green light) or 9 bytes starting with 0xC1 - C1 tells LCD to display message on top row to right. The following 8 bytes are the message. In the example " 03:56AMPM"
Looking ahead a following step in the project will be to extract the data from these longer lines. Later projects will do something with the data
Line 1 is a message displayed at the start of the program
Line 2 are dots displayed while waiting for the Bus to become avilable
Line 3 is the monitor message when the project is linked to the NCE Twin
The remaining lines ate the captured data formatted for clarity with spaces and a new line for each broadcast address.
With the NCE Twin the addresses are 80 through 8A with 81 missing. Larger controllers can have addresses in the range 0x80 through 0xBF
Occasionally there will be broadcast messages that may be captured with a monitor program that has a large buffer.
By scrolling through the captured the message 0xD4 0x0A was captured.
To assist explain what is happening the monitor messages as shown are included.
By scrolling through the data a long message has been captured.
Following the broadcast address (0x80) the data 0xC1 is captured. THis is a 9 byte message. The program displays this line plus the start of the next line.