DCC-EX / CommandStation-EX

EX-CommandStation firmware from DCC-EX. Includes support for WiFi and a standalone WiThrottle server. A complete re-write of the original DCC++.
https://dcc-ex.github.io/
GNU General Public License v3.0
155 stars 107 forks source link

Added the common S88 sensors. #166

Open Micha10 opened 3 years ago

Micha10 commented 3 years ago

With not arduino based dcc command stations the computer generates the dcc signal which is sent through a booster on the serial com port. The S88 sensors are connected through a parallel port to the computer. Nowadays the old ports are not supported. Now the dcc signal is created by this software but the S88 bus was not supported. With that change, you can connect the parallel port pins to arduino pins and the signals are sent to the connected computer which now can drive the whole fleet of trains fully automatically

FrightRisk commented 3 years ago

Chris and Harald, where does this fit in our world? We did not have this on the roadmap. My main questions are:

  1. Effect on compile size
  2. Effect on memory usage at runtime
  3. Should the be a fork, an option in config, etc? With the same tricks to not have any of the code compile in if not used
  4. What effect will using an interrupt have? Also notice the ifdef where nointerrupts() is called
  5. What code is missing that will "deliver the sensor feedback from network"?
  6. What is the value to the community for S88?
Micha10 commented 3 years ago

@FrightRisk Hi, I hope I can give a few answers First: With the command-station you can run trains manually and as far as I understood you can put one sensor on one arduino pin, which is too less for middle sized tracks. With the old but very very common S88 bus you can handle this. I wonder how your users use that command-station? Do they just drive manually?

  1. For the Mega there's enough space left. I have been driven the trains for 3 hours without negative effect, but of course the measurement with resilient numbers has to be done. I will have a look at the code again and minimize dynamically allocated ram.
  2. see above
  3. I can change as you desire. I thought: If you do not need the S88 sensors, they are not compiled if you comment out the defines. If the end user should not need to compile code than the S88-code, classes, variables have to be always there and a variable in the config.h just returns each function so the function does nothing. But there could be a little impact, because the code needs to be called in each loop. Would it be an option to build 2 versions? I would not prefer it, because the enduser has to decide which to download. It makes the decision more complicated.
  4. Perhaps we can try without, but please have a look in the file DCCTimer.cpp. While defining the timer first "noInterrupts()" is called, than the timers are configured and at the end "interrupts()" is being called.
  5. That was just a discussion. My father want's to connect the motor shield to the arduino and the arduino by lan cable to the computer and not by usb. He was astonished that the sensor feedback was only sent by usb and not by lan. He asked for the reason and thought the user should be free how to connect the arduino to the computer. By usb or lan should be an option. But as it seems to be "complicated" (even if it worked for us) I decided NOT to include that code change
  6. I've tried to answer that in the first sentences above. It's a very common bus for signal feedback. How do you drive your trains?

I must confess that i'm relative new at arduino programming. I started for fun (dht22 measurement, smoke detector.... just small projects where you do not need a deep knowledge). So if you have comments about the code don't hesitate to contact me. I'm eager to learn ;-) The code was 99% from my father. He used just functions and just the timer. I put all the code inside a class and added the option to work with the main loop and without the timer.

Asbelos commented 3 years ago

The reason for the not sending unpolled information over the ethernet is because the command station is acting as a server for multiple clients and they may be using mixed protocols so we can only send back what they adk for. Writing data over ethernet may seem trivial to a PC or mainframe programmer but under the covers there is maybe 50 times as much code going on to handle multiple connections, tcp/ip protocols, buffers, retries etc. On the Arduino this stuff does not come for free. Remember even a mega has one millionth of the ram of a typical laptop.

Our strong recommendation is to run your jmri/rocrail over the same usb wire you already have to load the software. Get a longer one if necessary... but when you spend extra money to add an ethernet board you seriously degrade the capability and performance of the command station... increase the complexity of the setup and frankly I wonder why we bothered to implement it.

habazut commented 3 years ago

Would it be an option to build 2 versions? I would not prefer it, because the enduser has to decide which to download. It makes the decision more complicated.

As the code is always built on the PC of the user after download for the Arduino of the user (Mega, Uno, whatever) many variants to download are not a problem. This is only an option that needs to be written in config.h by the user or by the installer which writes config.h for the user.

It does however increase the number of variants to test. What is the minimal setup to test S88. Can one make a "fake S88" just for test?

The trick is how to write the code so that the #ifdef are minimized as otherwise the code may get messy. #ifdefs tend to do that...

Reards, Harald.

Micha10 commented 3 years ago

@habazut Testing. Well, please have a look at S88Mega::S88Read. A test could be to re/set one of the lower 4 bits of the RmBytes. A few milliseconds later a command <Q numberOfTheSensor> or <q numberOfTheSensor> should be sent to the computer by the usb-connection.

Johanvd10 commented 3 years ago

I am new with DCC++ Ex can you help me how to connect the S88 connections to the Mega board (which pins are used on Arduino Board default) or how can I set the pins in which file? Or do you have an schematic how to connect? Have found the pin settings in your file. How do read the sensor data ( Arduino Serial monitor?)

Johanvd10 commented 3 years ago

To Asbelos, do you have some info about s88 monitoring nano which reported only sensor changes to dccex using the serial connection.

Asbelos commented 3 years ago

My suggestion would be to use your s88 code in a stand alone sketch on any suitable cheap arduino and have it communicate sensor changes to the dccex arduino over a simple serial connection. Then these changes can be reflected to jmri or other sensor dependent systems.

Johanvd10 commented 3 years ago

Thank you for thr info.

Johan

From: Asbelos @.> Sent: Tuesday, July 27, 2021 4:38 PM To: DCC-EX/CommandStation-EX @.> Cc: Johanvd10 @.>; Comment @.> Subject: Re: [DCC-EX/CommandStation-EX] Added the common S88 sensors. (#166)

My suggestion would be to use your s88 code in a stand alone sketch on any suitable cheap arduino and have it communicate sensor changes to the dccex arduino over a simple serial connection. Then these changes can be reflected to jmri or other sensor dependent systems.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/DCC-EX/CommandStation-EX/pull/166#issuecomment-887568243 , or unsubscribe https://github.com/notifications/unsubscribe-auth/AU7SH5SNWFCSMMREG722DOTTZ3ADJANCNFSM46DIU2DA . https://github.com/notifications/beacon/AU7SH5QAR3P3TG3XM3XMZHLTZ3ADJA5CNFSM46DIU2DKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOGTTTO4Y.gif

FrightRisk commented 3 years ago

We can have a repo, or a folder in another repo with code that runs on an external device to control S88. Some people have expressed a more modular approach would be better than trying to have the command station do everything. This "controller" could send and receive messages using the <DCC++EX> command language. A Mega has an open serial port to communicate. If wireless is truly important, the HC-12 USB to serial bridge boards may be an option. I should also mention that LCN is about to be released. That is a wireless, bi-directional accessory bus. I understand though that people who already have S88 want to use what they have. I wonder if the controller could use LCN with modifications for S88?

FrightRisk commented 3 years ago

@FrightRisk Hi, I hope I can give a few answers First: With the command-station you can run trains manually and as far as I understood you can put one sensor on one arduino pin, which is too less for middle sized tracks. With the old but very very common S88 bus you can handle this. I wonder how your users use that command-station? Do they just drive manually?

For larger layouts, people use their own bus system or use these to expand the number of ports with this:

https://create.arduino.cc/projecthub/xreef/pcf8575-i2c-16-bit-digital-input-output-expander-48a7c6

or this for servos:

https://www.amazon.com/JZK-PCA9685-Channel-12-Bit-Arduino/dp/B06XSFFXQY/ref=asc_df_B06XSFFXQY/?tag=hyprod-20&linkCode=df0&hvadid=366016835942&hvpos=&hvnetw=g&hvrand=15102899031586775156&hvpone=&hvptwo=&hvqmt=&hvdev=c&hvdvcmdl=&hvlocint=&hvlocphy=9009681&hvtargid=pla-376960288549&psc=1&tag=&ref=&adgrpid=80266838630&hvpone=&hvptwo=&hvadid=366016835942&hvpos=&hvnetw=g&hvrand=15102899031586775156&hvqmt=&hvdev=c&hvdvcmdl=&hvlocint=&hvlocphy=9009681&hvtargid=pla-376960288549

Micha10 commented 3 years ago

Johanvd10 I am new with DCC++ Ex can you help me how to connect the S88 connections to the Mega board (which pins are used on Arduino Board default) or how can I set the pins in which file? Or do you have an schematic how to connect? Have found the pin settings in your file. How do read the sensor data ( Arduino Serial monitor?)

Please have a look at https://wiki.rocrail.net/doku.php?id=s88_lpt-en
Nowadays a computer does not have a parallel port, thus the pins (reset, load, clock, bus 0-3) are connected to arduino pins.

<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882" xmlns="http://www.w3.org/TR/REC-html40">

parallel port | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- usage |   | Clock | Load | reset |   |   |   |   |   | Bus0 | Bus1 | Bus2 | Bus3 | 5V |   |   |   | gnd| gnd| gnd| gnd| gnd| gnd| gnd| gnd Arduino pinA |   | 26 | 27 | 28 |   |   |   |   |   | 22 | 23 | 24 | 25 | 5V |   |   |   |   |   |   |   |   |   |   |   Arduino pinC |   | 33 | 32 | 31 |   |   |   |   |   | 37 | 36 | 35 | 34 |   |   |   |   |   |   |   |   |   |   |   |     |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |  

So you need working S88 hardware (isolated tracks, a wire from that isolated place to the sensor-board. Mostly the board is using network-cables to connect to a S88-Bus-interface. So rj45-network cables goes into the s88-bus-interface and on the other side there's a parallel port to connect to an old computer. The Arduino is taking the part of the old computer by connecting the parallel-port-pins to the pins on the arduino

Micha10 commented 3 years ago

Asbelos

This code contains explicit references to mega timers, it will not compile/work on megaavr or teensy processors. Using a software interrupt at this frequency and doing this much work will destroy the dcc waveform unless the high accuracy pwn is active, in which case the dcc code needs to shout if low accuracy and s88 are on at the same time.

Given the timing and pin requirements of s88 I would suggest that a better solution would be to build an s88 monitoring nano which reported only sensor changes to dccex using the serial connection. This eliminates many potential complexities or testing issues.

Well, no problem, you can just uncomment #use_S88Timer in the config file and the data is read without timers. In the main loop the sensors are polled (sensors.cpp) and with every call the S88 sensors are read. That's slower, but fast enough to precisely catch every signal.

We can also check the board type. If it is a mega, timers are used otherwise the loop.

Micha10 commented 3 years ago

My suggestion would be to use your s88 code in a stand alone sketch on any suitable cheap arduino and have it communicate sensor changes to the dccex arduino over a simple serial connection. Then these changes can be reflected to jmri or other sensor dependent systems.

And that's exactly the reason why we tried to use the code with command-station. A Mega is big and fast enough to drive the trains and catch the sensors. NO NEED FOR EXTERNAL HARDWARE. That's the great benefit to integrate the code. Otherwise you need one piece of hardware for running the trains and an extra (superfluous) piece just for the sensors

Asbelos commented 3 years ago

This is only true if the mega motor-shield complies with the requirements for our high accuracy waveform algorithm.

Otherwise, If your software uses interrupts you have LESS THAN 3uS to process your interrupt before you push the dcc waveform out of spec. (Trains may well work... but its not what we want for the future)

We are also developing other features which would not interface cleanly with your code as-is and we are making all our code portable to other arduinos more powerful than the mega and your code will not compile on them. (Some features are not supported on uno/nano).

So, I hope you understand why we can't merge in your existing s88 to CommandStation as it stands.

My advice earlier would allow us to connect cleanly to s88 in a way that eliminates all the issues for the price of a nano (which probably costs less than the parallel plug you used to have for your pc). It would also allow easy stand-alone testing/configuring of your sensor network and easy testing of the dccex end. As Fred has noted, we would be happy for that to be a part of dccex and hosted on our github.

Of course, being open source, you may continue to operate as now if that meets your needs.

Johanvd10 commented 3 years ago

Asbelos,

I have used google to find something about this s88 code in a stand alone sketch on any suitable cheap arduino and have it communicate sensor changes to the dccex arduino over a simple serial connection but still nothing found can you direct me to some documents or links?

Asbelos commented 3 years ago

Hi Johan, we are discussing the possibility of making one here.. Micha10 has some working s88 code which he may share with you. I'm hoping we can cooperate to get it working in a way that we can incorporate within the dccex family.

Johanvd10 commented 3 years ago

Asbelos,

This is what I also hope then will the DCC++ EX compatible for everyone, but the option for S88 is something many people will use. Most people have already the S88 as standard.

Johanvd10 commented 3 years ago

Asbelos,

Can i use this code https://github.com/dirkjankrijnders/Arduino-S88 and how then to read and send it to serial?

Johanvd10 commented 3 years ago

@FrightRisk Hi, I hope I can give a few answers First: With the command-station you can run trains manually and as far as I understood you can put one sensor on one arduino pin, which is too less for middle sized tracks. With the old but very very common S88 bus you can handle this. I wonder how your users use that command-station? Do they just drive manually?

  1. For the Mega there's enough space left. I have been driven the trains for 3 hours without negative effect, but of course the measurement with resilient numbers has to be done. I will have a look at the code again and minimize dynamically allocated ram.
  2. see above
  3. I can change as you desire. I thought: If you do not need the S88 sensors, they are not compiled if you comment out the defines. If the end user should not need to compile code than the S88-code, classes, variables have to be always there and a variable in the config.h just returns each function so the function does nothing. But there could be a little impact, because the code needs to be called in each loop. Would it be an option to build 2 versions? I would not prefer it, because the enduser has to decide which to download. It makes the decision more complicated.
  4. Perhaps we can try without, but please have a look in the file DCCTimer.cpp. While defining the timer first "noInterrupts()" is called, than the timers are configured and at the end "interrupts()" is being called.
  5. That was just a discussion. My father want's to connect the motor shield to the arduino and the arduino by lan cable to the computer and not by usb. He was astonished that the sensor feedback was only sent by usb and not by lan. He asked for the reason and thought the user should be free how to connect the arduino to the computer. By usb or lan should be an option. But as it seems to be "complicated" (even if it worked for us) I decided NOT to include that code change
  6. I've tried to answer that in the first sentences above. It's a very common bus for signal feedback. How do you drive your trains?

I must confess that i'm relative new at arduino programming. I started for fun (dht22 measurement, smoke detector.... just small projects where you do not need a deep knowledge). So if you have comments about the code don't hesitate to contact me. I'm eager to learn ;-) The code was 99% from my father. He used just functions and just the timer. I put all the code inside a class and added the option to work with the main loop and without the timer.

Johanvd10 commented 3 years ago

Micha10,

What are you using for software with the DCC command station to control trains and track and see the sensors from S88?

Micha10 please contact me by mail johan@dijk-van.nl

murarduino commented 2 years ago

@FrightRisk嗨,我希望我能先给出几个答案 :使用指挥站,您可以手动运行火车,据我所知,您可以将一个传感器放在一个 arduino 引脚上,这对于中型轨道来说太少了。使用旧的但非常常见的 S88 总线,您可以解决这个问题。我想知道您的用户如何使用该命令站?他们只是手动驾驶吗?

对于更大的布局,人们使用自己的总线系统或使用这些来扩展端口数量:

https://create.arduino.cc/projecthub/xreef/pcf8575-i2c-16-bit-digital-input-output-expander-48a7c6

或者这对于伺服系统:

https://www.amazon.com/JZK-PCA9685-Channel-12-Bit-Arduino/dp/B06XSFFXQY/ref=asc_df_B06XSFFXQY/?tag=hyprod-20&linkCode=df0&hvadid=366016835942&hvpos=366016835942&hvpos=&hl=zh_CN&5hv1v1v2vp81&hv1v1vp81&hv1v2hvp81&hv1v1v2hp8hv1v1 =&hvdev = C&hvdvcmdl =&hvlocint =&hvlocphy = 9009681&hvtargid = PLA-376960288549&PSC = 1&标签= REF =&adgrpid = 80266838630&hvpone =&hvptwo =&hvadid = 366016835942&hvpos =&hvnetw = G&hvrand = 15102899031586775156&hvqmt =&hvdev = C&hvdvcmdl =&hvlocint =&hvlocphy = 9009681&hvtargid = PLA-376960288549

To be honest, I am also hesitating between S88 and I2C. The main reason is that the allocatable addresses that support I2C16bit I/O chips are only 0X20~0X27. That is to say, the maximum number of Senosr is 16*8, 128. I wonder if it is enough.

hansSchall commented 2 years ago

As I alredy wrote to #249 I think the best is to do this on it's own mikrocontroller:

I personally use SN74HC165 shift registers, they are used in many s88 devices.

I am currently devloping an arduino-based software connecting them to I2C. see here It is not production-ready yet.

Additionally I use SN74HC595 shift registers, which work exactly as SN74HC165 exept in the other direction so they are used as outputs.

Both togerther work as very cheap IO expander (0,50€ per 8 IO), but you have to add a dedicated microcontroller for frequent polling. I think integrating this directly into DCC-EX is not possible or very slow.

The mentioned software has shown in its current state (I2C interface is not implemented yet) that it can handle up to 64 (8*8) in/outputs on 8 lines (512 in/outs total). In maximum speed mode (only suitable for short cables to the chips) all the inputs can be read more than 7000 times per second (!).[^1] Additionally it has the feature of adding outputs.

To use this with DCC-EX:

If you use only 3-5 s88 devices it should be possible to do this in CS, but for larger layouts this is not suitable. Maybe we should support both

[^1]: Why is this so fast?: The output pin configuration is optimized for usage of direct port maipulation. The output loop is compiled to very fast code (~30 machine instructions).

JeaneLG commented 1 year ago

Why I do want to have a S88 Master on DCC++ Controller? I have a dedicated DCC++ EX for only controlling the peripherals, i.e. lights, signals, turnouts, etc. It does not control trains. So it is very handsome to also be able to collect the feedback with this controller. I have implemented a first working version of S88 Master with the HAL and my first tests are running fine on an arduino UNO. See here: https://github.com/JeaneLG/CommandStation-EX/tree/LightHAL. Have a look to the last commit. To use the S88, you only have to call S88Master::create();.