This page illustrates the development of the Class/Library NCE_Bus_Interface.
The code is developed using the private variable "_debug" that will be initialized using the begin() method.
(i) With no parameter of begin(0) the program will execute continuously with the minimum of debug messages. That is minimum number of Serial.print( ) statements.
(ii) With a valid parameter the program will either display debug messages or halt at at specified statement in the code to enable the debug messages to be annualized.
A high level diagram of the system is shown below. The NCE Twin Controller generates DCC signals that will control model trains and accessories.
The NCE Twin also has a RS485 connection designed to interface with other NCE devices. This project will duplicate another NCE device on the bus commonly known as a CAB or throttle.
The front and rear views of the NCE Twin controller used in this project. Note the Twin is only a light version of the professional NCE Controllers.
The basic operation of the NCE Controller is illustrated below. In the case of the NCE Twin it pings the addresses 80 through 8A excluding 81 in turn. If there is a device at that address it should acknowledge the ping or send a request for service
Note originally this project was developed for address 85. When tested on a larger layout address 85 was used so the project was changed to address 86. This diagram has not been changed.
The NCE Bus Activity is given below.
The NCE_Bus_Interface class will monitor the activity and when my_address occurs (Initially 85 but later changed to 86) it will acknowledge to say "I'm Here" or to make a request. (The example used in this project is a macro)
For educational purposes this project is developed in a number of steps defined by the begin(x) method. Depending upon x the program will send messages to the Serial monitor or may even halt to verify the program reached that point.
The notable features of the header file are
(i) the inclusion of the SoftwareSerial library that will be part of the interface to the NCE RS485 bus.
(ii) the declaration of the class NCE_Bus_Interface (uint8_t my_address ) that has a parameter the bus address. This page will assume address 6,
(iii) Two begin methods that will perform any initialization. With a parameter debugging options will be included.
(iv) The program loop that continuously reads the NCE bus until my_address
#ifndef NCE_Bus_Interface_H#define NCE_Bus_Interface_H#include "Arduino.h"
The waveforms below illustrate a captured message.
The program will be testing for a ping address. The ping address can be in the range 0x60 through 0xBF For convenience while testing a statement BUS_PING is defined.
From the document NCE Cab bus protocol-2006.pdf lists other possible messages:
0xc7 print next 8 chars to 4th line right of LCD (addr = D8h)
0xc6 print next 8 chars to 4th line left of LCD (addr = D0h)
0xc5 print next 8 chars to 3rd line right of LCD (addr= 98h)
0xc4 print next 8 chars to 3rd line left of LCD (addr = 90h)
0xc3 print next 8 chars to 2nd line right of LCD (addr = C8h)
0xc2 print next 8 chars to 2nd line left of LCD (addr = C0h)
0xc1 print next 8 chars to 1st line right of LCD (addr = 88h) Note: this is where the clock prints
0xc0 print next 8 chars to 1st line left LCD (addr = 80h)
The waveforms below show the captured activity. The top channel is the received data and the lower channel the response or transmitted data. (ie 7D/7F)
A full trace is shown below. The client tells the controller that it is present (7E/7F). Subsequent responses will be '7D' '7F'
The controller will then send the message CE 40 to my address. This will be a cursor command.
The controller then sends the messages LOCO:000, FWD:000 and -------. This is getting the client ready to set the loco number and speed/direction
An additional statement if (bus.free2send()) bus.setMacro(161); will be added to the client code
void loop( ) {
bus.do_my_address( );
if (bus.free2send() bus.setMacro(161);
}
The header file must include these two additional public methods bool free2send(); and void setMacro(int);
As part of sending data to the bus a sendBuffer will be necessary. A boolean variable _sendbuffer_full will store the status of the buffer. The public method free2send() will send the status of the buffer. That is
bool NCE_Bus_Interface ::free2send(){
return !(_sendbuffer_full);}The resultant trace from start up is as before. The NCE Controller first asks for type of terminal and then sends out messages to disable the cursor followed by a message indicating LOC: 000. (See previous section),
In-between is the message Request Macro 161: Set Macro 5C 51 56 51 40 that indicate the data has been placed in the send buffer.
When in the state OTHER when my address occurs except for the first time the response has been 7D/7F. On the first pass it is 7E/7F.
If there is something in the buffer (ie _sendbuffer_full) this takes precedence over the 7D/7F. ie Send2Bytes485(_sendBuffer[_sendBufferPtr],0x7F); For a macro the first pass will send 5C/7F the 0x5C being a macro request
The photo shows the macro being developed on an NCE CAB. At this point a macro has been requested (0x5C), the NCE Controller has responded with the message MACRO NUMBER: and the cursor commands to place the cursor ready for the first key entry.
That completes the development of the class NCE_Bus_Interface.
The project is now used as part of a model railway system to control several sets of points.