Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added the common S88 sensors. #166

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Open

Conversation

Micha10
Copy link

@Micha10 Micha10 commented Jun 4, 2021

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

Mikado added 7 commits June 3, 2021 19:52
…als from the sensors back to the command station.
…ailable

checkAll: Added S88Mega->loop if no int/timer is used
checkAll: Check for changes of the S88 busses
printall: Send the current status os all S88 sensors
…the new base.

Tested with / without int/timers on my railroad. The trains can now be completely driven by the computer software
@FrightRisk FrightRisk self-assigned this Jun 4, 2021
@FrightRisk
Copy link
Member

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
Copy link
Author

Micha10 commented Jun 5, 2021

@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
Copy link
Contributor

Asbelos commented Jun 5, 2021

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
Copy link
Contributor

habazut commented Jun 5, 2021

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
Copy link
Author

Micha10 commented Jun 6, 2021

@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
Copy link

Johanvd10 commented Jul 27, 2021

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?)

Copy link
Contributor

@Asbelos Asbelos left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@Johanvd10
Copy link

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

@Asbelos
Copy link
Contributor

Asbelos commented Jul 27, 2021

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
Copy link

Johanvd10 commented Jul 27, 2021 via email

@FrightRisk
Copy link
Member

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
Copy link
Member

@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
Copy link
Author

Micha10 commented Jul 28, 2021

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.

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
Copy link
Author

Micha10 commented Jul 28, 2021

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
Copy link
Author

Micha10 commented Jul 28, 2021

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
Copy link
Contributor

Asbelos commented Jul 28, 2021

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
Copy link

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
Copy link
Contributor

Asbelos commented Jul 28, 2021

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
Copy link

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
Copy link

Asbelos,

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

@Johanvd10
Copy link

Johanvd10 commented Jul 29, 2021

@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
Copy link

Johanvd10 commented Jul 29, 2021

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
Copy link

@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
Copy link

hansSchall commented Aug 15, 2022

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:

  • add I2C interface
  • add HAL driver

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

Footnotes

  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
Copy link

JeaneLG commented Nov 18, 2022

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();.

daniviga pushed a commit to daniviga/CommandStation-EX that referenced this pull request Mar 26, 2023
Most of the content from CONTRIBUTING.md was already moved to
docs/contributing/website.rst and updated.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

8 participants