Trains.com

Subscriber & Member Login

Login, or register today to interact in our online community, comment on articles, receive our newsletter, manage your account online and more!

Preliminary design for my Arduino-based CMRI node

15572 views
35 replies
1 rating 2 rating 3 rating 4 rating 5 rating
  • Member since
    February 2002
  • From: Reading, PA
  • 30,002 posts
Preliminary design for my Arduino-based CMRI node
Posted by rrinker on Friday, August 11, 2017 4:47 PM

 With the turnout controller nearly done, I started thinkign about my CMRI node design. Like the turnout controller, prototyping is being done using Arduinos, but the final product will be built using bare Atmel ATMegas328P chips since the in use boards don't need things like extra voltage regulators, USB ports, or unused pins.

 To get enough digital pins, I am using Microchip MCP23S17 port expanders. These communicate to the Arduino with SPI, and each one has a pair of 8 bit ports. My basic node will have 5 of these (they are less than $1 each!) for 64 output ports for signal LEDs and turnout control, and 16 input ports for block detectors and switch position feedback (not sure if I am going to do that). That should cover any interlocking I can think of, but just in case I will lay the boards out with a space for an extra chip each on the input chain and output chain (simple code change to add the extra bits - or leave off a chip or two when not needed).

 Most implementations (other than Bruce Chubb's SMINI and SUSIC boards) leave the CMRI node address selection in code, so you have to change and recompile the sketch for each node. Since all I/O on my board comes from the 23S17's, I have plenty of pins to put in jumpers or a DIP switch to set the address in hardware. So far I have the following pin arrangements:

A0-A5 for the address selection, which allows 64 of these nodes. I looked at my prelimiary track plan and it looks like I will need no more than 1/4 that number at most.

D13 for the SPI SCK clock line

D12 for the SPI MISO line - data from the 23S17 to the Arduino

D11 for the SPI MOSI line - data from the Arduino to the 23S17

D10 for the slave select line for the output bank

D9 for the slave select line for the input bank

(note on the last two, the 23S17 has 3 address pins of its own, which allows up to 8 of them on one SPI line, or the 2317 which uses I2C can do the same). The library for the 23A17 allows you to specifiy which data pin is used as the select. So I am dividing up the inputs from the outputs)

D0 and D1 are the serial port

D2 for transmit enable to the RS485 transceiver chips

D3 for a status LED that tells me the loop is running.

Questions? Comments?

                            --Randy

 

 


Modeling the Reading Railroad in the 1950's

 

Visit my web site at www.readingeastpenn.com for construction updates, DCC Info, and more.

  • Member since
    January 2009
  • From: Bakersfield, CA 93308
  • 6,526 posts
Posted by RR_Mel on Friday, August 11, 2017 5:53 PM

Keep up your Arduino information coming Randy.  I for one really appreciate any and all Arduino input.  Thumbs Up  Thumbs Up
 
I have a working 14 block signal system using single light three color H5 signal heads driven with an Arduino MEGA as well as three 14 port Arduino UNOs programmed as Random Lighting controllers for three houses.
 
I also have my remote 180° panable Q5 camera on a depressed flat car working, it uses a pair of Arduino Nanos with Blue Tooth for servo control.  It would be nice if I could find a Q5 camera that works right.
 
I’m working on using Nanos for controlling all kinds of automation, figures, vehicle lighting and operating doors.
 
If my health holds up I plan on replacing my turnout machines with the SG90 servos driven by Arduino.
 
I haven’t been successful using an Arduino as a stepper motor controller for operating a wig-wag crossing signal.  I need help with the programming, I haven’t been able to stop the swinging pendulum (30°-0-30°) straight down.
 
 
Mel
 
Modeling the early to mid 1950s SP in HO scale since 1951
 
My Model Railroad   
 
Bakersfield, California
 
I'm beginning to realize that aging is not for wimps.
  • Member since
    December 2003
  • From: Quebec
  • 983 posts
Posted by Marc_Magnus on Friday, August 11, 2017 6:47 PM

 

 

 

I haven’t been successful using an Arduino as a stepper motor controller for operating a wig-wag crossing signal.  I need help with the programming, I haven’t been able to stop the swinging pendulum (30°-0-30°) straight down.
 
 
Mel
 
Modeling the early to mid 1950s SP in HO scale since 1951
 
My Model Railroad   
 
Bakersfield, California
 
I'm beginning to realize that aging is not for wimps.
 
 
 
 Mel,
 
I beleive but not sure you can find may be an answer on the following blog for step by step motor contol by Arduino.
 
In the case of not, you could probably answer this bloger, he answer at any question about Arduino and share the answer.
 
Good luck.
 
Marc
 
The address is 
 
http://model-railroad-hobbyist.com/blog/geoff-bunza
  • Member since
    January 2009
  • From: Bakersfield, CA 93308
  • 6,526 posts
Posted by RR_Mel on Friday, August 11, 2017 6:58 PM

Marc_Magnus

 

 
 Mel,
 
I beleive but not sure you can find may be an answer on the following blog for step by step motor contol by Arduino.
 
In the case of not, you could probably answer this bloger, he answer at any question about Arduino and share the answer.
 
Good luck.
 
Marc
 
The address is 
 
http://model-railroad-hobbyist.com/blog/geoff-bunza
 

I’ve tried emailing him a couple of times and didn’t get any response, same thing with Bruce Kingsley.
 
Thanks for your input Marc.
 
Mel
 
Modeling the early to mid 1950s SP in HO scale since 1951
 
My Model Railroad   
 
Bakersfield, California
 
I'm beginning to realize that aging is not for wimps.
 
  • Member since
    July 2009
  • From: lavale, md
  • 4,644 posts
Posted by gregc on Friday, August 11, 2017 7:36 PM

rrinker
I started thinkign about my CMRI node design.

could you summarize what CMRI defines?   I assume it's rs-485 based, so what is the packet structure/size?

rrinker
My basic node will have 5 of these (they are less than $1 each!) for 64 output ports for signal LEDs and turnout control, and 16 input ports for block detectors and switch position feedback

is each node fixed?   Have you considered making the number of inputs/outputs configurable at startup through a configuratoin command?

rrinker
 Most implementations (other than Bruce Chubb's SMINI and SUSIC boards) leave the CMRI node address selection in code, so you have to change and recompile the sketch for each node. Since all I/O on my board comes from the 23S17's, I have plenty of pins to put in jumpers or a DIP switch to set the address in hardware.

are you dedicating 5 inputs for address?

you could use optional pull-up/pull-downs on 5 of the outputs that are read at start up to determine the address before programming the I/O pins as outputs

another alternative is to program the address in the atmel EEPROM

rrinker
D10 for the slave select line for the output bank

D9 for the slave select line for the input bank

can you explain the purpose of these?

rrinker
The library for the 23A17 allows you to specifiy which data pin is used as the select. So I am dividing up the inputs from the outputs)

can explain this more?  why divide the inputs and outputs?

I assume there are 16-bit transmitted to/from the device during each interval.  The master (arduinoe) sends an output bit while the salve (MCP) sends the corresponding input.

It's been a while since I worked on I2c.  Doesn't it precede data with an address.   I see the 23S17 uses a !CS.   Does this require a separate data pin to select each chip?

 

 

greg - Philadelphia & Reading / Reading

  • Member since
    January 2014
  • From: Moneta, VA USA
  • 1,175 posts
Posted by gdelmoro on Friday, August 11, 2017 7:37 PM

WOW and I thought Latin was hard to learn Tongue Tied. you guys are on a whole different level!

Gary

  • Member since
    February 2002
  • From: Reading, PA
  • 30,002 posts
Posted by rrinker on Friday, August 11, 2017 8:14 PM

 Mel - I would think the key would be to count the steps and hope the motor you are using has good repeatability. Another way would be to use a servo, you'd have to run linkage up the post but you could definitely stop it facing the right way.

                              --Randy

 


Modeling the Reading Railroad in the 1950's

 

Visit my web site at www.readingeastpenn.com for construction updates, DCC Info, and more.

  • Member since
    January 2009
  • From: Bakersfield, CA 93308
  • 6,526 posts
Posted by RR_Mel on Friday, August 11, 2017 9:01 PM

rrinker

 Mel - I would think the key would be to count the steps and hope the motor you are using has good repeatability. Another way would be to use a servo, you'd have to run linkage up the post but you could definitely stop it facing the right way.

                              --Randy

 

 

Thanks Randy
 
I haven’t dinked around with that sketch in several months and I can’t remember where I left off.  When I saw Bruce’s Wig-Wag I wanted one, actually several.  Bruce used some 4mm diameter 2 phase 5 volt 4 wire stepper motors.  I bought a sack full off eBay along with a matching driver board.  As I remember it didn’t take much to get it to swing 60°.  I’m still interested in getting one going but frustration got the best of me.
 
I had similar problems with my signal system but conquered it by simply using a truth table.  Super simple and easy to do once I got rid of a sample sketch of the Internet.
 
I’m using a single servo with a .015” wires to operate two Wig-Wags at one crossing.  I figured out a way to use a micro LED in the swinging pendulums and they look real sharp.  They are 5’ in on my layout so it’s hard to see the actuating wire but I still want to use the tiny motors.
 
The Arduino programming is getting easier to do but I don’t have enough patience to get some things to work the way I want.
 
 
Mel
 
Modeling the early to mid 1950s SP in HO scale since 1951
 
My Model Railroad   
 
Bakersfield, California
 
I'm beginning to realize that aging is not for wimps.
 
  • Member since
    February 2002
  • From: Reading, PA
  • 30,002 posts
Posted by rrinker on Friday, August 11, 2017 9:23 PM

Inline replies..

gregc

 

could you summarize what CMRI defines?   I assume it's rs-485 based, so what is the packet structure/size?

CMRI defines the protocol over an RS-485 interface. It's actually been adopted by the NMRA as an alternative LCB protocol - and it's WAY easier than CAN. The full specs are in the various CMRI articles Bruce Chubb has published, and also at the NMRA: 

https://nmra.org/sites/default/files/standards/sandrp/Other_Specifications/lcs-9.10.1_cmrinet_v1.1.pdf

 

gregc

is each node fixed?   Have you considered making the number of inputs/outputs configurable at startup through a configuratoin command?

The CMRI protocol does provide for a configure packet but my goal was to simplify it and used fixed packet sizes - any unused bits would juet be 0, or 1, whichever. My master computer program (or anyone's, really) needs to know what devices use what bits on what node - ie, it needs to be programmed such that Signal East 5 is bits 0,1, and 2 of byte 3 on node 6. Rather than customize each node's definition and have the corresponding code to build the transmission strings of different sizes, I was planning to just always send 64 bits, and the node to always send 16. Even if the node only drives a simple passing siding with 20 LEDs (3+2 on points side, 2 head dwarf on exit to siding, 3 head on main side, x2) , 2 turnouts, 2 locks, and 6 detectors (main in, OS section, siding between turnouts, main between turnouts, other OS section, and other main). My layout will be double tracked so every OS section will have more outputs needed. This is all subject to change, but my main goal was simplification.

 

gregc

are you dedicating 5 inputs for address?

you could use optional pull-up/pull-downs on 5 of the outputs that are read at start up to determine the address before programming the I/O pins as outputs

another alternative is to program the address in the atmel EEPROM

 Since even after I do that, I have 7 pins unused, 'wasting' 6 for an address switch doesn't seem so bad. I originally was going to do it the same way the cpNode is designed, which is set in the firmware by a defined constant. But then I'd have to program each node's micro individually and change the address. Same if I stored the address in the EEPROM. The SMINI actually has 7 pins used just for setting the address, all of PA on the PIC plis PC4. Since nothing on the board uses analog, using the analog pins as inputs seems like a decent plan. And 6 bits is plenty, since I will never need more than 64 nodes.

 

gregc

can you explain the purpose of these?

can explain this more?  why divide the inputs and outputs?

I assume there are 16-bit transmitted to/from the device during each interval.  The master (arduinoe) sends an output bit while the salve (MCP) sends the corresponding input.

It's been a while since I worked on I2c.  Doesn't it precede data with an address.   I see the 23S17 uses a !CS.   Does this require a separate data pin to select each chip?

 The MCP23S17 uses SPI, not I2C. So you have 3 lines, Master Out,Slave In; Master In,Slave Out; and SCK, the clock. All slave devices are wired in parallel with those 3 lines, and then there is a chip select on each one that is how it determines which device you are talking to. Thus the use of D10 and D9 as selects. The 23S17 ALSO has an address so like I2C, you send an address first so it knows which chip to talk to. The chip select gets connected in parallel like the other 3 lines. The 23S17 has 3 pins for address select, so you can have up to 8 in one chain. But those are address bits 1, 2, and 3 - internally the 23x17 chips are dual 8 port, each with it's own address. 

I wanted to split out the input and outputs because initially I was planning a lot more outputs and inputs as the standard device - I've actually pared it back. I originally would have had more than 8 chips. So I split inputs and outputs. It also simplifies programming - on each power up the chip registers have to be initialized for input and output, and the driver library has a handy function that reads or writes all 16 bits of a given chip in the string.

 

                                    --Randy


Modeling the Reading Railroad in the 1950's

 

Visit my web site at www.readingeastpenn.com for construction updates, DCC Info, and more.

  • Member since
    July 2009
  • From: lavale, md
  • 4,644 posts
Posted by gregc on Saturday, August 12, 2017 3:14 PM

rrinker
CMRI defines the protocol over an RS-485 interface. It's actually been adopted by the NMRA as an alternative LCB protocol - and it's WAY easier than CAN. The full specs are in the various CMRI articles Bruce Chubb has published, and also at the NMRA:

  https://nmra.org/sites/default/files/standards/sandrp/Other_Specifications/lcs-9.10.1_cmrinet_v1.1.pdf

thanks for the reference.   Not sure this is exactly C/MRI

they describe an RS-422 inteface which is 4-wire, duplex transmission in both directions.  They show nodes wired in a daisy chain, so devices must re-transmit packets not intended for them to the next device, in both directions.

You mention using RS-485, which is half-duplex, and I believe more common.   Every device sits on the bus and no retransmission is required

Their packet size appears dependent on the reception of an end-of-transmission (ETX) byte.  This is why they use a data link escape (DLE) byte, so that data with the same value of ETX can be sent.  Adding a packet size byte to the header might simplify things.   Not sure about synchronization.

they have 4 types of packets: initialization, poll, transmit and read.

 

I think CMRInet is a bit complicated for the things being discussed and based on my understanding of the Pacific Southern control system.    It's intended to simplify wiring to obtain state that is constantly in flux which is different than receiving infrequent commands from a device such as a DCC handheld.

Sounds like you're borrowing ideas from it, not implementing it exactly.  Do you intend to have the slaves sends responses only when its input state changes?   If so, what happens if the response packet is corrupted?

 

rrinker
The CMRI protocol does provide for a configure packet but my goal was to simplify it and used fixed packet sizes - any unused bits would juet be 0, or 1, whichever. My master computer program (or anyone's, really) needs to know what devices use what bits on what node

Not sure if you plan on having both address and type bytes in the header.  An address might would be sufficient if a single bit were used to indicate that the packet is not common data, a command/configuration packet.

A configuration packet can be used to configure the number of I/O and which are outputs.   This would avoid the need to have a fixed number of I/O or number of inputs vs outputs.     This would allow all configuration information to be in the master.   The master could query the node to verify it has the correct number of I/Os (multiple of 8) and then confgure GPIOs as input or output.

flexibility will be important during early development and installation when plans need to change.

CMRInet either transmits data to the node or sends a poll and receives a packet back from the node.    

I think a more common approach for this type of application is for the master, as you said, to send the number of bytes the node supports regardless of whether they are outputs or inputs and with each transmission, the node immediately sends back a packet with the same number of bytes containing all the input data.

You mention fixed byte packets but not whether you intend to poll each time or have the node respond to each transmission.   Would you describe the packet structure and protocol you intend to use, if different than CMRInet?

 

have some questions about the MCP interface that can wait

greg - Philadelphia & Reading / Reading

  • Member since
    February 2002
  • From: Reading, PA
  • 30,002 posts
Posted by rrinker on Saturday, August 12, 2017 6:31 PM

 Yes, Bruce uses 4 wires for the connection - but it's still half duplex RS485. The node and master never transmit and receive at the same time. It's all polled, there is no "input changed, so send a packet to the master" mechanism at all. So there are no collision issues. If you look on the actual hardware, like the SUSIC, SMINI, or cpNode, the TX in and TX out on the boards is tied together, as ire the RX In and RX Out pins. So TX from the master is connected to the RX of all slaves, and the TX of all slaves is connected to the RX of the master. 

 Any varying transmissioon size must be managed by the master - there is no parameter in the protocol for total packet size. All you have is the start (STX), an address, a command, the data bytes, and an end (ETX). It's actually ridiculously simple - look at the source for either the CMRI Arduino library, or the cpNode. All I'm really doing is dropping the Initialization message since my sketch will hard code the number of input and output ports on the node. Each Transmit from the host will send 8 bytes in the data portion, even if the particular node only has 5 bytes worth connected to hardware. When polled, the node will send a 2 bytes, even if there are only 8 input devices attached. The master program has to know the number and location of the bits for a given device regardless if there is a fixed packet size or the packet size varies per node. I'm thinking along the lines of a multidimensional array in the master to store each device. 4 dimensions, in fact - one for the node address, one for the byte, one for the starting bit position, and one for the number of bits. So if Signal East 4 is a standard 3 LED signal attached to the the first 3 bits second port of node 3, it's value might be something like 3,1,0,3 meaning node 3, second byte, bit 0, for 3 bits. The start bit position and number of bits is used directly to extract the values for a specific object. 

 Other than not using an I message type, the packets will be the same format as standard CMRI.

                                      --Randy

 


Modeling the Reading Railroad in the 1950's

 

Visit my web site at www.readingeastpenn.com for construction updates, DCC Info, and more.

  • Member since
    July 2009
  • From: lavale, md
  • 4,644 posts
Posted by gregc on Sunday, August 13, 2017 5:45 AM

rrinker
Yes, Bruce uses 4 wires for the connection - but it's still half duplex RS485.

my understanding is that 4-wire RS-422 can be used half-duplex but separate wires are used for transmission in each direction.  RS-485 has only 2-wires and transmission in both directions uses the same wires.

RS-422 and RS-485 line interfaces are different.   Looks like C/MRI and CMRInet require RS_422.

in your original post you identify an I/O (D2) to be used for the RS-485 transmit enable

rrinker
Each Transmit from the host will send 8 bytes in the data portion, even if the particular node only has 5 bytes worth connected to hardware.

are you going use the data link escape when sending date bytes that have the same values as SYN, STX or ETX, or are you not going to worry about synchronization?

rrinker
When polled, the node will send a 2 bytes, even if there are only 8 input devices attached.

rrinker
So if Signal East 4 is a standard 3 LED signal attached to the the first 3 bits second port of node 3, it's value might be something like 3,1,0,3 meaning node 3, second byte, bit 0, for 3 bits.

It's not clear if polling only reports inputs that have changed or if a separate msg is sent for each group of input bits that have changed.

why not just send 8 bytes back?   Is bandwidth a concern?  is each node sequentially updated and polled?

 

Is the future benefit of being CMRInet compatble that you can possibly use complient boards in the future?   But such board would require RS-422

greg - Philadelphia & Reading / Reading

  • Member since
    February 2002
  • From: Reading, PA
  • 30,002 posts
Posted by rrinker on Sunday, August 13, 2017 12:06 PM

 I assure you, it is multi-drop RS485. The nodes are all in parallel along the transmision line. There is no retransmission from node to node to pass the data.

See here: 

https://cdn.shopify.com/s/files/1/0947/9088/files/CHG04_SMINI.pdf?4186001288561530172

This is the information (including schematic and parts list) for the SMINI. The main reason for the seperate receive and transmit lines is, as described by Bruce Chubb, to make it easier to debug. One pin of the micro is used to enable the transmit on the serial driver chip of the node that needs to respond to a poll request. All others are held tri-stated.

 If you look at the cpNode, they do it differently. They don;t use a controlled pin for TX Enable, they built in what they call AutoRTS using a 555 timer to periodically assert the transmit enable on the MAX489 they use for interface. Schematic here: 

http://www.modelrailroadcontrolsystems.com/content/cpNode_Schematic_v20.pdf

 Note they use a 14 pin MAX489 full duiplex chip while the Chubb design uses a pair of MAX487 half duplex chips. Also you can see how the serial lines connect through the pair of connectors on each board. You wire them point to point, one board to the next, but the topology is a multi-drop bus. The tap is on the board so you don't have to rig up feeder drops off the signal bus.

 Yes, I will still use DLE, you have to, to handle cases where the data happens to match the STX or ETX. SYN is not escaped, the SYN serves miostly as a spacer in the data stream, the code doesn't look for it, only the STX to start a data stream, so an in-stream SYN wouldn't throw the processing loop off like an STX or ETX would.

 As for the packet sizes - fromt he host tot he node I would send 8 bytes, that's kind of the idea, to make them all the same. There are 64 bits of output on each card, so 8 bytes gets send, always. If there is no train near the area controlled by a particular card, the signals and turnouts would not change, so it would in many cases be 8 bytes unchanged fromt he last time it updated that node, but in general that's how it works - it doesn't just send changed data, it sends the whole thing. Sending only changed data would greatly complicate the protocol, sending all of it every time means the receive code just has to chift it to the MCP23S17's and that's all. Data sent back in response to a poll would send 2 bytes, fromt he 16 bits of input on each node. There's no need to send back the output bits, the master already knows what those values are, and the same thing goes for sending all vs just changed, just changed data would mean complex encoding and decoding and in the end the protocol overhead would mean it has to send a lot more than if it just sent all 16 bits each time, changed or not.

 That's the beauty of what Dr. Chubb came up with here - it's really dead simple. On the JLC web site there are other freely downloadable parts of the various CMRI books that show BASIC code for the master side, and there are at least 2 CMRI libraries for Arduino that are open source, plus the code for the cpNode is also released under Creative Commons so you can look at that. The nodes really do nothing other than take an input data stream and shift it to output drivers, and read the input ports and create an outgoing data stream. Though the Arduinoo CMRI code is non-blocking, so the loop() continues to run and you can add additional code.

 Everything is controlled from the master. Typically it is sequential, send to node 1, 2, 3, etc then poll node 1, 2, 3, etc. However, nothing prevents mixing this up if needed, althought here is little need. I calculated out some transmission rates, although I don't have the document here, it might be on my laptop. Even at a modest 19.2k baud rate with 20 nodes, each one gets read and written several times per second, which is more than sufficient. There's a 6 byte fixed overhead (2 SYN, STX, Node Address, Message Type, ETX) so assuming a message that requires no DLEs, it's 14 bytes send, 112 bits, and the node would send back 6 + 2 bytes or 64 bits. There's no need for super high speed, and the slower you can run it, the longer the line can be. Distance limitations, unless the layout is airplane hanger size, don't really come in to play and the driver chip has a limit of 250kbps although there are others that go up to 2.5mbps. Even sticking with say 115.2kbps, each node would be updates well over 10x a second. The amount of data being transmitted is tiny, there is no need for multi-mbps or gbps speeds. Had a similar discussion with my friend the other week - they keep trying t push everyone into using these newer 32 bit ARM core microcontrollers for everything, because they are fast. Yes, but not everything actually needs to run that fast, there are still plenty of applications where a simple 8 bit micro running at 16 or 20MHz is PLENTY fast enough. Do you really need GHz speed and 32 bit ptocessign power to read 40 buttons on a remote control and generate a data stream on an IR LED or an RF module?

                                    --Randy

 


Modeling the Reading Railroad in the 1950's

 

Visit my web site at www.readingeastpenn.com for construction updates, DCC Info, and more.

  • Member since
    July 2009
  • From: lavale, md
  • 4,644 posts
Posted by gregc on Sunday, August 13, 2017 3:06 PM

still confused about RS-422 vs. 485.   That can wait

 

Chubb obviously had other applications in mind.   Again, what is the benefit of implementing C/MRI instead of just developing you're own apporoach?

rrinker
Everything is controlled from the master. Typically it is sequential, send to node 1, 2, 3, etc then poll node 1, 2, 3, etc.

for this type of application, receiving updates from the nodes is critical.  The master knows when outputs need to change, but it doesn't know when inputs change.  It doesn't need to send a TX message, but what if there's a transmission error.  So why not just transmit an update which serves as a poll?

A minimum packet is 6 bytes.   A poll requires 6 bytes.   Instead of a TX packet (14 bytes), a Poll (6) and a response (8) for each node, total 28 bytes, a TX + response is only 22 bytes and eliminates processing (both generating and recognizing) of the poll packets.

at a modest 9600 bps (1 byte / ~msec) there can be ~35 (with poll) and ~45 (w/o poll) nodes serviced every second.

 

 

 

greg - Philadelphia & Reading / Reading

  • Member since
    February 2002
  • From: Reading, PA
  • 30,002 posts
Posted by rrinker on Sunday, August 13, 2017 10:41 PM

 I'm lazy? Since someone has already done it, I don't have to design a protocol and the implementation both in C++ on the Arduino and VB or VC# for the PC side.

 I actually was initially considering using Loconet, as there is an Arduino library for that as well, since I will already have a Loconet connecting my DCC system. There is even a .Net library, Percli's RR-Automation, so I wouldn't be stuck with JMRI (I despise Java as a programming language). However, compared to CMRI, the Loconet protocol is a hundred times more complex. I also considered Ethernet and also various wireless systems, but the last thing I think I need is MORE stuff trying to share the 2.4GHz spectrum, plus there's still the issue of complexity of the protocol.

 Yes, Chubb had many other uses envisioned for CMRI, many of them are int he original 80's series in MR, like Computer Block Control and Computer Cab Control (this being pre-DCC, the object was to let the computer handle all the block toggle flipping so you could just drive the train). But even those boards were controlled via the exact same protocol.

 I think you're missing part of how it works. It's designed to run with the nodes being purely slaves, answering only when polled. There's no requirements for the conversation to be TX, Poll, Receive. In fact, the more typical way it works is that the nodes are polled until a node requires an output update, in which case a TX is done. Even if sequential - things are still read plenty fast enough. The inputs are latching, so even a pushbutton press won't be missed. Even if there is an error on one read, with multiple reads per second, a good value will get through more than fast enough to properly update signals and so forth. There are lots of VERY large layouts using CMRI with no lag issues or bad data.

                             --Randy


Modeling the Reading Railroad in the 1950's

 

Visit my web site at www.readingeastpenn.com for construction updates, DCC Info, and more.

  • Member since
    July 2009
  • From: lavale, md
  • 4,644 posts
Posted by gregc on Monday, August 14, 2017 6:38 AM

 

rrinker
I don't have to design a protocol and the implementation both in C++ on the Arduino and VB or VC# for the PC side.

ok, you're using existing libraries for both you master (PC) and nodes

rrinker
I think you're missing part of how it works. It's designed to run with the nodes being purely slaves, answering only when polled.

i believe i understand.  that's why i said it's intended for more sophisticated applications

 

rrinker
When polled, the node will send a 2 bytes, even if there are only 8 input devices attached. The master program has to know the number and location of the bits for a given device regardless if there is a fixed packet size or the packet size varies per node.

you didn't respond to this.   Do the 2 bytes contain all input bits or coding for only the bits that have changed?

greg - Philadelphia & Reading / Reading

  • Member since
    February 2002
  • From: Reading, PA
  • 30,002 posts
Posted by rrinker on Monday, August 14, 2017 10:58 AM

 For both directions, all bits are sent. Trying to do just changed bits makes for an unecessarily complicated decode process - you'd need to send a lot more than 2 bytes in order to send just the 4 bits that changed since the last poll. By just sending the whole thing every time, it's a simple operation to shift them to the 23S17's, or read from the input ones. On the output side, SE(4)'s red LED will always be bit 5 of the 4th byte. On the input side, Block 2 East detector will always be bit 2 of the second byte. If this were all compressed down to only send that one bit if the only thing that happened was that block became occupied, there would have to be a bunch more data to somehow encode that. Not worth the effort, in increased packet size or processing at either end.

 If you look at the code for cpNode, look at the bottom for their Loop() function. There's just 2 lines: Check CMRI (well, the serial buffer) to see if there is any data, and then a call to their function which reads all the input ports and makes the byte stream. Under the CMRI processing, if the message detected is a poll, it does one more read of the input ports, then builds the R message (adds the header infor, inserts DLEs where needed, puts the ETX on the end) and send it. Super simple.

 That's the beauty of CMRI - it's a very simple protocol but it can be used for nearly anything. Being polled, there's no need for any sort of collision detection or avoidance.  Plenty fast for detection and signalling - modern stuff may be faster, but in the era I model and earlier, the signal and detection systems were relatively slow. A signal would drop relatively quickly, because the track circuit was local, but the indication would take noticeable time to reach the dispatcher's console. All those heavy gravity operated relays were slow. CMRI is, or at least can be, fast in comparison. Seems most people don't run it past 19.2kbps even with many many nodes and ports in use. Don't really have to.

                                --Randy

 


Modeling the Reading Railroad in the 1950's

 

Visit my web site at www.readingeastpenn.com for construction updates, DCC Info, and more.

  • Member since
    February 2007
  • From: Christiana, TN
  • 2,134 posts
Posted by CSX Robert on Monday, August 14, 2017 11:03 AM

gregc
still confused about RS-422 vs. 485.

RS-485 is basially just RS-422 with the send and receive pairs tied together.

  • Member since
    July 2009
  • From: lavale, md
  • 4,644 posts
Posted by gregc on Monday, August 14, 2017 4:54 PM

CSX Robert
RS-485 is basially just RS-422 with the send and receive pairs tied together.

that's my understanding, RS-422 is 4-wire and RS-485 is 2-wire.   I don't understand why a 4-wire interface is decribed as RS-485.

http://www.modelrailroadcontrolsystems.com/content/cpNode_Schematic_v20.pdf

 

greg - Philadelphia & Reading / Reading

  • Member since
    July 2009
  • From: lavale, md
  • 4,644 posts
Posted by gregc on Monday, August 14, 2017 5:54 PM

Randy

I believe i understand the nodes and protocol for communicating with them.   A big benefit of using serial communication and I/O nodes is to reduce the amount of wiring, allowing a PC to communicate with a railroad of any size with a single serial port.

 

How about discussing how your master is organized.

I'm familiar with a system on a large layout where there is a lot of hardcoded logic.   In other words, the control program is unique to that railroad.

Another approach is to describe the railroad in a table (file) containing descriptions of the relationships between blocks, turnouts, signals and I/O bits in tables.   I don't know if this is what JMRI is capable of.   Which approach are you planning?

i assume transmission and handling responses to/from nodes is handled as a background process and a foreground process monitors inputs and updates outputs which are transmitted periodically (?).

Do you think main (foreground) processing is simply 1)  updating signalling by sequentially scanning each block for occupancy and turnout positions and 2) monitoring turnout controls on panels and switching turnouts based on interlocking rules?

greg - Philadelphia & Reading / Reading

  • Member since
    November 2013
  • 9 posts
Posted by SETH NEUMANN on Monday, August 14, 2017 9:33 PM

Randy

I love the CMRI on Arduino + i2C and MC23017 expansion plan!  A friend and I designed and built a system like that 4 years and have been using it and installing it for friends for 4 years.  Check out the Arduini yahoo group.  We've presented this at various NRMA regional and National (2014,2015,2016) conventions and the presentations, CAD designs and code are available at www.modelrailroadcontrolsystems.com.

We did the address assignments in the sketch to save hardware. We used Arduino the Leonardo and used the standard assignments for SDA, SCK, TX and RX.  This left 16 lines for i/o on the "cpNode" and we provided optional pads for resistors to current limit the signal drivers.  Then we made IO expanders,(IOX) with one or 2 MCP23017s each for 16 or 32 lines, also with optional resistor pads.  That gives up to 128 lines of expansion --like you say: enough for any interlocking -- or 144 lines total = 2 SMINI. 

anyway, we've got 100s of these out in the field and people seem to love them, please take a look!

Seth Neumann

www.modelrailroadcontrolsystems.com

  • Member since
    November 2013
  • 9 posts
Posted by SETH NEUMANN on Monday, August 14, 2017 11:00 PM

The big advantage of using the 4 wire version is that you can be having different events going on in each direction.  Since the polls are about 50mS per node, this can get to a lengthy poll cycle with inexpensive Arduino based nodes (since they're cheap you can have lots of small ones, close to the devices being controlled).  My partner Chuck Catrania has added some code (in the forthcoming JMRI release but you could implement it in VBASIC pretty easily) where if a node has no changes it simply returns an ACK and the master can move on much more quickly.

We usually run at 28,800 or 56K to keep the polling intervals reasonable on systems with 10 or more nodes.

This is an easy and inexpensive way to set up a layout control bus, and we've found it very robust.  I'm glad to see you doing this and I hope you'll share your designs and code on a forum like CMRI-USERS or Arduini!

Seth Neumann

www.modelrailroadcontrolsystems.com

 

Seth Neumann

www.modelrailroadcontrolsystems.com

  • Member since
    February 2002
  • From: Reading, PA
  • 30,002 posts
Posted by rrinker on Tuesday, August 15, 2017 7:03 AM

 I was wondering if I would attract you tot his thread Seth. I freely admit I have cribbed many of my idea from cpNode. Not sure why this is, but I prefer SPI to I2C so that's why I am using the MCP23S17 instead of the 23017 you did. Maybe because for the expense of one more IO line, I can add 8 more chips, 128 bits more, though the only place I can foresee ever needing that much IO in one place might be a physical CTC panel (which I DO want to build - but that comes very late in the process, as it's much easier to tweak a virtual panel than rearrange a physical one if I need to make changes.).

The idea of adding a simple ACK to indicate no changes sounds interesting, as I will have somewhere around 10-12 nodes. More than I should for a layout the size of my plan, but my plan is also double tracked (which I know wouldn't normally have CTC but I like CTC so...). I also contemplated another of your ideas, to put the local logic in the node more like the prototype, but then I realized how complex the Arduino sketch would get - commands over the CMRI line, plus I would have to get status from adjacent nodes and... while I don't mind programming, it's not my primary thing, I'm more of a hardware guy.

 I'm planning to use plain ATMegas328 chips in mine, originally I was going to use Arduino Nanos and just socket them like you did with the Leonardo, but it's just as easy to put a 28 pin DIP socket, a resonator, and a couple of capacitors and just use the bare chip. I did the same in designing my servo controllers. There's a bunch of extra hardware on most Arduinos that I just don't need - multiple supply voltage input, the 3.3v regulator I won't be using, etc. There is an advantage with the Leonardo since it uses a different micro - it has 2 serial ports so you can have the debugging via serial as well as the CMRI interface. That I will be giving up.

 Code too I will shareThe Arduino side will look awfully much like the code in the cpNode. The master side - one thing I DON'T see is CMRI code in modern .NET languages. Old Visual Basic, and even older MSBASIC is all over. I'm not one to put together a computer of obsolete parts just because it's cheap - I used to be a huge tinkerer that way, ran lots of stuff at home, but since that's also my day job, I hit the point where I just want stuff that works at home, I don't want to come home and spend still more hours maintaining servers and old equipment. Otherwise I probably would have automated several layouts ago using my old Super Elf. In the early 90's I was going to build an original CMRI type system, but alas I had no working bootable disks for my old TRS-80. I actually just acquired a machine that would be perfect for old school CMRI - a NEC PC8801A, which can run CP/M and 8 bit MSBASIC, or MSDOS and 16 bit QBASIC. It even has a serial port, so the interface is there. The only thing is it's an incredibly rare machine in the US, and while it runs 100% at the moment, it IS 36 years old and if I set up a layout that depends on this pretty much unfixable one of a kind machine, I think I am setting myself up for failure, or a lot of headaches. So, modern machine with a .NET implementation is the way I'm going. That way I have the ability to do a virtual CTC panel as well as all the logic. I MIGHT even just use the machine on my workbench upstairs as the railroad computer, it's right above one end of the proposed layout so no long cable run, and it would mean the dispatcher truly can't cheat and look at the layout.

                           --Randy

 


Modeling the Reading Railroad in the 1950's

 

Visit my web site at www.readingeastpenn.com for construction updates, DCC Info, and more.

  • Member since
    February 2002
  • From: Reading, PA
  • 30,002 posts
Posted by rrinker on Tuesday, August 15, 2017 7:13 AM

gregc

Randy

I believe i understand the nodes and protocol for communicating with them.   A big benefit of using serial communication and I/O nodes is to reduce the amount of wiring, allowing a PC to communicate with a railroad of any size with a single serial port.

 

How about discussing how your master is organized.

I'm familiar with a system on a large layout where there is a lot of hardcoded logic.   In other words, the control program is unique to that railroad.

Another approach is to describe the railroad in a table (file) containing descriptions of the relationships between blocks, turnouts, signals and I/O bits in tables.   I don't know if this is what JMRI is capable of.   Which approach are you planning?

i assume transmission and handling responses to/from nodes is handled as a background process and a foreground process monitors inputs and updates outputs which are transmitted periodically (?).

Do you think main (foreground) processing is simply 1)  updating signalling by sequentially scanning each block for occupancy and turnout positions and 2) monitoring turnout controls on panels and switching turnouts based on interlocking rules?

 

 I was more likely than not going with the hardcode approach. As I get deeper into it that may change. Given that at least at first there will be a virtual disoatcher console in my program, it will be pretty much specific to my layout and not a generic program like JMRI. I have no desire to recreate JMRI with a drag and drop panel editor and all that. Plus there will be no logic restrictions, as far as how many conditions I can have on a given element - and if there are only 2, then only 2 will apply, not 2 plus some number of blanks. 

                      --Randy

 


Modeling the Reading Railroad in the 1950's

 

Visit my web site at www.readingeastpenn.com for construction updates, DCC Info, and more.

  • Member since
    July 2009
  • From: lavale, md
  • 4,644 posts
Posted by gregc on Tuesday, August 15, 2017 3:57 PM

randy, what kind of bus are you planning?   i see several possibilities

  1. 2-wire RS-485.   each card taps onto the bus like the NCE cab bus and can be removed without disrupting service to other nodes.  both master and slaves need to be enable TX.   This is required to be half-duplex
  2. 4-wire RS-422 (duplex transmission is possible)
  1. Fig-3 in the CMRInet spec  suggests that packets are received and forwarded to the next up/downstream node.  Presumably two RS-422 interface are required and each node forwards packets not addresses to it either up or downstream.  A node cannot be removed without affecting downstream nodes.   No need to enable transmission of responses.
  2. common buss that each node taps onto.  Node plugs into a socket providing power and access to the bus (like NCE panel jacks).  Nodes can be removed without  affecting other nodes.   Slaves must enable transmission.   (think you suggested this approach).
  3. common buss with daisy chained connections.  Each node has multiple sockets for 2 or more boards to be connected to it as suggested by the cpNode schematic you posted.  Special cables between nodes.   With more than two connections, the network does not need to be linear. Removing a node disrupts downstream nodes.

I think a 2-wire RS-485 bus like NCE cab-bus is the simplist.  You mentioned that Bruce Chubb advocated a 4-wire bus for easier debugging.   But I think RS-485 is less complicated today.

 

greg - Philadelphia & Reading / Reading

  • Member since
    February 2002
  • From: Reading, PA
  • 30,002 posts
Posted by rrinker on Tuesday, August 15, 2017 6:49 PM

 That figure 3 is misleading. The Chubb booards are wired exactly as the cpNode schematic shows, there are two connectors on every board, wired in parallel. It is a multi drop bus, there is no forwarding. The schematics for the SMINI and SUSIC are on the jlcenterprises web site and clearly show the same wiring as the cpNode. The updated SUSIC was also in MR, late 90's or early 2000's I think. The old one int he original mid-80's articles was a straight RS-232 board, no multiple drops at all. Even the current one supports either, depending on which components you populate. On a smaller layout, or where centralizing all the hardware (why?) is desired, the RS-232 option would work. They are ALL like your number 3, except there are no special cables, all cables are the same. Various types of cables are supported, I was considering using UTP, in which case a simple coupler could be inserted in place of a removed board to keep the bus continuous. But unlike a DCC throttle this isn;t something where you would willy-nilly plug and unplug nodes - any change in the nodes, would also require changes in the master program, either because the same node was reused for a different OS section, mening the address is still the same but the logic applied to the various inputs and outputs would need to change, or you are adding a new node which means adding a new address to the polling routine AND the logic associated with the I/O on this new node.

 2-wire and 4-wire is not the only definition difference between RS422 and RS485. In fact the is s spec for 4-wire RS485, but the only prime differnce is the RS422 is generally only a 1 to 1 communications. One device talking to one other device, just over longer distances and higher speeds than RS232 because of the differential signalling. And more noise immunity as well. RS485 is based on RS422 but designed for multiple drops, as is used here. Chubb's design is simply two RS485 interfaces on each card. Yes, it can work with a single pair of wires, if you use a different driver chip (or reqire what's there accordingly, and use only 1 chip instead of two. A look at the SMINI schematic will show you how he designed it, and it's fairly obvious how the schamtic could be altered to use just the one chip since the whole protocol is, in fact, half duplex. No one talks unless polled, and when the master talks, all are listening. There is no periodic access granted to every device, ala token ring, or no state in which everyone is trying to talk ala ethernet. It's like the polled DCC systems. The reduction in throughput as you add mode nodes (cabs) is steady and predictable, but even the gastest speed is kind of slow relative to other methods. Ones that use a CSMA/CD type system are very fast with few nodes, but as more are added, the drop is not linear like a polled system due to too many factors out of the system's control - for example the knob twiddler operator who constantly clicks the speed control between two settings generates a lot mooore network traffic than the operator whoo just leaves the speed control alone until needed based on track conditions or signals or whatever. The old way of using JMRI to do flashing aspects on Loconet for example - signal on....signal off.....signal on...<repeat> absolutely KILLED the network, flooding it with packets just to make oe signal flash. It made it hard to control trains, which is why our club layout has 2 Loconets, one for signals and one for throttles. The modern method has the flashign done by the device, so all that gets sent is a packet that says flashing yellow on signal 35. Once and done, the signal controller flashes the appropriate output. But this is getting off topic.

                           --Randy

 


Modeling the Reading Railroad in the 1950's

 

Visit my web site at www.readingeastpenn.com for construction updates, DCC Info, and more.

  • Member since
    June 2016
  • 21 posts
Posted by ReneZ on Wednesday, August 16, 2017 8:12 PM

Great info, thanks for sharing!! Brgds, Rene

  • Member since
    November 2013
  • 9 posts
Posted by SETH NEUMANN on Friday, August 25, 2017 9:33 PM

Randy:

I've been off line chasing the eclipse for the past week, so I'm a little behind.  Just a couple of impressions as I think you've got a good handle on it.  There are lots of AtMega options and a number of serial expansion options, too.  We chose the Leonardo because it has a completely separate port for programming and serial monitoring, and the Modern Device module was cost competitive at the time.  Subsequently the Arduino IDE support for Leonardo has not been too good and less expensive alternatives have emerged due to widespread piracy of some good designs.  If I were to do it today I would use a Pro-Mino or Nano as they are very cheap (in fact I'd soilder them in, not socket, as commodity pro-minis and Nanos cost less than the sockets!).  Chuck has written some nice CMRI code that will be in the next JMRI release that knows about cpNode and IOX expanders and provides some good diagnostics, provisioning and metrics for all CMRI nodes, but  in any case you can just tell JMRI (or VB Code for that matter) that you're a SUSIC with a given configuration.  The only issue with the serial comms scheme (RS485 multidrop) is managing the poll cycle.  It's best to keep it to 500mS or less (that is 2Hz or better).  You can do that by running at higher speed, we like 28,800 but you can go up to either 56 or 112K (I can't remember which).  By separating the input and output streams you can easily live with the latency in the node (between 25 and 50mS depending on a lot of implementation factors). 

Seth

  • Member since
    February 2002
  • From: Reading, PA
  • 30,002 posts
Posted by rrinker on Friday, August 25, 2017 11:42 PM

I was originally planning to use nanos in all my designs. In fact I got a few packs of them, like 5 Nanos for $8 (that's cheaper than bare ATMega328P chips!). OK, I had to solder the pin headers on myself--whoopie!. I actually was going to socket them - but just using cheap pin headers because a wide format socket is, as you mentioned, more expensive than the Nano. However, while I coontinue to use them as my development platform, plopping in a plain ATMega328 makes it cleaner, IMO. 

 I'm not so sure I would call it piracy, the Arduino hardware design is open source hardware, so anyone can (and does) make and sell them. The only illegal bit with some of them is they use the Arduino name and logo, but most of them don't, and call their boards something-duino so it sound the same but isn't actually Arduino. Quality does vary quite a bit, I don't know that I'd trust some of the ones I have in a long-term circuit, though they all do work and I only had one failure. It was a little flakey when disconnecting the USB, I found a capacitor on the bottom almost tombstoned. So  tried to fix it - my eye, despite using both a fairly high power magnifier AND a rather nice but cheap USB microscope, and SMD do not get along - so I ended up making it worse. Eh, less than $1.50 lost.

 That's another good point about using a 4 wire connection and splitting out the TX and RX onto their own lines. Kind of wonder what sort of speeds Bruce uses on his own layout, he's got far more nodes than I will ever have and his system appears to work just fine. The slew rate limited 1/4 load RS485 chips can theoretically do a maximum of 250Kbps, 115k should be comfortably within the chip capabilities and be plenty fast enough. The older stuff never went that fast yet works well for many people.

 Hopefully I'll have some time this weekend to work on this a little. I did receive some MCP23S17's so I cna breadboard a prototype. I need to work up my master computer software, for a quick and dirty test it doesn;t need to do anything fancy outside of handle the CMRI protocol, but I'm getting hung up on writing classes for US&S style signal and switch levers for a virtual CTC panel. Getting ahead of myself as usual. The other thing that's been puzzling me is just how to handle CTC on double track. Examples of this are few and far between since very few double track mains needed it. I would like to see what the machine looked like as well as just knowing how the signals were handled. I think I have a decent idea on how the signals should tumble down from one home signal at an OS section to the next. Maybe I'm overcomplicating things by trying to signal a double track main for bidirectional traffic. I'd almost be willing to make the whole layout single tracked - would save a lot of space - but pretty much the entire core of the Reading system was all double tracked. Decisions, decisions. Continuous run would be much easier if it were all double tracked. But signalling would be much easier if it were just single track...

                                 --Randy

 


Modeling the Reading Railroad in the 1950's

 

Visit my web site at www.readingeastpenn.com for construction updates, DCC Info, and more.

srl
  • Member since
    March 2008
  • 3 posts
Posted by srl on Monday, May 10, 2021 12:13 PM

Randy,

Did you ever get this working?  I was wondering if you have implemented this on a PCB yet.  Thanks,

 

Steve

Subscriber & Member Login

Login, or register today to interact in our online community, comment on articles, receive our newsletter, manage your account online and more!

Users Online

There are no community member online

Search the Community

ADVERTISEMENT
ADVERTISEMENT
ADVERTISEMENT
Model Railroader Newsletter See all
Sign up for our FREE e-newsletter and get model railroad news in your inbox!