If you have been following along, you already know that the L&NC module 1, lower level is a complex beast. Here’s the state of the accumulated electronics as of today. I’ve talked about quite a bit of it, but there are still key areas to discuss.
Block detection on this first module turned out to be somewhat challenging because of the large number of blocks—24— in a relatively small space.
24 Blocks?
Obviously, the mainline, secondary/yard lead track and a siding are only part of the story. Two big factors in the block count are Red Bluffs Yard (5) and the Roundhouse turntable, tracks and lead in (9). Block arrangement is sometimes dictated by the Peco power routing turnouts I use and the need for insulating gaps; block 11 is ultra small (I’m rethinking the block boundaries here — adding/consolidating feeders and re-gapping is no big deal) because it is at the edge of the module and includes a turnout. The feeder map below will give you some idea of the block layout.
Current sensing takes time.
Regardless of the type of sensor you use, the single most important factor is the time it takes for an ADC (analog-to-digital converter) to read the sensor. On an Arduino board with a 10-bit ADC (most boards), it takes 50 μs; if you need to do 100 reads to get an RMS reading, the total read time will be more than 5 ms; add waiting between readings plus calculation time and you need 80 – 100 ms to read a single current sensor. If you are doing only a few, that should present no problems.
But with 24 blocks you are looking at 2+ seconds to do a complete read cycle at that rate. That is an eternity if you are trying to do more than that with the microcontroller. Frankly, its even an eternity just in the context of BOD, because that 2+ seconds for a read cycle limits how fast the system can respond to changes in block occupancy.
Mayhew Labs Extended ADC Shield
I knew I would need a faster and more capable ADC, so I’ve been working with the Mayhew Labs 14 bit Extended ADC Shield. The Mayhew Labs Extended ADC Shield, which is sometimes available at Amazon, comes in 12, 14 and 16 bit flavors. Bits, in the case of an ADC, determine the smallest detectable voltage out of a given range. An ADC with 14 bits of resolution can divide a 0 – 5 volt range into 16,384 steps (2 ^ 14), making the lowest detectable current (and the detection step interval) 305 μV. In contrast, the 10 bit ADC built into an UNO is capable of only 1024 ( 2 ^ 10) steps, making the lowest detectable current (and step interval) 4.88 mV. That is a huge difference in detection sensitivity.
In addition to sensitivity, the shield is fast, producing a reading in 5 µs. That is 10 times faster than the conversion rate of a built-in Arduino ADC; in fact, the conversion is completed by the time the UNO is ready to execute the next instruction after triggering the read.
The shield and the supporting Arduino Library are optimized to scan the ports sequentially. The system is at its most efficient when you read all the ports in sequence in a single pass. That requires some adaptation of my current sensing methods, although the detection algorithm itself remains unchanged.
The Mayhew Labs Extended ADC shield has eight ports that can be used in one of two fundamental ways: single ended or differential. Single ended — the same mode used by the Arduino ADC — reads each port individually; a sensor is attached to the port and to ground. Differential mode reads and compares two adjacent ports. With CT sensors, each port of the differential pair connects to one side of the sensor creating a complete circuit. CT sensors produce an AC current at the same frequency as DCC; in single ended mode the ADC only sees the positive phase of the cycle; in DIFFERENTIAL BIPOLAR mode the ADC see both phases of the cycle. Accordingly, reading CT sensors in differential bipolar mode will produce the most accurate results and require the fewest reads for calculating an RMS. However, because the DCC cycle is high frequency (8 Khz), its possible to get reasonably accurate results in single-ended mode because the ADC will see multiple positive DCC phases during each read.
It didn’t take many experiments to convince me to use the Mayhew Labs ADC in differential mode. That means the shield is limited to 4 sensor connections. Made little difference inasmuch as I already had a problem with 24 blocks to watch from a limited number of ADC ports. I’ll concede that at $35, the Mayhew Labs shield is an expensive board; but given how cheap the CT sensors are, the overall cost of the system for 24 blocks is under $100. I don’t think it is possible to do the job at this scale with an off-the-shelf BOD system for anything like $100. I anticipate using using the shield in one or two more areas where there are 8 or more blocks to watch.
Muxing/Demuxing to BOD Bliss
I’ve frequently talked about techniques for multiplying digital pins, using shift registers and other devices. It is also possible to multiply analog connections to an Arduino or an external ADC using a Multiplexer/Demultiplexer IC. A mux/demux is basically a device with a common I/O port and 8 selectable I/O ports, plus 3 address lines to select which port is connected to the common I/O. Think of it as a rotary switch with 8 positions, selectable via the address line. The important part is that each connection is isolated from the others so that only one selectable port can be active and cannot by affected by the other ports.
I use the Texas Instruments CD4051B CMOS Single 8-Channel Analog Multiplexer/Demultiplexer [ Digi-Key ]. This functional diagram of the CD4051B show how it works and includes the address bits required to select an I/O channel. [Note: other CD405XB variants have different port arrangements that are useful in other situations.]
To use these, you have to supply power, ground, three digital address lines and an I/O line back to your microprocessor—two power connections and four logic connections. So you are getting a 8 to 1 improvement in analog capacity, at the cost of three digital address lines, which is OK; with connection sharing (sounds odd, but you’ll see it works), my three address lines can control multiple banks of 8 sensors, further improving pin efficiency.
Round Robin Reads
Since I have 24 blocks, and each CD4051B IC supports 8 channels, three groups of 8 sensors seemed like the optimal approach. The idea is to do an optimized read of all three boards on each pass, using the address lines to select which sensors are read. I think of this as a “round robin” technique. I’ll get into the details of the reading technique in second part of this two part post.
I set out to create sensor boards and the very first question that arose was this: how wise was it to have one side of each CT connected to a shared I/O line, with only the other side of the CT’s isolated through the mux/demux? I’m not an electrical engineer, but I had a feeling that connecting all CT’s together on one side might not be a good idea.
I decided to follow my instincts and build two boards using two 4051B’s to fully isolate each sensor. Here are pictures of that version (annotated as much as possible for those who are interested in building their own):
A couple of notes about this board:
- I start with a Busboard Prototype Systems B1 Solderable Breadboard. The board has 6 rails that, with good planning, can cut the number of jumpers you have to use. Use the outer rails for power (+5v on one side, Ground on other); the other two rails on each side can be used to connect sensors to the mux/demux ICs. I didn’t get it quite right on any of them and left some unused rails as a result.
- Use high accuracy resistors at the CT’s so that they are essentially identical. I use 100Ω resistors with .1% tolerance [Digi-Key].
- I get CT sensors in quantity from Digi-Key. I use universal jumper sets that I get on Amazon.
- I have a fetish for power indication LED’s so I know a board is live. I’m starting to get wise about the brightness of today’s LEDs, though, and am using 1K resistors to cut the brightness back (skip the calculations and use a bigger resistor!).
- Once I decided on a connection protocol (see the pictures), building the board is a matter of patiently matching connections per the IC pin-outs — like many IC’s this one will make you wish the designers had shown some mercy in arranging the pin-outs! But basically its this simple: connect channel 0 of mux1 to one side of sensor 0, then channel 0 of mux 2 to the other side of sensor 0. Do that for 7 more CT sensors and you’ll have an eight sensor detection board that is as effective as anything out there. Be consistent about which side of the sensors are connected to which mux.
- I use 22 gauge wire for feeders. I’ve learned to cut feeder leads for each sensor when I build the board — about 12″ long. The lead needs to wrap 3 times around the sensor, with a tail on each side for splicing to the feeders and connecting to the power distribution board. This makes the installation process a whole lot easier. The “wrap three times” thing is almost a catechism; 2 times will work but the signal is significantly weaker. This is an induction system, so the more times wrapped the better.
- I secure the wrapped feeder on the CT coil with a dab of hot glue.
- I’m sure you color code your feeders. I recommend that you always read the same rail on all CT sensors.
How NOT to do it.
But, since part of the point of this exercise is to learn and apply knowledge, I also made a single mux/demux version with one side of the CT’s on a shared line. That would simplify wiring and omit an IC; a good thing, right? Reduces your IC count and the number of connections you have to solder. Initial tests on the bench seemed to show that it worked just fine, thus making me further question my sanity.
But then I installed the whole system, and wouldn’t you know that under load my pessimism was rewarded. The odd board produced odd readings, clearly off the norms of the other two boards. Lots of cross-talk was evident; occupancy of one block would cause other blocks to show false readings. I’m sure a real electrical engineer would find that pretty funny and predictable.
Here is a picture of the errant board. I put this here as a warning NOT to do this or you will be profoundly disappointed.
The Interface board.
To consolidate the three boards and their connections, I had to create an interface board.
The trick here is that the address lines are shared; address lines set the same address on all three boards at the same time. So, when a “round robin” read cycle occurs, the same channel is read on each board on each pass: the first pass is channel 0, next channel 1 and so on.
To Be Continued
I had to modify my current sensing algorithm to accommodate the “round robin reads.” That was easy enough. But when I got around to integrating all the functionality on an UNO, I ran into the proverbial brick wall.
More in the companion post that follows.
Hi just found your site through a recommendation from http://www.dccinterface.com and very impressed with your work on block detection. I am wanting to create a semi automated layout and am fascinated about what can be done with Audrino etc however sometimes gets a little beyond me! Is there a way I could integrate something like your 24 block detector with JMRI over DCC plus to run automated trains?
Hi David,
I’m glad you stopped by.
Your question is a great one. The short answer is yes with a fair amount of effort. I have a fairly clear idea of how to achieve that but I haven’t attempted to do that level of integration yet. So my thoughts reflect untried ideas.
I should say up front for the benefit of all readers that putting all the pieces together for a semi or fully automated DCC layout remains challenging primarily because there are no standards for how to do it beyond the DCC command set. JRMI can bind together the DCC command set and provide a lot of automation…. with limitations.
The single biggest impediment is communication. DCC is a one-way communication standard (on the rail; the command bus is two-way); two-way communication is not part of the rail standard and can only be achieved by slipping data in between DCC commands (see Digitrax transponding). In general (Digitrax transponding not-withstanding) you are limited to issuing commands to a decoder equipped devices, and cannot read back data. I doubt Lenz thought it would be needed, though I think everyone concedes that point now.
What we need is a way of interfacing an Arduino network with a DCC system and JRMI. I recently found DCC PLUS PLUS (https://github.com/DccPlusPlus/BaseStation/wiki/What-is-DCC–Plus-Plus), a system for creating base station that integrates your Arduino with DCC, plus a controller system that works with JRMI for layout control.
My thinking is the DCC PLUS PLUS can be used to bridge Arduino systems like a block detection to the DCC system to exchange information and commands. Typically you are going to use multiple Arduinos on a layout using a networking technology (like ethernet or wifi) to link them together. From a cursory look at the code, I would say it would not be too difficult to combined DCC PLUS with your own communications systems and logic. So, on a MEGA, I would expect to be able to load both DCCPLUS and my other code (such as for the 24 block detector) to achieve a fully integrated device.
So that’s my thinking on the issue right now. I’m working on the next version of block detection made up of small groups of detectors that communicate with each other (and any other device configured for the network). So I’m gradually moving toward semi-automation.
Best,
Robin
Great blog. Have followed for some time and at some point will get back into the hobby.
Don’t know if you have seen these ADS1115 boards. 16bit with an adjustable internal gain, so should give great resolution. It’s also i2c with 7 available addresses. That would allow 14 CTs off two Arduino pins in differential mode. There’s an Adafruit library and a couple of good videos on YouTube of them being used with other stuff.
Thoughts?
https://www.ebay.co.uk/itm/16-Bit-I2C-ADS1115-Module-ADC-4-channel-with-PGA-for-Arduino-Raspberry-F/123600400624?hash=item1cc72870f0:g:hq8AAOSwR6RaDcb9
The price point is better than the Mayhew board.
Can’t really comment other than it sounds like it would do the job. However, one question with any ADC is response time. I found that response time makes a big difference in how well a large scale block detection system works. I settled on the Mayhew card because of its speed.
First, I have to thank you for all work that you’ve done so far; and especially taking the time to answer everyone’s questions. It is much appreciated.
Back to the ADS1115, when I looked it up at AdaFruit, assuming I am reading all the warnings correctly, it can measure 2 to 5.5 volts. Elsewhere, you say that you run DCC at 15 volts. Does that mean we would have to use two voltage dividers in line to get the input level low enough for the ADS1115? Another warning on that product is that voltages must be positive. Does that mean we now have to put a low power schottkey bridge rectifier in line with the voltage dividers? This link is where I found these warnings: https://learn.adafruit.com/adafruit-4-channel-adc-breakouts Seems like a lot of work, that could be better spent downloading a 15k table from digikey, that lists the attributes of the 15k ADC units they sell.
I’m a software guy, not a EE, so I could be way off base.
Again, thanks for all the posts and the responses to our questions.
Hi Charles,
Sorry for the delayed response … my real world businesses have been extra demanding lately.
If I’m reading your post right, you are being confused by the specs. The power specification is for the board itself, and represents the maximum signal voltage the board can handle. IF you are thinking of directly reading a DCC signal, that would not work and would burn out the board because of the higher voltage.
What you need to do is use a current detection device — such as an ACS712 or an induction coil (my preference and best for DCC). Those objects will produce a small current that is proportional to the amount big current being measured. You use your ADC to measure the output from the detection device. The ACS712 is easiest to work with — just read the signal produced by an off-the-shelf ACS712 board. The downside of the ACS712 is that it has a low current detection limit — depending on the model, the limit will be between 10 and 20 mA. That precludes detection of a single resistor axle/wheel on rolling stock, but two or more resistor wheels would be detectable.
Induction coils can sense really low current — a few hundred microamps is detectable — but the coil requires additional components to work — specifically a burden resistor to tune the coil and its feedback current, and (if using the Arduino built-in ADC) a capacitor or voltage divider to convert the DCC full-wave signal to a half-wave, all positive signal. I think the Adafruit ADC is a full wave, differential ADC so you shouldn’t need to rectify the incoming signal.
Let me know if I can help.
Best,Rob
Super job Robin. I can clearly see the cost advantages with NCE BD20’s costing us about $30 each in Australia.
The technical side is way above me though. Wish I had a knack for this like you obviously do.
Great blog.
Well done and thanks for sharing.
Always delighted to know that people find this useful. Thanks!
I certainly understand how the technical stuff can be challenging. My advice to everyone is to take to heart an old joke:
Start small – one turnout, one block, one signal – get that to work, then scale up to the entire layout.
Cheers!