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!

A little update on my Arduino controls

1654 views
7 replies
1 rating 2 rating 3 rating 4 rating 5 rating
  • Member since
    February 2002
  • From: Reading, PA
  • 30,002 posts
A little update on my Arduino controls
Posted by rrinker on Saturday, February 18, 2017 9:26 PM

 A short while ago, I came across a document by Charles Sloane on the Yahoo CMRI group page. In it, Mr. Sloane described a theoretical turnout control module that included local pushbuttons, dispatcher lockout, and dispatcher control. It sounded like a great idea. A little thought and it was obvious using an ATTiny85 as my turnout controller was out, I needed more IO pins. So back to the Arduino Nano. I briefly thought about using bare ATMega 328P chips (same as on the Nano and Uno) but when pricing them out plus a 16MHz resonator plus a bag full of capacitors for both the resonator and proper bypass caps on the power supply to the chip, it seems I cna get Nanos for less and I would not have to build another ISP shield to program the ATMegas 328 like the one I built for ATTiny85s. And mounting a Nano in a more complex circuit is no bif deal, just lay out 2 rows of female header pins and the Nano plugs in like an oversize IC.

 Something that you may or may not know, the analog pins can be used as digital inputs or outputs, and they just carry on the numbers - standard Arduino naming has D0-D13, and then on the Nano you have A0-A7 (Nanos have 8 analogs, Uno only has 6, A0-A5). Well, A0 is also known as D14, A1 is D15, etc, So what you get on a Nano is D0-D21, 22 total digital pins. D0 and D1 can be used but you have to be careful or you might not be able to use the USB port to program the Nano without disconnecting your circuit. Doing a quick pin round up, without doing any fancy tricks, just 1 pin to 1 function, I found I would need to have 8 pins per turnout. (sidetrack: I tried a few methods of using the same line for both the pushbutton AND the LED. None of them was very satisfactory and there is potential for problems in some cases if say both buttons were pressed at the same time. I could also save a line by using a single button to toggle, but I prefer one button per direction, so on a fascia diagram I can lay it out so that you push the button where you want the train to go, not press the button and look to see if the LED shows the correct route).

 Pins used: 2x input for pushbutton. 2x for output for indicators. 1x servo output, 1x remote control signal (internal pullup, high/open is normal, low is reverse), 1x dispatcher lock control (internal pullup, high/open is unlocked, low is locked), and 1x output for lock indicator LED (on = turnout locked by dispatcher).

I have this all working on a breadboard, for one servo. The only thing left is to add code to remember the last position so when the layout powers up, the turnouts all go to wherever they last were. The active low input for the lock means if I power up everything EXCEPT the dispatcher system, all turnouts will be unlocked and controlled manual for casual running. Two servos per Nano, and completely avoiding already used pins like 0, 1, and 13.

 For non-dispatcher controlled turnouts, such as a yard, for single I will still use the ATTiny 85. They have enough pins for 2 buttons, 2 LEDs, and the servo. Without the remote control, lock line, or lock indicator, I can get 4 servos to each Nano.

 That's progress so far - I really only worked on it two evenings, many nights I had an idea that i was going to finish this up and then never got to the workbench. Tonight I finally did it and cranked it out in short order.

                      --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
    March 2012
  • 63 posts
Posted by crusader27529 on Saturday, February 18, 2017 10:47 PM

Just a recomendation for saving the state of your system.....I used the EEPROM on the NANO, but to prevent writing to the same locations continuously, I designed a simple database into code. Simply put, a unique data value needs to be chosen as an End-of-Data marker, so the code can tell where the current data is saved. Each time the data is saved, the loction where it's saved is incrimented by the number of bytes needed to hold the data, and the END code is written. You need to allow for hitting the end of the storage and wrapping back to the start, but at startup, the code scans the memory looking for the END code, and that gives the location of the last written data. Each time the data is written, it overwrites the END code with new data, and writes a new END.......it works very well.

  • Member since
    July 2009
  • From: lavale, md
  • 4,640 posts
Posted by gregc on Sunday, February 19, 2017 6:58 AM

rrinker
 Pins used: 2x input for pushbutton. 2x for output for indicators. 1x servo output, 1x remote control signal (internal pullup, high/open is normal, low is reverse), 1x dispatcher lock control (internal pullup, high/open is unlocked, low is locked), and 1x output for lock indicator LED (on = turnout locked by dispatcher).

My understanding is some pins can be used for either digital or analog (ADC, PWM) functions.  Instead of 2 digital inputs, could you use one ADC input.

The input is tied to 2 resistors, one tied to V+ the other to ground.   A normally open switch is wired across each resistor.   Pressing a switch either pulls the input to V+ or Gnd.   Should be able to test for > 2/3 V and < 1/3V.

a bit hokey.  a little more processing.  but saves a pin if pin count is important. 

greg - Philadelphia & Reading / Reading

  • Member since
    February 2002
  • From: Reading, PA
  • 30,002 posts
Posted by rrinker on Sunday, February 19, 2017 10:05 AM

 I've actually already worked out a scheme to manage the EEPROM to get around constantly writing to the same location. Since in a case like this I always know how many bytes I need to write (2, one for each servo), I then add a third byte which functions as a 0-255 counter. I also designate one EEPROM location as the pointer. First step is to read the pointer, that tells me where my data is. Then I read the data. Every time a change is made, the data is rewritten with the counter incremented. When the counter rolls over, the pointer is incremented, in this case by 3, and rewritten. I calculated that if you changed the position 10 times a minute (far more than it really would) for 4 hours a day, 7 days a week, it would be some ridiculous number of years before any location got 100k writes, and the pointer would be well under 50k writes at that point, well within specs. It works out to some 80+ years. Maybe if my layout is still being operated by grandkids or great grandkids, they'll have a puzzle to figure out when the EEPROM finally stops working reliably. Edit - running it 7 days a week every week of the year brings it down to about 40 years. But again this is changining the switch position 10x a minute for 4 hours a day - no one is going to come close to that. The servo or the turnout will wear out mechanically before those numbers are hit.  

 

Greg - that may work, but I suspect a bit more fussy if the buttons aren't fairly close to the controller. The real unicorn is 2 buttons/2 LEDs with just 2 pins, but with the Nano and keeping it simple I have enough pins available to not even double up any of the standard ones like 0 and 1 for the USB and even 13 doesn;t get used - maybe I'll have that blink as the loop is traversed so it can be a heartbeat to show the code is running. For the actually controller unit I will be using shift registers and parallel to serial converters to expand the pin count. As much as it saves wires and pin count, I don't think I will have any logic for the signals at that point, since hardware logic restricts the signal wiring to specific schemes. One pin per LED in each head is ultimately flexible, at the cost of more wires and an extra shift register or two depeneding on how many signals a given node will be controlling. Cheap enough to keep it simple since I'm not making thousands of these. If I was designing something to manufacturer in large wuantities - yeah, it would probbaly make sense to reduce relatively expensive shift registers with cheap logic.

                             --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 Sunday, February 19, 2017 10:58 AM

rrinker
...I could also save a line by using a single button to toggle, but I prefer one btton per direction, so on a fascia diagram I can lay it out so that you push the button where you want the train to go, not press the button and look to see if the LED shows the correct route)...

 

Here's a neat trick for using a single pin for more than one input if the pin can be used as an analog input:  You can have one button connected straight to ground, a second connected to ground through a single diode, a third connected throught 2 diodes...(up to seven buttons if using a 0-5 volts).  The first button generates 0 volts on the AD input, second button generates ~0.7 volts, etc.   The only issue I've seen with this method is you can only see one button at a time, i. e., if two or more buttons are pressed at the same time it looks to the AD converter like only the one with the fewest diodes is pressed.  That actually might work well in this situation because you could have the dispathcer as the 0 volt input and when it' slow you are not concerned with the other inputs anyway.

  • Member since
    March 2012
  • 63 posts
Posted by crusader27529 on Sunday, February 19, 2017 11:46 AM

Does the pointer also 'move' through the EEPROM array as the data is updated? The 'flag' method allows the position of the 'flag' to be the pointer, so no pointer is actually stored....when the data is searched at power on, the pointer value is the location of the flag that it finds.

  • Member since
    July 2009
  • From: lavale, md
  • 4,640 posts
Posted by gregc on Sunday, February 19, 2017 3:33 PM

here's a circuit (on right) that turns on one of two LEDs with a single pin.

rrinker
The real unicorn is 2 buttons/2 LEDs with just 2 pins,

greg - Philadelphia & Reading / Reading

  • Member since
    February 2002
  • From: Reading, PA
  • 30,002 posts
Posted by rrinker on Sunday, February 19, 2017 4:01 PM

 The pointer stays put. The counter moves. So in myu case I am saving 3 bytes of data, 256 times in locations 0-2, then 256 times in 3-5, etc.

With 1024 bytes I have 340 pointer values. I could sneak in 341, using location 1023 for the pointer, but I'll sacrifice the 3 bytes for a little headroom.

With 256 times per block, that gives me 87040 updates per loop through the whole memory. That causes the pointer to be updated 340 times.

With a specified duration of 100k writes, 256 per block results in 390 times I can repeat this loop. 390 times would exceed 100K writes to the pointer, at the limit of 100K writes, I can run the loop 294 times. 294 time through the loop is 25,589,760 updates. Now lets say I run trains 4 hours a day, 5 days a week, every week ofr the year. And I flip the turnout 10 times every minute. That's 600 times an hour, 2400 times a day,  12000 times a week, 624,000 per year. Dividing that out, it's 41 years. While I would still love to be active with my model railroad 41 years from now, odds are not good. Plus - no one operates a turnout 10x every minute for 4 hours solid. Or has 4 hour operating systems every day of the week.

 A similar calculation with an ATTiny85 which only has 512 bytes of EEPROM gets similar numbers, and for my controller (if I decode to store last settings and not just have the computer refresh them on startup), it would have 11 bytes stores plus counter and the resulting loop count gets me 56 year's worth of saves assuming 4 changes per minute over 3 hours, 3x a week. Still over 22 years at 10 updates per minute. Remember this is only switch position and signal aspects - no point in saving block detection status as it will immediately be known when the power is turned on. No real sense storing turnout position if the turnout controller will do it. This quickly leads to just saving the current railroad state in the computer when shutting down and restoring it all from there.

                     --Randy

 


Modeling the Reading Railroad in the 1950's

 

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

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

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!