Skip to main content

In response to a different thread that I started, another forum member (John Galt Line) offered to help me with a project to control Atlas switches and led indicator lights with an Arduino.

 I have written the code for the Arduino, and now I am deciding how to send a signal from an insulated rail to the input pin of a shift register. I am thinking about using an AC input optocoupler that would be activated by either the insulated rail section or a momentary push button on my control panel.

Here is the plan (a crude drawing is also attached below):

  • Connect 1 input pin of optocoupler to 10v AC post of transformer through 330 ohm resistor
  • Connect 2nd input pin to insulated rail section and momentary switch
  • Connect emitter pin of optocoupler to DC ground
  • Connect collector pin to shift register input pin
  • Pull shift register pin HIGH by connecting to 5v DC through 10k resistor
  • Shift register pin will change to LOW when insulated rail or switch is activated

 

I would welcome any suggestions. Am I on the right track or is there a better way to do this?

Attachments

Original Post

Replies sorted oldest to newest

For whatever reason I can't read your crude docx but in any event some comments:

- You only need to drive an optocoupler with, say, a few mA.  A 10V AC source thru a 330 ohm resistor into a ~1V optocoupler is overdriving the optocoupler if the output is driving a low-current digital input to a shift register.  That's a peak current of ((10V x 1.4) - 1V) / 330 ohms = 40 mA into the optocoupler.   A 1k resistor is more than enough.

- If you're driving any "modern" digital input, you don't need to pull it up with 10k.  You can lower current by 10x with a 100k pullup resistor.  10k pullups are a holdover from the last century with bi-polar (TTL) inputs.  Anything digital today is CMOS which has negligible input currents.

- By using 100k (instead of 10k) you can use, say, a 0.1uF capacitor across the input to smooth out the AC ripple.  Yes you can "debounce" or smooth the ripple in software but that's just silly if a 1 cent capacitor can do the same.

- Then, if you put that filtering cap on the input you can use a single-ended optocoupler rather than an AC input optocoupler.  AC input optocoupler can run you 2-3 times the cost and are fewer choices.  Of course if you already have a bag of AC optocouplers then never mind.  By using a capacitor as described above it will still filter the half-wave output from a single-ended optocoupler so your digital input still sees a steady DC voltage (no software debouncing).  Then just put in a 5 cent diode on your 10V AC source to feed all your single-ended optocouplers with half-wave DC (so as not the apply reverse voltage to the optocoupler).

 

Here is a circuit I use to generate a clean logic signal to a shift register from an insulated rail:

sensor

Note that I use an RC debounce and feed the signal into a Schmitt trigger buffer to generate a clean transition from a noisy signal. This takes care of the AC ripple as well as intermittent contact between the wheels and the third rail.

Debouncing and filtering could be performed in software, but I originally built the circuit for a microcontroller that had very little memory or processing power, so software debouncing wasn't an option.

Attachments

Images (1)
  • sensor
Last edited by Professor Chaos

Stan,

Thanks for the advice. I wasn't sure how much current the optocoupler needed. I will change the resistor on the input to 1k and the pull up to 100k. I already have some AC optocouplers, so I think I will stick with them. 

Professor Chaos,

Your circuit diagram was very helpful. Do you have any recommendations for a specific part that I could use for the Schmitt trigger. I would prefer a chip with 6 or 8 channels because I have several switches to control. I am a novice, and I'm having difficulty deciphering all the specifications and deciding which part to buy.

 

John

Finally have a moment to get back here, sorry for the delay.

Using the optocoupler from track power as described above should work out just fine, but I'm a little concerned if it would work properly under varying track voltages.  Under command operation it wouldn't be a problem, but in any case I prefer a different method.  

I would use a separate DC power source with its ground connected to the outside rail bus of the layout.  When the insulated rail is bridged by passing wheels it would complete the circuit to allow that DC source to power the optocoupler.  This would insure that the LED in the opto is fully turned on and not over driven.  

Something else to note on the output stage is that you will need to use transistors or some other driver between the shift registers and relay boards or LEDs.  The 74HC595 can supply 25mA on one output, but can only supply 70mA total, so if more than a couple outputs are turned on it will over drive the chip if outputs are directly driving relays/LEDs.  

I looked over the sketch posted in the other thread, and if it does the job that's needed it's great.  It is massively less complex than the sketch I have going.  I have some concerns about what is going on there, but will need to test it out with hardware to see  exactly how it is working and if my concerns have any merit.  

The sketch I have going reads all inputs, stores their values, then decides what to do with them before sending out all data to the outputs.  All this makes for a pretty inefficient program, so I'm hoping that what you have will actually get the job done.  

It isn't really a problem yet, but also just wanted to make sure you're aware that the EEProm in the Arduino has a limited life.  Under normal conditions as used in your sketch it should last many, many, years, but under testing conditions it's life can be quickly expended, so just be aware of that and make sure your code doesn't write to the EEProm any more than it needs to.  

Anyway, that's about all for right now.  

JGL

JGL,

I hope you don't mind that I am working on this at the same time as you. I initially wanted to learn enough so that I would understand what you are doing, but I got interested in the Arduino and decided to go ahead and take a stab at the program. I'm also becoming comfortable with the components so you won't have to hold my hand through the wiring process.

I have an unused fixed 10V post on my transformer that I plan to connect to the optocoupler.  Do you think that would be okay? It would be easy to switch to another source at this point. 

Here is a link to the relay board that I purchased for testing. It uses a separate 12v power supply to run the relays. The relays are activated by a LOW signal from the shift register, and I read somewhere that this only uses 3 mA of current.  I can also power the indicator lights through a relay to reduce current flow through the shift register. Let me know if you think I need the transistors with this setup. I am going to need some help on the transistor circuit if you think it is necessary.

I was aware of the memory issue with the Arduino. I'm trying to be careful while testing, but I will probably shift the storage to a different memory location once I've finished all the testing. The code is written so that it only writes to memory when a switch is thrown and only reads once in the startup.

Let me know if you need an explanation of anything in my sketch. Here is a basic outline of the flow of the sketch:

1. Read all inputs from shift registers (assumes 4 switches to each register, each switch on 2 consecutive pins)

2. Check to see if a timer is running for each input (a timer running indicates that power has already been turned on to the switch coil and led)

3. If the timer has been running less than 1 second then maintain power to the switch coil

4. If the timer is between 1 and 3 seconds then remove power from switch coil (this keeps down chatter from the insulated rail)

5 After 3 seconds reset the timer to 0 unless the input indicates that the insulated rail section is still occupied or a button is being held down. (This way the sketch will keep checking every loop and reset the timer to 0 once it no longer senses a signal from the insulated rail.)

6. If no timer is running then if a signal is present at an input, turn on power to switch coil and led. Also turn off power to opposite led and start timer.

7. Send all outputs to shift registers. ( 2 output registers for each input register. 1 for switch coils and 1 for led's)

I just want to update everyone on my progress. Today I had a successful test on my layout controlling a total of 8 inputs and 16 outputs (8 switch coils and 8 indicator lights). Here is a picture of what I have now:

IMG_20170214_203507760

It's a jumble of wires now, but I found some solderable breadboards that have the same layout as the larger solderless ones I used. I will be able to fit enough components to control 8 switches (16 inputs/32 outputs) on 3 boards. I should also be able to clean up some of the wiring and add screw terminals for connections to the layout.

Thanks to everyone for your help. You gave me a lot of great ideas and kept me from making several mistakes.

Attachments

Images (1)
  • Arduino project

RTR12,

For the first part of my project I used the circuit proposed by Professor Chaos. 

schmittTrigger

I only made a few small changes. I am using 10V AC Hot as an input so I changed the resistor to 1k from 1.5k. The arrow going to AC common leads to an insulated rail section and a momentary push button on the control panel. The AC is connected to this optoisolator , and this is the Schmitt trigger that I used. It is slightly different from the one drawn above because it inverts the output signal. (When the button is pressed or the insulated rail connected, the signal going into the Schmitt trigger is LOW and the signal coming out is HIGH). I had to use this part because I could not find a non-inverting one with through hole mounting. The Schmitt trigger is connected directly to an input pin of a 74HC165 parallel in shift register.  My Arduino sketch requires that the 2 inputs (straight and diverging route) on each switch are connected to adjacent pins on the shift register. I plan to chain 6 shift registers together on one board so I can handle a total of 24 switches. The basic purpose of the Arduino sketch is to make sure that power is only applied to switch coils for a short period of time even if a train is parked on an insulated rail. The sketch also maintains power to the appropriate indicator light and will remember the switch positions even after power is turned off.

The shift registers are connected to the Arduino by 4 wires. The connections are described in the comments at the top of my Arduino sketch. The sketch outputs data to twice as many 74HC595 parallel out shift registers. These are connected to the Arduino by 3 wires. The data is output in the following order: input from the first register (closest to Arduino in chain) is sent to the last (farthest in chain) output shift register. This register controls the relays for the switch coils. The next to last output shift register controls the relays for the led's. The data output continues in this alternating pattern of coil / led control.

I am using this relay module to receive the output from the shift registers. It does not come with instructions, but the only required connections are the 12v dc power source (2.1mm plug), a 5v connection from the Arduino, and one wire from each shift register pin to a numbered pin on the relay board. John Galt Line suggested using transistors to power the indicator lights instead of the relays. I ordered a few transistors, and I am going to experiment with them. At first glance it seems like they would be less expensive and take up less room.

I am planning to build permanent boards to control 8 switches and try them out on my layout for a few weeks before continuing. Let me know if you have any questions about the details.

John

 

Wow, that was a great description of EVERYTHING, Thank You! I need to do a little studying now and look at the data sheets for the devices. I am getting a little better at figuring those out. Also, I think I may have a couple of the parts already and I might try to breadboard this myself. You certainly picked up the Arduino programming very quickly, as well as ALL of the other stuff too. I would agree that the transistors that JGL suggested would make for a smaller package when finished.

The only thing that didn't come through was the picture, it says 'Image Not Found'. I am guessing that it was the same picture that Prof Chaos posted above? If so I will just use his schematic.

Thanks again for taking the time to explain all this and with good parts links too. I am guessing there will be others interested in this as well. Great project and you got is all figured out pretty quickly too. 

Please keep posting your progress and how your testing goes.

Thanks again for the update on the project with all the details!

RTR12,

Yes. The missing image is the same as the professor's diagram. One thing that helped me was to put each component on the breadboard individually to make sure that I knew how it worked. I then started combining components and testing the results. The optocouplers and Schmitt triggers both have pretty simple wiring schemes, so they were pretty easy. The shift registers were more complicated, and I was glad I spent some time experimenting with them.

First off, great work, John.  I'm glad you are getting things to work and you're not having much trouble with the components or Arduino coding.  

I'm still plugging away at this project as time allows, hoping to make a solution that is useable by anyone that wants to throw the parts together.  

Up until now my progress has been pretty much in parallel with the prototype JohnF has posted above.  I use some slightly different components but the functionality is about the same.  As of now, however I'm changing directions as a "less-complex" idea has come to me.  Before getting into that, I figured I'd share some of the layout and such I had completed.  

SMC01SMSMC01BBSMC01PCB

This was the input side of the project, this board capable of sensing inputs for 8 switches.  It also allows for daisy-chaining of several more identical boards to control more switches.  The PCB layout is unfinished as I came up with a new idea to try out while working on it.  It's also not a real PCB design, but instead intended to be built on perforated proto-board in a common 4.5" x 6" size.  

While working on this project some of my main goals were to keep cost as low as possible, and to make it build-able by folks with little experience in electronics.  I used through-hole components for ease of assembly, and used inexpensive, common, components wherever possible.  All told this input module isn't the worst thing ever, but I think I can do better.  The cost is somewhere right around $12 in parts for this half of the circuit, which isn't all that bad, but it is way more complex for that cost than I'd like.  

On to the controller version 2.0:

I'm going to try out replacing the Schmitt triggers and Parallel to Serial shift registers with a micro-controller.  For about the same part cost (in the sort of low quantities we're using here) an Arduino Pro mini can replace 7 IC's on the board.  All of the information I've found so far seems to suggest it's going to work the way I'm thinking it, but I'll need to throughly test before I know.  I may also look to see if it's practical to use just the ATmega chip instead of a whole arduino board.  If that works out I think I can get the parts cost down quite a bit while also making the entire project less complex for someone to build.  

One other factor I'm working on, though not a top priority, is trying to make the final board as small as possible, while retaining the easy to assemble factor.  If I can get the board small enough, it may be practical to use a PCB fab house to make a run of boards, greatly reducing the amount of wiring needed.  At this point the 4.5x6" design would cost about $25 for a PCB, and considering that is only half of the electronics needed for 8 switches, it seems an impractical cost.  If I can get the whole apparatus to fit on a $10 PCB, however, that may be feasible.  Using surface mount parts would help a lot here, but honestly I don't think that contributes to making things easy to assemble. 

Anyway, I'll keep you up to date with what I figure out over the next couple days.  

Ill finish up with a couple design questions for those playing along at home:  

Is it acceptable for all boards/ parts of this system to be located in one place, with input/output wires running across the entire layout, or is it beneficial to allow modules to be placed about the layout at a slightly higher cost per module?  

Also, is it beneficial to have separate inputs for buttons and the anti-derail tracks?  my thinking is that you would want the switch to ignore remote throws if a train is on the switch going the other way.

JGL

Attachments

Images (3)
  • SMC01SM
  • SMC01BB
  • SMC01PCB

JGL,

Thanks for all the diagrams. I like the way you added the connector to make it easy to chain several modules. 

I have a few questions for you:

1) I see that you eliminated the RC debounce portion of the input circuit between the optocoupler and the Schmitt trigger. I guess that makes sense to me because it really just duplicates what can be done by the code in my Arduino sketch. It also makes wiring easier and reduces the number of components that could fail. Would it make sense for me to modify the code to require a more definite input signal? Right now the sketch smooths the output signal (by holding it on for 1 second) but it will act on an input signal as soon as it is received. I could require that the signal be present for 4 or 5 consecutive loops of the code to make sure that an errant signal does not cause a switch to be thrown. Let me know what you think.

2) I noticed that you are using 10k pull up resistors for the Schmitt trigger inputs. Earlier in the thread, Stan suggested that I use 100k instead of 10k to reduce the current used.  Does that make sense to you?

3) Should I add a decoupling capacitor to the 74hc595 shift registers that I'm using for the outputs?

Here are my thoughts about your design questions:

I think it would be okay to have all the modules in one place except for the relay boards. I would like to place the relays close to groups of switches to minimize wire runs and then just have a 16 conductor cable run from the main modules to each relay board. Do you think that would work?

I was also thinking about the question of what to do when conflicting signals are sent such as when a train is on the non-derail track and the button is pushed for the other switch direction. It seems like that could be handled by the Arduino. I could add some code that would prevent an output signal from being sent if there was already a signal being detected from the opposite direction. It would also be possible to have both indicator lights illuminate to show the operator that there was a problem.

John

 

John,

To answer your questions, 

1, No hardware de-bounce:   I'm unsure of the behavior of your Arduino code and what it would do with a changing input.  In the code I'm working with only the first transition matters, so the "button" can bounce all it likes and it will have no effect on the operation of the rest of the code or hardware.  My timers start from that first transition when a button is pressed, and the code ignores all additional triggers of that input pin until it's matched second input has been tripped.  EX: when you press the button to set a switch to 'through' pressing the button again does nothing.  you first must set it to the diverging direction before it will respond to another through command.   Set up this way allows for parking a train on a switch with out the coil being fired.  

All that said, I'm thinking of adding provisions for a hardware de-bounce in the circuit so that the same board can be used to read inputs for devices other than switches such as uncoupler sections and accessories.  I think the final design will include a hardware de-bounce, but also be designed such that the components can be omitted if de-bouncing is not needed in the intended application.  

2, Pull-up resistors:  100k Ohms should be just fine and would reduce current draw as stan suggests.  10k Ohms is sort of a generic pull-up value and I didn't put any thought into it.  I will probably take some time to optimize the value of several parts before establishing a "final" design.  

3, Decoupling capacitors:  At the speed we are sending data with the Arduino's shiftOut function and over short distances between the Arduino and the shift register of a couple inches, you could probably get away without the caps if you really wanted to.  That said when working with reasonably high frequencies it's a good idea to use them.  If using the Arduino's SPI bus to send shift data then the decoupling caps would become necessary.  For the 5 cents or so per cap I would recommend using them.  


On the board location, also remember you nee 16 wires for the inputs from the anti-derail isolated rails, 16 more from push buttons, and 16 more for dwarf/panel indicators.  That's a lot of wires.  I can get by with 4 wires between each module instead of 18 (16 data, Power, and Ground).  I'm thinking of adding a RS485 chip to each module here, allowing for distances between boards of easily hundreds of feet, but this would add about a dollar to the cost of every module. It also makes the coding and hook-up a bit more complex.  Another option I'm kicking around is adding Bluetooth or similar radio transceivers to each module that would allow all the data to be sent between devices without any data wires, just a power source.  Cost is similar to RS485 at about a dollar per radio, but the code is significantly more complex to make this work, and it may have range or interference issues in some installations.  Over all I like the radio method the best because it allows for really easy installation, but I'm not really decided one way or another. For modules places near each other ( within a couple feet) the Arduino's built in I2C interface would work great, but that requires all the parts of this system to be in one place with over 60 wires running about to various switch machines, buttons and signals.  Over all just thinking about ways to reduce that mess.  

On the second topic, yes, it is not hard to do the code to prioritize the anti-derail inputs.  The difference is that you need a second set of 16 inputs to do this, so a whole extra input board.  I'm thinking of programing for the option, then letting folks decide if they want the feature or not, but posed the question because I thought, " Well, what if I'm over thinking things and no one needs or wants the feature?"  I'll keep thinking it over for now.  

JGL

Puttzing around a bit more, and I think I have a working Input Module that should be fairly simple for most folks to put together now.  I'm still working on the output end of things.  

The plan is to use a single $2 ProMini clone to replace the pair of shift registers as well as the Schmitt triggers.  We can also eliminate all but one of the pull-up resistors as the microprocessor has built in pull-ups that can be activated in software.  Just to be safe I'm still using a pull up on pin 13, because the onboard LED can make that pin's internal pull-up act flaky.  The ProMini here will communicate with the main micro-controller over the I2C bus, which allows for high speed, two way, communication between many devices (over relatively short distances).The code running on the ProMini here will be pretty simple.  It will poll the inputs to check if they are active or not and store the results, then when it is asked for the data over the I2C bus it will report the current state of each input.  

The down side of this set-up is that each module will have to have a unique address programed in when it is set up, because every last I/O pin on the thing is being used already, leaving no option for a hardware addressing solution.  I'm thinking I can incorporate some sort of fairly easy to use 'programing module' into the system to make things easier.  Additionally if multiple sets of switch controllers are not being linked together, the default address for each module should work with no problem as they will not be talking to other units with the same address.  

Once again, the PCB layout is optimized for perforated project board, however the layout should work in a proper two-layer PCB as well.  

My testing concurs with the data sheets of the parts in use, and this set up will work with AC track voltage input consistent with normal conventional control of 8VAC to 20VAC, or it will work using a separate accessory transformer for the inputs.  My preferred method is still to use a DC power supply with ground connected to the track common, and I'd recommend using 12VDC on the 'trigger power' input.  

I don't suggest anyone build any of this quite yet, just in case something doesn't work out for some reason.  I do plan on putting together a fully working model before I suggest anyone else jump in.  

JGL-SMC-v02-02_bbJGL-SMC-v02-02_schemJGL-SMC-v02-02_pcb

JGL

 

Attachments

Images (3)
  • JGL-SMC-v02-02_bb
  • JGL-SMC-v02-02_schem
  • JGL-SMC-v02-02_pcb

I ran into a problem while testing my Arduino system on the layout, so I thought I would update everyone on what happened and what I did to fix it. I would welcome any thoughts people have about the situation.

After I  connected a few of the Atlas switches to the relay outputs, I started noticing some kind of electrical interference when power was removed from the switch coils. The interference would almost always cause the indicator lights on the relay boards to flicker, and it would sometimes cause relays to activate unintentionally. Here is what I did to get rid of the problem:

1) The problem only occurred when I had power going through the relay outputs, so I first changed the power supply that I was using for the Atlas switches to a DC transformer with a capacitor across the inputs. This improved the situation a little but did not  eliminate the problem.

2) Next I changed the way I was powering the Arduino. I had been using a 12v power supply plugged into the barrel jack of the Arduino. I switched to a 5v supply that I connected directly to the 5v and ground pins of the Arduino. I also ran power to each of my separate boards directly from the power supply instead of through the Arduino. This change eliminated the unintentional relay activation, but I still noticed an occasional flicker.

3) Finally I added a flyback diode across the Atlas switch coils. This seemed to completely fix the issue. I have 16 switches connected, and they have been working perfectly for a few days.

 

 

arduino

Here is a picture of the setup with 8 switches connected. The board on the left has the optocouplers and Schmitt triggers. The input wires are connected to the green screw terminals on the left of this board. The next board has the parallel in shift registers. There is room to add more registers to this board, and it also has header pins that can connect to another board. The red board is just to distribute my 5v power input to the Arduino and the other boards. The board above the relays has the parallel out shift registers. This board can also be chained with another board.

After I connected everything I realized that I could use 8 fewer relays by using both the NC and NO posts for the led indicator lights.

I have made a few small changes to my Arduino sketch, and I will post another update once I get it cleaned up.

Attachments

Images (1)
  • arduino

John,

Glad you managed to figure your problem out.  The problem comes from using a 12V in to the arduino.  The higher the voltage in, the less current the arduino's onboard regulator can provide before it shuts down from over heating.  At 12v it can only provide about 200mA.  The arduino it's self uses something like 120mA so that only leaves 80mA for anything connected to it.  With the relay boards we are using, each relay draws about 70mA when it is first activated, and about half that to remain on.  If you try to power more than 1 or 2 relays at a time it will overload the on bard voltage regulator.  

If you power the arduino from USB if can source about 500mA, and with 7 volts on the barrel jack you can get close to 700mA.  

Pretty much it is recommended to use the 5 volt in and power other devices separately when possible unless it's just a couple LEDs or sensors that won't draw much current.  How you have things set up now is the recommended way to do it.  

JGL

P.S.  all looks good in your pics!

JGL,

I am interested in your suggestion to eliminate the shift registers and Schmitt triggers from the input module. Have you thought about using an Arduino Mega instead of the ProMinis and the I2C bus. The Mega has a total of 70 pins and can be bought on eBay for $7. You could control 14 switches with one Mega by using 28 pins as inputs and 42 pins as outputs (28 for the switch relays and 14 for the leds).

I did a small test with an Arduino controlling 2 switches, and it seems to work fine. I just used the optocoupler circuit that you diagramed in your post above as the input and then connected the Arduino outputs directly to a relay board. The advantage of this setup would be its simplicity. The optocoupler boards can be assembled quickly and the only other connections are jumper wires going to and from the Arduino.

I actually kicked around the Mega idea as well, and it may be the way to go.  I was leaning in that direction when I got sidetracked with other projects.  I don't have a schematic for this right now, but here's a PCB layout I did for a controller for 8 switches.  

Mega-SMC-v03-02_pcb

The Mega plugs in on the bottom of the board and other connections are on the top side to save space.  It has 16 inputs for the anti-derail function on 8 switches, and outputs for 24 relays.  8 for the red/green signals and 16 for the relay coils.  While I plan to use the 12VDC of a power supply, the inputs are good for upwards of 22VAC track voltage.  There is also a header to connect a driver so that the brightness of the LEDs can be adjusted.  I added a set of headers as well to connect a RS485 module to allow this board to communicate with other boards or a master control unit. The plan here is that you could locate the relay boards and this 'motherboard' with a Mega2560 near your switches, then run just 3 wires over distances of hundreds of feet, if needed, to a control panel or master control unit.  Another unit would be at the control panel and light up panel lights and allow push-button control of the switches, as well as control from TMCC. One could also use DCS to control their switches with this set-up, but I'm not going to get into how to accomplish that at the moment.  The header labeled 'watchdog' however has nothing to do with DCS. Instead this is to attach a watchdog timer that will reset the Arduino if it hangs up for some reason, preventing a glitch from causing a derailment if the Arduino were to lock up and stop functioning.  

I need to actually assemble a prototype before I'll be sure everything works as planned, but I don't see any reason it wouldn't.  I'm thinking of adding an on-board 5v power supply, but my preferred method is to use an ATX computer power supply to power the Arduino's, relay boards, and other associated things.  

JGL

Attachments

Images (1)
  • Mega-SMC-v03-02_pcb

JGL,

You only need two wires for RS485. I have this setup on my JMRI setup for testing. It is talking with an Arduino which acts like a CMRI node.

You guys are doing some interesting stuff here and I think will need to do this as well. I'm going to use servos for my turnouts will need a circuit for non-derail activation. The Servos will be able to be "thrown" by JMRI, Toggle, or Lionel Legacy.

I plan on using these for non-derail activation (block detection) circuit. https://www.adafruit.com/products/732

Which is a 16 port i/o expander over i2c and Adafruit has library for it. 

I think I will use the schmitt trigger eliminate code in my program since it will be doing a lot of other tasks. I will also have relays added which will connect to Lionel LCS STM2 to update the ipad app. 

JGL are you using 5v ground for detection or 18v AC?

crood58 posted:

JGL,

You only need two wires for RS485. I have this setup on my JMRI setup for testing. It is talking with an Arduino which acts like a CMRI node.

You guys are doing some interesting stuff here and I think will need to do this as well. I'm going to use servos for my turnouts will need a circuit for non-derail activation. The Servos will be able to be "thrown" by JMRI, Toggle, or Lionel Legacy.

I plan on using these for non-derail activation (block detection) circuit. https://www.adafruit.com/products/732

Which is a 16 port i/o expander over i2c and Adafruit has library for it. 

I think I will use the schmitt trigger eliminate code in my program since it will be doing a lot of other tasks. I will also have relays added which will connect to Lionel LCS STM2 to update the ipad app. 

JGL are you using 5v ground for detection or 18v AC?

Yes, the RS485 standard only needs 2 wires for communication (just like RS232 or I2C), but it also needs a common ground between devices... a third wire.  

It would depend what your design goals are to come up with a plan of attack for servo control.  for easy to program and hook up, an array of Arduino-type boards would probably do the job, where as for a lower cost solution one uP might be used to control many simpler PWM drives for the servos.  I'd have to really get into the thing to figure out what way I'd go.  As far as connecting to Legacy, I think JMRi will do much of this for you, but it is also pretty easy to have the uP read commands directly from the serial port.  

I'm using the same port extender in another project I'm working on (Here), but I'm buying mine shipped out of China for about 80 cents each.  I haven't researched the hysteresis of these chips to see if they require a Schmitt trigger for a solid IO or if they do it on their own as the project I planed to use them in is only dealing with solid highs and lows.  I'll post back here if I find out one way or the other.  

"I think I will use the schmitt trigger eliminate code in my program since it will be doing a lot of other tasks. "  In this case one has nothing to do with the other.  The purpose of the Schmitt trigger is to allow the processor to have a clearly defined high or low state that does not fluctuate back and forth when the signal is in transition between states.  (As an example [with approximate values] in most logic gates anything below 1 volt is low and and anything over 3 volts is high.  The problem comes in that the area between 1 and 3 volts is undefined and the state can float between values at that voltage.  The schmitt trigger works by saying  'I won't change states until the input voltage reaches a threshold level, well beyond what is certainly  a high or low.  Basically it filters varying voltage, jittery inputs into strict 1's and 0's.  Anyway, the point of all this is, the input pins on an Arduino have Schmitt triggers built in so you don't need to add them if a pin is connected directly to.  

And finally, "JGL are you using 5v ground for detection or 18v AC?"  I believe JohnF is using track AC (18VAC?) to trigger his set up.  I am planning to use 12VDC here.  My plan is to use the 12VDC line on an ATX power supply to provide the current for the sensing.  The power supply's ground would be connected to track common and the 12+ would connect to the positive power connection on the input board.  When an insulated rail is bridged it will conduct the ground path to complete the 12V circuit.  I think 5V would probably work, but I expect that 12V will hold up better to losses from distance, track resistance, and dirty wheels and track.  The Optocouplers I'm using, with a 1.5K Ohm resistor  will work with voltages up to 30VDC (probably 24-28VAC RMS shouldn't cause any damage, but I'm gonna play it safe and say 21VAC for the limit).  I've tested the inputs to work just fine at 5 volts as well, but will need to double check this with other optocouplers.  I'm using the cny17-1 right now, because I have a bag full of them.  Based on the data sheets I see no reason that any of the others I've looked at wouldn't work just as well.  

Basically all you're doing is using an insulated rail to light up a single LED.  If you can do that, replace the LED with the optocoupler, and you have an isolated, logic level, signal your microprocessor can use.  The microprocessor has plenty of time to debounce any flicker from dirty wheels or what-have-you, so hardware debouncing is not needed.  

Hope I didn't twaddle on too much there.

JGL

If you debounce in software, you should think about an integrating algorithm rather than a simple timed debounce.

I found that response time was too long when I relied on a simple debounce algorithm, which is why I reverted to analog.  (I originally went analog because my first microcontroller was a Basic Stamp, which had something like 20 bytes of RAM.)

An RC debounce can effectively discriminate between a momentary loss of contact due to dirty track, versus when the last little bit of wheel has left the sensor rail. An integrating algorithm can emulate that effect.

Last edited by Professor Chaos
JohnGaltLine posted:

Yes, the RS485 standard only needs 2 wires for communication (just like RS232 or I2C), but it also needs a common ground between devices... a third wire. 

 No it doesn't. It is a differential signal, so it does not need a common ground. I have an RS485 bus setup right now between my Raspberry Pi and Arduino and they don't share a common ground and work perfectly. Besides even if you did. You stated that you are going to use an ATX power supply to power all your Aduinos, so they would already have a common ground. 

JohnGaltLine posted:

It would depend what your design goals are to come up with a plan of attack for servo control.  for easy to program and hook up, an array of Arduino-type boards would probably do the job, where as for a lower cost solution one uP might be used to control many simpler PWM drives for the servos.  I'd have to really get into the thing to figure out what way I'd go.  As far as connecting to Legacy, I think JMRi will do much of this for you, but it is also pretty easy to have the uP read commands directly from the serial port. 

 Will I'm planning on using a CMRI library for Arduino that will let me do a lot with JMRI attached. One reason would be prototypical signals, where JMRI would handle the logic. The reason for Legacy is because I would mostly throw the turnouts with the CAB-2 than JMRI. JMRI functionality is just there if I want it. 

JohnGaltLine posted:

I'm using the same port extender in another project I'm working on (Here), but I'm buying mine shipped out of China for about 80 cents each.  I haven't researched the hysteresis of these chips to see if they require a Schmitt trigger for a solid IO or if they do it on their own as the project I planed to use them in is only dealing with solid highs and lows.  I'll post back here if I find out one way or the other.  

 I didn't have time to look at your other post regarding the IO expander, but I buy them from Adafruit and currently have three of them in my parts box. I like buying from Adafruit even if I pay a little more, because they provide a lot of free information and libraries for Arduino and Raspberry Pi. I think I would still put a schmitt trigger just to debounce the signal. They would be perfectly fine reading high and low of a digital signal. Adafruit's library would take care of all the heavy lifting. Check it out. It has digitalRead function, so all you have to do in the sketch is mcp.digitalRead(0) for example. 

JohnGaltLine posted:

"I think I will use the schmitt trigger eliminate code in my program since it will be doing a lot of other tasks. "  In this case one has nothing to do with the other.  The purpose of the Schmitt trigger is to allow the processor to have a clearly defined high or low state that does not fluctuate back and forth when the signal is in transition between states.  (As an example [with approximate values] in most logic gates anything below 1 volt is low and and anything over 3 volts is high.  The problem comes in that the area between 1 and 3 volts is undefined and the state can float between values at that voltage.  The schmitt trigger works by saying  'I won't change states until the input voltage reaches a threshold level, well beyond what is certainly  a high or low.  Basically it filters varying voltage, jittery inputs into strict 1's and 0's.  Anyway, the point of all this is, the input pins on an Arduino have Schmitt triggers built in so you don't need to add them if a pin is connected directly to.  

 I personally think one does have to with the other. If you are trying to run multiple servos, turnout signaling, touch toggles, and whatever else there has to be some limit to what you put into the software side. I much rather use a schmitt trigger on and not have to worry about missing a train in the non-derail "block". Besides the software can get tied up and eventually miss the train in the non-derail block. I use Object Oriented Programming for most of my "complex" stuff, so I can multitask the board. I would still do this if there was a schmitt trigger, so the train would never be missed. 

JohnGaltLine posted:

And finally, "JGL are you using 5v ground for detection or 18v AC?"  I believe JohnF is using track AC (18VAC?) to trigger his set up.  I am planning to use 12VDC here.  My plan is to use the 12VDC line on an ATX power supply to provide the current for the sensing.  The power supply's ground would be connected to track common and the 12+ would connect to the positive power connection on the input board.  When an insulated rail is bridged it will conduct the ground path to complete the 12V circuit.  I think 5V would probably work, but I expect that 12V will hold up better to losses from distance, track resistance, and dirty wheels and track.  The Optocouplers I'm using, with a 1.5K Ohm resistor  will work with voltages up to 30VDC (probably 24-28VAC RMS shouldn't cause any damage, but I'm gonna play it safe and say 21VAC for the limit).  I've tested the inputs to work just fine at 5 volts as well, but will need to double check this with other optocouplers.  I'm using the cny17-1 right now, because I have a bag full of them.  Based on the data sheets I see no reason that any of the others I've looked at wouldn't work just as well.  

Basically all you're doing is using an insulated rail to light up a single LED.  If you can do that, replace the LED with the optocoupler, and you have an isolated, logic level, signal your microprocessor can use.  The microprocessor has plenty of time to debounce any flicker from dirty wheels or what-have-you, so hardware debouncing is not needed.  

 

 Interesting. Just shows there are 20 ways to do something. I think I much rather use DC myself, because it would make life a little easier, especially since I will be using an ATX power supply anyway. I'm not sure what would be better. A 12V or 5V line. Would it matter, since you are just using the power to complete the circuit? Really the ground (current) is what the train passes to the Optamp. I don't know the answer to this. Just putting it out there. I'm just wondering if there some advantage of using track power or DC. 

Professor Chaos posted:

If you debounce in software, you should think about an integrating algorithm rather than a simple timed debounce.

I found that response time was too long when I relied on a simple debounce algorithm, which is why I reverted to analog.  (I originally went analog because my first microcontroller was a Basic Stamp, which had something like 20 bytes of RAM.)

An RC debounce can effectively discriminate between a momentary loss of contact due to dirty track, versus when the last little bit of wheel has left the sensor rail. An integrating algorithm can emulate that effect.

Yes, I agree with this. I much rather just use the RC Circuit with schmitt trigger than try to write some integrating algorithm in the software to handle this. 

Professor Chaos posted:

If you debounce in software, you should think about an integrating algorithm rather than a simple timed debounce.

I found that response time was too long when I relied on a simple debounce algorithm, which is why I reverted to analog.  (I originally went analog because my first microcontroller was a Basic Stamp, which had something like 20 bytes of RAM.)

An RC debounce can effectively discriminate between a momentary loss of contact due to dirty track, versus when the last little bit of wheel has left the sensor rail. An integrating algorithm can emulate that effect.

I don't see why a timed debounce would behave any differently than an RC circuit.  In one you adjust a variable for how long you want to wait before a state change occurs and in the other you tune the values of the resistor and capacitor to get the same result.  After a change in the input state some amount of time passes before that change is registered.  Assuming the uP you choose has enough speed to keep up, and you have the free space in memory, the net effect is the same.  Either method works equally well, but when timing is not critical, ex 1 or 2 milliseconds won't matter, such as reading an insulated rail or push button, I choose not to add any parts or board space where 4 or 5 lines of code will do the job, and I gain the ability to fine tune the timing down to the millisecond.  

Now an RC debounce will behave a little differently than the software solution I typically use, however a couple more lines of code could make it behave the same.  I actually prefer a uniform timing between on's and off's.  The RC design will switch from low to high much quicker than from high to low in a typical configuration.  Once again, adding parts can equal this out, but to me code is more economical than parts.

 On the RS485, every example I've seen and all the documentation I've seen shows some common ground.  Most just use a third wire while many industrial applications use earth ground.  In any case it doesn't matter to me as it will only be two wires between devices and track common will be connected to them anyway.  

On the port expander there's two things.  I do tend to purchase products from vendors I support for developing something I use, but for a single component a 2.5 to 5x markup seems a bit much.  LadyA can have my money for new products, not components.  The other issue is library overhead.  Does the library for this chip also require the wire library to be included, or will it work as a standalone?  If a standalone library, if it's smaller than the wire library I may look at it.  If it requires the wire library as well then it's a toss up depending on free space.  

As a third thing, the port expander chip is nice because it's easy to use if you need to add just a couple of both inputs and outputs, however using shift registers is usually a better way to go if you need a large numbers of I/O.  there are also many other options for port expander chips out there using both I2C and SPI.  If you're comfortable with SMT parts, 64 bit expanders are reasonably priced.  

Crood58 posted:  " I personally think one does have to with the other. If you are trying to run multiple servos, turnout signaling, touch toggles, and whatever else there has to be some limit to what you put into the software side. I much rather use a schmitt trigger on and not have to worry about missing a train in the non-derail "block". Besides the software can get tied up and eventually miss the train in the non-derail block. I use Object Oriented Programming for most of my "complex" stuff, so I can multitask the board. I would still do this if there was a schmitt trigger, so the train would never be missed. "

I think maybe some terms are getting confused or something.  Adding a Schmitt trigger will have no effect on the code needed, it will simply allow the processor to have an absolute high/low, one/zero state.  it is an unneeded part if you're input is connected directly to an Arduino as the ATmel chip that is the brains in an Arduino has Schmitt triggers built in on all GPIO pins.  

A Schmitt trigger does not store any data.  it will report whatever the current value is when the input is polled it just filters incoming signals that may have some ripple or noise into nice clean square waves.  The use of Schmitt triggers was suggested earlier i the thread to filter out noise from varying saturation of the optocoupler that may have caused problems when connected to the 74165 shift registers for input as these have a no-mans-land- where the state can be undefined.  

If you're really worried about ensuring that a train triggers an anti-derail as close to instantly as possible, the input should be connected to one of the Arduino's hardware interrupt pins.  The mcp23017 also supports interrupts.  For me I don't see the point.  Even with a rather complex sketch an arduino is likely to make a full run through the loop several thousand times each second.  There's no real world difference to me between a relay clicking on 1/10,000th of a second after the engine touches the insulated rail and it taking 1/1,000th of a second.  In the real world whether using a hardware or software method to debounce the inputs, transition times of 15 to 30 milliseconds are going to be the norm, so I don't think it matters if the uP takes 1 or 2 ms to react.  For reference of the reaction times here, an O scale train moving at a scale speed of Two-hundred MPH will move about 0.07 inches in a millisecond.  I would be doubtful the contacts of the relay can close or the solenoid or servo throwing the switch can move the points before the Arduino has had a thousand times to check the state of the input.  The Songle relays on the module boards are specked to take up to 10ms to click on, for example.

" Interesting. Just shows there are 20 ways to do something. I think I much rather use DC myself, because it would make life a little easier, especially since I will be using an ATX power supply anyway. I'm not sure what would be better. A 12V or 5V line. Would it matter, since you are just using the power to complete the circuit? Really the ground (current) is what the train passes to the Optamp. I don't know the answer to this. Just putting it out there. I'm just wondering if there some advantage of using track power or DC. "

It is not really going to matter all that much here, but higher voltages withstand longer distances better and AC better than DC.   I don't know that it will actually matter with the low current needed to drive an optocoupler but I have the 12v rail doing nothing so that's what I plan to use it for.  For folks using a wall wart to power the electronics, just using track power for triggering might be easier to do.  you don't have to worry about any new power supply if you don't want to.  The only difference in design if one re-did it to only work with DC would be removing a diode that costs less than 1/10th of a penny from each input (Just bought a sack of 1000 1n4007's for $7.)

 

All told My purpose with the various designs I'v proposed in this and other similar threads is to make the device as easy for the lay-person to build as possible while still keeping costs down well below any store-bought solution.  Sometime a choice was made that raised the cost to greatly simplify the design.  other times some complexity was added to drop the cost.  I'm still not 100% sure on things, but it looks like using a Mega2560 with just a couple added components seems to make more sense than having to add 10 more chips for the same functionality.  It costs about $4 more, but seems worth it to make things simple.  (On the other hand it actually would cost less if one was paying boutique electronics parts prices. ex $2.75 for a 3-pack of shift registers from Adafruit vs 95 cents for 10 from the auction site.(even less if you buy more.) )

 

JGL

 

JohnGaltLine posted:
Professor Chaos posted:

If you debounce in software, you should think about an integrating algorithm rather than a simple timed debounce.

I found that response time was too long when I relied on a simple debounce algorithm, which is why I reverted to analog.  (I originally went analog because my first microcontroller was a Basic Stamp, which had something like 20 bytes of RAM.)

An RC debounce can effectively discriminate between a momentary loss of contact due to dirty track, versus when the last little bit of wheel has left the sensor rail. An integrating algorithm can emulate that effect.

I don't see why a timed debounce would behave any differently than an RC circuit.  In one you adjust a variable for how long you want to wait before a state change occurs and in the other you tune the values of the resistor and capacitor to get the same result.  After a change in the input state some amount of time passes before that change is registered.  Assuming the uP you choose has enough speed to keep up, and you have the free space in memory, the net effect is the same.  Either method works equally well, but when timing is not critical, ex 1 or 2 milliseconds won't matter, such as reading an insulated rail or push button, I choose not to add any parts or board space where 4 or 5 lines of code will do the job, and I gain the ability to fine tune the timing down to the millisecond.  

Now an RC debounce will behave a little differently than the software solution I typically use, however a couple more lines of code could make it behave the same.  I actually prefer a uniform timing between on's and off's.  The RC design will switch from low to high much quicker than from high to low in a typical configuration.  Once again, adding parts can equal this out, but to me code is more economical than parts. 

Okay, so Professor Chaos has actually built one of these and seems to have no problems with it. Utilizing hardware for the debounce that is and he saying that you need more than just a debounce timer like normally used in Arduino Sketches. My question what is the complexity of the code required compared to just using the schmitt trigger? If I have to write and test complex code to do this than I much rather just do it in hardware and be done with it.  There is always multiple ways to do something, but which one requires less resources and is a more practical application. 

JohnGaltLine posted:

 On the RS485, every example I've seen and all the documentation I've seen shows some common ground.  Most just use a third wire while many industrial applications use earth ground.  In any case it doesn't matter to me as it will only be two wires between devices and track common will be connected to them anyway.  

 I disagree. I have this working perfectly fine for weeks without a common ground shared. I don't know why tutorials show this, but it maybe just a safety factor. Why would track common be connected to RS485? I don't recommend that at all. I would keep track power & ground separated from 5V DC power. Hence the Optamp. 

JohnGaltLine posted:

On the port expander there's two things.  I do tend to purchase products from vendors I support for developing something I use, but for a single component a 2.5 to 5x markup seems a bit much.  LadyA can have my money for new products, not components.  The other issue is library overhead.  Does the library for this chip also require the wire library to be included, or will it work as a standalone?  If a standalone library, if it's smaller than the wire library I may look at it.  If it requires the wire library as well then it's a toss up depending on free space.  

As a third thing, the port expander chip is nice because it's easy to use if you need to add just a couple of both inputs and outputs, however using shift registers is usually a better way to go if you need a large numbers of I/O.  there are also many other options for port expander chips out there using both I2C and SPI.  If you're comfortable with SMT parts, 64 bit expanders are reasonably priced.  

 I agree that the price be more than what you can get out of China, but if I place an order for products than I tend to order some components as well. This way I get a bang for my buck with shipping. I'm not going to cry over spending $2 over .80 cents. Where it makes told sense the Arduino boards themselves. Paying $5 from China vs. spending $20. Same with Servos. 

The library does depend on the wire library and automatically includes it within the library. Wait, you are going to tell me that you wouldn't use the library because it depends on the wire library? A few lines back you are arguing hardware vs. software debouncing, which proves my point that there has to be some limit on the software side. The wire library isn't going to make or back anything and people use it all the time for I2C communication. 

I disagree again on the shift registers. They need three wire communication and are more complex to address. Where I can use the port expander and have easy addressing. I can but 8 chips on a single I2C bus an have 128 additional I/O, which is a lot. 

JohnGaltLine posted: 

Crood58 posted:  " I personally think one does have to with the other. If you are trying to run multiple servos, turnout signaling, touch toggles, and whatever else there has to be some limit to what you put into the software side. I much rather use a schmitt trigger on and not have to worry about missing a train in the non-derail "block". Besides the software can get tied up and eventually miss the train in the non-derail block. I use Object Oriented Programming for most of my "complex" stuff, so I can multitask the board. I would still do this if there was a schmitt trigger, so the train would never be missed. "

I think maybe some terms are getting confused or something.  Adding a Schmitt trigger will have no effect on the code needed, it will simply allow the processor to have an absolute high/low, one/zero state.  it is an unneeded part if you're input is connected directly to an Arduino as the ATmel chip that is the brains in an Arduino has Schmitt triggers built in on all GPIO pins.  

A Schmitt trigger does not store any data.  it will report whatever the current value is when the input is polled it just filters incoming signals that may have some ripple or noise into nice clean square waves.  The use of Schmitt triggers was suggested earlier i the thread to filter out noise from varying saturation of the optocoupler that may have caused problems when connected to the 74165 shift registers for input as these have a no-mans-land- where the state can be undefined.  

If you're really worried about ensuring that a train triggers an anti-derail as close to instantly as possible, the input should be connected to one of the Arduino's hardware interrupt pins.  The mcp23017 also supports interrupts.  For me I don't see the point.  Even with a rather complex sketch an arduino is likely to make a full run through the loop several thousand times each second.  There's no real world difference to me between a relay clicking on 1/10,000th of a second after the engine touches the insulated rail and it taking 1/1,000th of a second.  In the real world whether using a hardware or software method to debounce the inputs, transition times of 15 to 30 milliseconds are going to be the norm, so I don't think it matters if the uP takes 1 or 2 ms to react.  For reference of the reaction times here, an O scale train moving at a scale speed of Two-hundred MPH will move about 0.07 inches in a millisecond.  I would be doubtful the contacts of the relay can close or the solenoid or servo throwing the switch can move the points before the Arduino has had a thousand times to check the state of the input.  The Songle relays on the module boards are specked to take up to 10ms to click on, for example.

I KNOW that the schmitt trigger does not store a state (I don't know how you got that from what I said). What I was saying was that I much rather use the hardware over the software. I would write library that would include the Adafruit MCP23017 library and use it to constantly check all my inputs. By running someLibrary.Update() in the loop.  The Arduino can WALK and CHEW gum at the same time by doing this (see here). Meaning that it is multitasking, so it is doing what the library needs to and processing through the loop. I may not need an interrupt. 

JohnGaltLine posted:

" Interesting. Just shows there are 20 ways to do something. I think I much rather use DC myself, because it would make life a little easier, especially since I will be using an ATX power supply anyway. I'm not sure what would be better. A 12V or 5V line. Would it matter, since you are just using the power to complete the circuit? Really the ground (current) is what the train passes to the Optamp. I don't know the answer to this. Just putting it out there. I'm just wondering if there some advantage of using track power or DC. "

It is not really going to matter all that much here, but higher voltages withstand longer distances better and AC better than DC.   I don't know that it will actually matter with the low current needed to drive an optocoupler but I have the 12v rail doing nothing so that's what I plan to use it for.  For folks using a wall wart to power the electronics, just using track power for triggering might be easier to do.  you don't have to worry about any new power supply if you don't want to.  The only difference in design if one re-did it to only work with DC would be removing a diode that costs less than 1/10th of a penny from each input (Just bought a sack of 1000 1n4007's for $7.)

 

 Yes, I would also have 12V rail doing nothing. This might be a good use for it. 

Chris 

 

crood58 posted:

JohnGaltLine posted:

 On the RS485, every example I've seen and all the documentation I've seen shows some common ground.  Most just use a third wire while many industrial applications use earth ground.  In any case it doesn't matter to me as it will only be two wires between devices and track common will be connected to them anyway.  

 I disagree. I have this working perfectly fine for weeks without a common ground shared. I don't know why tutorials show this, but it maybe just a safety factor. Why would track common be connected to RS485? I don't recommend that at all. I would keep track power & ground separated from 5V DC power. Hence the Optamp.

The reason for the ground is the common mode voltage capability of the RS-485 drivers.  The ground is typically necessary when going between widely separated points that could have different power systems and different grounding.  Of course, if the two devices have no issue of having excessively different ground levels, you probably don't need the ground. 

If the RS-485 is using optical isolation, then keeping the ground reference should no longer be necessary.  B+B SmarkWorx has optically isolated RS-485 that apparently solve this issue, I'd assume they're not the only ones.

Here's a good description of the ground: Why does RS485 (and RS422) require to connect the logic Ground?

gunrunnerjohn posted:
crood58 posted:

JohnGaltLine posted:

 On the RS485, every example I've seen and all the documentation I've seen shows some common ground.  Most just use a third wire while many industrial applications use earth ground.  In any case it doesn't matter to me as it will only be two wires between devices and track common will be connected to them anyway.  

 I disagree. I have this working perfectly fine for weeks without a common ground shared. I don't know why tutorials show this, but it maybe just a safety factor. Why would track common be connected to RS485? I don't recommend that at all. I would keep track power & ground separated from 5V DC power. Hence the Optamp.

The reason for the ground is the common mode voltage capability of the RS-485 drivers.  The ground is typically necessary when going between widely separated points that could have different power systems and different grounding.  Of course, if the two devices have no issue of having excessively different ground levels, you probably don't need the ground. 

If the RS-485 is using optical isolation, then keeping the ground reference should no longer be necessary.  B+B SmarkWorx has optically isolated RS-485 that apparently solve this issue, I'd assume they're not the only ones.

Here's a good description of the ground: Why does RS485 (and RS422) require to connect the logic Ground?

I can see this industrial applications, but I would assume that 99% of the time a Arduino or Raspberry Pi would be fed off of the same power source and would not require this common ground for the RS485 bus. Making only two wires required. Technically speaking my Arduino and Raspberry Pi are sharing earth ground. 

 

"My question what is the complexity of the code required compared to just using the schmitt trigger? If I have to write and test complex code to do this than I much rather just do it in hardware and be done with it.  There is always multiple ways to do something, but which one requires less resources and is a more practical application. "  

First, need to address this again, I think you are confusing 'Schmitt trigger' with an RC filter.  It does not matter if you are using ha hardware or software debounce, you still need a schmitt trigger on the input.  Arduino's have them built in on all GPIO pins so it is a non-issue if you only need the number of I/O pins the Arduino has.  If you need more I/O than that, you'll need to add something like a 7417 or other Schmitt trigger, or find a shift register or port expander that has them built in.  

As for the software solution, the code looks something like this:  

// Define variables:
byte MB1_State; // current pin state - high/low
byte MB1_StateLast; // pin state on last read - high/low
byte ManualButtonOnePin = 2; // pin of Arduino input is connected to
unsigned long CurrentTime; // clock variable for current cpu clock time
unsigned long ManualButtonOneClock; // clock variable for input debounce
byte DebounceTime = 20; // time to wait before declaring a state after a change of input (ms)
byte ManualButtonOneCurrentState; // debounced value for the rest of the sketch to use for the input state.

// Actual routine:
CurrentTime = millis(); // set the clock to the current time

MB1_State = digitalRead(ManualButtonOnePin); // read the input pin
if (MB1_State != MB1_StateLast) ManualButtonOneClock = CurrentTime; // if it's not the same as it was last time reset the clock
if (CurrentTime >= ManualButtonOneClock + DebounceTime) ManualButtonOneCurrentState = MB1_State; // if the clock runs out reset the state the rest of the program uses.
MB1_StateLast = MB1_State; // Save the input pin's state to compare with on the next cycle.

This routine takes 894 bytes of memory as opposed to the 742 bytes it takes just to read the pin without the debounce.  Some of that is also overhead that is not repeated in additional instances of the debounce for other inputs.  There are other variations on the theme here, but this method gives the results I like.  

"I would keep track power & ground separated from 5V DC power."

My plan is to have the ground of my ATX supply connected to track common anyway to use the 12v rail for triggering.  It's already connected so it doesn't matter.  You only need isolation if there is a current path available.  in this case there is no way for spikes to travel across the void of space/air between the AC hot and 12VDC + connections, nor between +12 and +5, so a spike is effectively isolated from any of the electronics.  You can connect the ground of 800 different power sources together without a problem.  it's only an issue when you start trying hook the high ends together.  

"Where it makes told sense the Arduino boards themselves. Paying $5 from China vs. spending $20. Same with Servos. "

I actually own one genuine Arduino board for each type of knock off I own, that sit on a shelf and never end up getting used for anything.  I buy these to support the research and development of the project.  I don't think Microchip technology Inc is going to get a kickback from LadyA for selling a part they designed, so I'll just buy it right from the source.  I prefer to spend my money to support development, not supply chains.  For something like the MCP23017, it's not really a big deal.  for many jellybean components, however, the markup is rather insane, even over digikey or mouser.  

"The library does depend on the wire library and automatically includes it within the library. Wait, you are going to tell me that you wouldn't use the library because it depends on the wire library? A few lines back you are arguing hardware vs. software debouncing, which proves my point that there has to be some limit on the software side. "

Yes.  the limit is how much memory your microprocessor has to store the program.  Libraries eat up memory like crazy.  The wire library alone chews up over 1200 bytes of space.  If you're using a Mega, or a raspberry Pi, then memory is probably not a problem.  On an Uno, Nano, or ProMini you've only got about 30K bytes to work with.  Then you have Up's like the ATtiny's that often have a whopping 1KB of space, less than the wire library alone.  I admit my code is sloppy most of the time by professional standards, by trying my best not to waste space is something that was beat into me.  If you have a simple sketch it won't matter, but when things get complex, shaving a couple kilobytes can save you.  

On the shift registers, the extra wire is pretty meaningless since you get a practically unlimited number of IO pins off of those 3 wires.  There are also a number of easy to use libraries out there to handle the code, if you are not worried about the overhead.  

"I KNOW that the schmitt trigger does not store a state (I don't know how you got that from what I said). What I was saying was that I much rather use the hardware over the software. "

From this line:  "Besides the software can get tied up and eventually miss the train in the non-derail block."  It sounds like you think a schmitt trigger will somehow help speed things up or hold a value until the processor gets to it.  it takes the same amount of software with or without the Schmitt trigger.  Just one way gives you useable inputs, and the other gives you chatter in the data.   Using or not using a Schmitt trigger isn't really on the table, it's a needed component to the system for predictable operation.  

" The Arduino can WALK and CHEW gum at the same time by doing this (see here). Meaning that it is multitasking, so it is doing what the library needs to and processing through the loop."

The ATmega, unfortunately, can only do one thing at a time.  It has just one processor and processes one instruction at a time.  In the world of computers it is slow and dumb.  It can not actually multitask.  Fortunately, humans and mechanical devices are slower and dumber.  The arduino Can do one thing and then do another fast enough for us not to be able to tell that the first thing stopped, but it is still just a list of one thing after another, never two things at once.  Now there are some things that can happen all at once, but the processor can only make one change at a time.  

 

One other factor not really discussed is board space.  when prototyping on solder-less breadboard it really doesn't matter, but if you're trying to do a PCB layout or even fit everything on a perf board, it makes a difference.  A resistor may cost a tenth of a penny but the board space under it costs 5 cents.  If the cost of the PCB is too high, there's no point in reinventing the wheel as there are already store bought solutions out there if you want to spend the money.  The goal here was to replace 8 $20 boards with one that costs $20-30.  As stated in a previous post, the two main design factors are cost and ease of assembly for someone with limited skills.  We deal with through hole parts to make it easy to assemble, but use as few of them as possible.  

Anyway, six hour drive ahead of me.  got to run. 

JGL

crood58 posted:

I can see this industrial applications, but I would assume that 99% of the time a Arduino or Raspberry Pi would be fed off of the same power source and would not require this common ground for the RS485 bus. Making only two wires required. Technically speaking my Arduino and Raspberry Pi are sharing earth ground.

Exactly why I posted the reasons, I agree that if you have something in the same room with the same ground reference, you already have the "common ground".

gunrunnerjohn posted:
crood58 posted:

I can see this industrial applications, but I would assume that 99% of the time a Arduino or Raspberry Pi would be fed off of the same power source and would not require this common ground for the RS485 bus. Making only two wires required. Technically speaking my Arduino and Raspberry Pi are sharing earth ground.

Exactly why I posted the reasons, I agree that if you have something in the same room with the same ground reference, you already have the "common ground".

* thumbs up*

Add Reply

Post
×
×
×
×
Link copied to your clipboard.
×
×