All, As mentioned, I spent some time exploring the I2C/TWI bus this weekend and had considerable initial success creating a DCC++ "Server" Station. The purpose of the Server is to be a generic extension to the Base Station that can take commands from the Base Station, send commands back to the Base Station, and also serve up DCC signals (thus acting as a booster or auto-reverser). First step was to figure out whether I2C would be viable. My initial tests worked well and I was able to reliably communicate using a simple 6-foot telephone cable (two-wires, straight - not twisted, no ground shield). Using twisted, shielded wire would likely only improve things. I began with the sensor routines -- the Base Station code was updated so that when you define a sensor, you optionally can select a server address from 1 through 120. When the program first runs, it checks to see if those boards are available, and if so, sends them create-sensor commands for each sensor to be implemented on the Server board. The Server then operates using the normal sensor logic, recording changes in pin states. The Base Station continuously polls the Servers and if there is a change in the state of any remote sensor pins, it throws a <Q ID> or <q ID> just as if the sensor was local to the Base Station. I also added in some error-checking code to make sure definitions are in-sync even if the Arduinos don't all boot at the same time or rate. What I like about this method is the Server does not have to be pre-configured. You don't need to define any of its sensors or save them in Server EEPROM. These definitions are all handled by the Base Station along with definitions of local sensors. This greatly minimizes the house-keeping and allows you to load the code just once on the Server and forgot about it. Next I'll add in the logic to control remote Outputs, tidy up the code, and test with multiple Servers in use at the same time. I'll also get some longer cable to see where the I2C bus begins to fail, but so far the results are promising. Once done, I'll upload to GitHib. -Gregg
Gregg, Glad to hear this. I am assuming that the overall plan is still in line with this post from the "Introducing" thread where what you describe above is the "messaging" piece but there is another wire involved to carry the DCC signal (the pin 12 output of the Base Station) in the final connection. I have a pair of Unos and clone shields on the way. Looking forward to testing out the Server Station concept. While I'm waiting for hardware I'm actually starting on benchwork. Time to make the sawdust...
Yes, that's exactly it. First step is the messaging piece to ensure a master board can send commands to and from a series of server-boards. Second step is adding in the master DCC signal so the servers can also be used as boosters and ARs. -Gregg
Gregg/TwinDad Now that I have my setup using an Ethernet shield (tested as a WebServer with cable to router) .... Is there an example of code in our postings to use it wireless to connect Base station and Engine Driver? Steve
Hey, Gregg, I'm thinking we already have too many different code bases and configurations, and managing them is becoming tricky for both end users and developers. Wouldn't it be easier to have a single code base, single version if you will, and have configurable settings for master mode (generate DCC signal, drive rail power), booster mode (drive rail power) with optional accessory/sensor mode?
That's a very good idea. I am trying to build the server code into a form of an Arduino library so it would be added into the main code and activated as needed. This keeps everything in one version.
There has been a fair bit of chatter on the main thread about using RS485 to connect throttles and other devices, perhaps connecting boosters via RS485 might be better? or can you not do RS485 without additional hardware?
I haven't seen this done in software yet. But it's possible with as simple prefab TTL to RS485 Module for Arduino or some basic components. I have one setup to communicate with my Roco Multimaus, which acts as a handheld and central unit in one. The Roco system uses RS485 to communicate using the XpressNet protocol. I has a RJ12 6p6c connector which has the RS485 signal on pin 3 and 4. There's GND and 12 V that can power other devices on pins 2 and 5. And, interestingly enough, it has the DCC signal on pins 1 and 6 to connect boosters. Using I2C would perhaps be "cleaner" and simpler as you wouldn't need any extra components at all, besides the wires.
@Gregg : I stumbled across this today: http://www.aliexpress.com/store/pro...Interface-for-Arduino/506373_32434579531.html Do you think it would be possible to have the base station and server communicate wireless using this shield? Just a thought...
Gregg, Jason Here is a group that's looking to streamline communications RS485 and I2C via common bus MRBus 'Open Embeded Network, based on both 6p6c RJ12 and 8p8c RJ45 jacks and a Peer to Peer controller architecture. http://www.mrbus.org/info/Specification Hardware layer; http://www.mrbus.org/info/Specification2 Software Layer; http://www.mrbus.org/info/Specification3 Component integration http://www.mrbus.org/info/Specification4 Optional Items; Arduino MRBus Shield http://www.iascaled.com/store/MRBus/MRB-ARD A I2C 40 Channel Digital I/O expander; http://www.iascaled.com/store/MRBus/I2C-XIO and on board ATMega328 and 40 Channel MRBus I/O Node interface http://www.iascaled.com/store/MRB-XIO Software is GPL v3 https://github.com/IowaScaledEngineering/mrb-ard https://github.com/IowaScaledEngineering/i2c-xio https://github.com/IowaScaledEngineering/mrb-xio Edited addition; MRBus With Arduino http://www.mrbus.org/info/ArduinoLibraryReference http://www.mrbus.org/info/ArduinoExample Does this help at all on your Server Station idea? Kevin
All, Over the last month I have spent over 50+ hours working with the I2C bus on the Arduino. I quickly realized that the Arduino-provided library was not up to the task (it blocked the rest of the program from running whenever the bus was being used) and thus I needed to develop my own I2C library. At first this was sort of fun -- the I2C spec is very cool. BUT...the implementation of the spec on the Arduino is not sufficiently robust to use with DCC++. I tried every possible combination of modes (Master Transmitter, Master Receiver, Server Transmitter, Server Receiver, Multi-Master Arbitration), tested different frequencies, inserted error checks, etc. In many cases the bus would work fine, but after a while it would hang on some form of a collision. The I2C spec is supposed to handle these, and I thought I was doing something wrong until I found some other I2C enthusiasts on the web who experienced exactly the same problem. Fortunately, one of them also had a good multi-channel oscilloscope and was able to diagnose the problem in his own system (which paralleled my own issue). Based on what this other person found, it seems the implementation of the I2C bus interrupt mechanism within the Atmel chips used on the Arduino leave a bit to be desired, especially when it comes to being able to robustly handle multiple boards at the same time (which is needed if we really want to create a series of servers to control things like servos, sensors, and of course ARs). Though I'm frustrated the I2C bus did not pan out, it was a fun learning experience (and when it did work, it was pretty neat to see in operation). The good news is that a lot of the logic I created to handle multiple boards (regardless of the form of bus communication) can still be used. I am going to try to see if I can use a cascading set of serial connections (or perhaps use the Arduino's software serial library) to daisy-chain Arduinos. Perhaps that will give me better luck (and if so, would be a good candidate to implement via the RS485 protocols). -Gregg
Gregg, You are truly amazing!!! Please know how much we appreciate all the effort you put into this project. Like Thomas Edison, you now know more things that don't work. Dave
Gregg, Is there any news on multiple Arduinos, code for servers, and the RS485 network? Is this feature included in the current version of Base Station? Also is anyone using servos with DCC++? If so what is involved in adding the necessary libraries and code? Gregg, thanks for all you do for us. Dave Merril
Dave, I've been keeping up with TrainBoard when I can but unfortunately have not been able to revisit the DCC++ code in a while. When I was testing a few different networking schemes I uploaded a few new branches to GitHub, but the Main branch is still the original (and stable) version. Where I last left off, I was able to cascade three Arduinos using their built-in serial interfaces. I used a Mega as the master since that has additional Serial lines built into the chip. The TX line of Serial1 on the Master Mega was fed into the RX line of a second Arduino (Uno). The TX line of that second Arduino was then fed into the RX line of the third Arduino (also an Uno). And the TX line of this third Arduino was fed into the Serial1 RX line on the Master. The idea was that if the Master could not process a command, such as turning on an output, because it was not defined, instead of returning an <X> error it would copy the command to its Serial1 TX line. The second Arduino would then receive the command and try to process. If it could not, it shuffled the command to the third Arduino, and so forth. If the command ever made it back to the Master, the code would assume that none of the other Arudinos recognized the output command, and only then would it return an <X> error. Though my testing seemed to work, implementing this efficiently, and then adding on logic for sensor detection on the remote Arduinos still needed to be built. I hope to be able to return to this project at some point, but likely not in the very near future (work and other commitments...) I also recognize the need to add in support for Servos. The Arduino library includes a specific servo module, and it is something I hope to be able to embed within DCC++ once I get a chance to re-open the code. -Gregg
Gregg, Thanks for the update. I do realize that this is a hobby and there are often more important things in life. Thanks again for all that you do. Dave
Gregg, There is an Adafruit servo shield that can control 16 servos using 12bit PWM and might prove interesting. https://learn.adafruit.com/adafruit-16-channel-pwm-slash-servo-shield/overview I have seen this used with an Uno to decode the DCC signal and have turnouts thrown and semaphore signals set on and off by giving each servo its own DCC address. The shield could probably controlled directly by the Base Station using the turnout control. The shield is stackable, uses the I2C bus and can control up to 992 ( 16 x 62 ) servos! Hoping you can use this easily in the near future if it catches your imagination like it did mine. Regards Terry.
Would there be any merit to using a linux based board like a Intel Galileo type system with the DCC++ sketch running in the Arduino Layer, and some form of server software running in the linux environment? I am by no means a software engineer and can't code worth a damn, but it seems like the Galileo was designed exactly for projects such as this.
Kind of an old thread, i realize, but was the DCC++ "Server" station feature ever completed? I am curious as i see portions of the code in my copy of DCC++ base station. it would be neat to be able to use more inputs and outputs than what an Arduino Mega 2560 can provide, assuming my layout ever "grows up". if it works now, there is no reason for me to re-invent the wheel, but if the feature turned into a sinking ship, maybe i could come up with something. I read in this thread talk about RS485. this could have merit, though RS485 is generally half-duplex, and a whole transmit/receive protocol would have to be written, and it would also likely require extra hardware, such as a MAX485 chip (RS485 driver/receiver). I tend to prefer the TTL serial ports already on the Mega 2560. I will have to study the code deeper and see if it is something i want to dive into. i mean, being able to configure pins remotely, as well as monitoring and activating them through the built in sensor/turnouts/outputs would be a major plus. maybe just load a "remote device" firmware onto an arduino and connect it. would be nice. like i said though, i will have to study the code and think on it. ~Travis