serialport / node-serialport

Access serial ports with JavaScript. Linux, OSX and Windows. Welcome your robotic JavaScript overlords. Better yet, program them!
https://serialport.io
MIT License
5.81k stars 1.01k forks source link

Changing parity on the fly #924

Open ficzusistvan opened 8 years ago

ficzusistvan commented 8 years ago

SerialPort version: 4.0.1 NodeJS Version: v4.2.6 Operating System and Hardware: Raspbian Are you using Electron/Atom/NwJS?: no

(Run node -v && npm -v && python --version to get version numbers) v4.2.6 2.14.12 Python 2.7.9

Summary of Problem

As stated in the documentation for serialPort.update([options], [callback]) only baudRate is currently supported. In my project I would like to send data with parity 'space', but the only way to achieve this on Linux is to change parity on the fly between parity 'even' and 'odd', depending on the bits to send.

Requested Behavior

serialPort.update([options], [callback]) should support parity selection beside baudrate changing.

NaveenChander commented 5 years ago

@reconbot We have the same issue. There is a need to change parity from Mark to Space and Space to Mark depending on the payload. is there a date for this fix ?

reconbot commented 5 years ago

It needs a champion, someone to build it.

emeryao commented 3 years ago

needs this feature too any update or workaround ?

GazHank commented 3 years ago

Is there still demand for this feature? I'd be happy to try to code for this, however I don't have a usecase or sensible means to test it, so would need some support to test this before it could be deployed

emeryao commented 3 years ago

Hi here is my scenario

I have two same devices connected to the same two line of a RS485 bus line and then connected to a PC with a 485-usb cable

I have to send a command to the serial port with mark parity to activate the device with a device address and then send a query command to serial port with space parity to get some data from the activated device

I actually worked around with this awesome lib by open port / write data / close port / new another port with other parity / write data

It works well just with a few more codes but changing parity on the fly would definitely be better for coding experience

image

image

sample commands

# query device 1
// active device with address 01
send -> FF01FF // mark parity
receive <- FF01FF // device activated
send -> AAFF // space parity
receive <- SOME_DATA_FROM_01

# query device 2
// active device with address 02
send -> FF02FF // mark parity
receive <- FF02FF // device activated
send -> AAFF // space parity
receive <- SOME_DATA_FROM_02

Sorry for my poor English

GazHank commented 3 years ago

@Emeryao absolutely no need to appologise! Excellent English, and not only great info, but images and diagrams too!

I'm interested to take a look at the code and see how big a change this would be, and if we can get it to work on all platforms. What operating system(s) are using? While at first glance it looks like the code should use cross platform logic it would be good to initially target platform(s) where we have people interested in testing the new code :-)

@reconbot Do you have any preference for which method we use for this? I was thinking of extending the Set and Get methods for this feature, but either Update or a new method could also work. I don't think WebSerial account for this fuctionality, so don't think there is an option of following a standard for this yet, and therefore I assume we need to set the standard

emeryao commented 3 years ago

in my scenario it's a laptop with Windows 10 64bit and I actually wrap the codes to an Elecrton app to communicate with serial port

@GazHank

GazHank commented 3 years ago

Hi @Emeryao, I've created a fork with some initial changes to achieve the parity change functionality at https://github.com/GazHank/node-serialport/tree/parity-change

At the moment this is very limited so we can check if this works. So far:

Next steps (TODO):

I can't really test it this works myself other than monitoring the data over the port as I don't have any devices that are parity dependant, so it would be great if you can check if it works for you

@reconbot if you have any suggestions or guidence on how best to share experimental functionality then please shout, I would like to make sure we can get some robust testing of this functionality before it is promoted to avoid any issues

reconbot commented 3 years ago

We need to know if all platforms support changing this on the fly. It's not a usual thing to change. Get/set/update are a mishmash of apis. I'll have to give it some thought.

GazHank commented 3 years ago

We need to know if all platforms support changing this on the fly. It's not a usual thing to change. Get/set/update are a mishmash of apis. I'll have to give it some thought.

I've mocked up the code for unix platforms but haven't had chance to compile it yet. If anything unix seems more likely to support this since it has the options to initiate the changes immediately, wait until the data has drained, or flush the existing data and apply the changes. I've drafted the update based on draining the existing data, but can always change that.

With some luck Mac will work using the unix code and won't need any extra changes 🤞🏼

GazHank commented 3 years ago

A branch with draft changes for the unix platforms is available at https://github.com/GazHank/node-serialport/tree/parity-change-unix but I don't know when I will get chance to test this out on Linux, so it's available for anyone you would like to take a look and progress this in my absence.

Since both Linux and Mac os appear to use the same logic for setting parity when opening a port (tcsetattr) it looks like this single change should work for both platforms, however there are already some mac os specific comments related to this method call, so it will need to be tested

GazHank commented 3 years ago

@Emeryao would you be able to test if the windows code works for you?

if you clone the windows only branch into a folder alongside you project then you should be able to test the code by adding a resolution into your package.json per below:

    "dependencies": {
        "serialport": "^9.2.0"
    },
    "resolutions": {
        "@serialport/bindings": "file:./../node-serialport/packages/bindings"
    }

By along side I mean that the above assumes that if your project is stored at "c:\abcxyz\myproject\" then the clone of the test branch is stored at "c:\abcxyz\node-serialport\"

Since this is the source code it will need to be compiled from source. Let me know if you need instructions or support with that.

GazHank commented 3 years ago

@ficzusistvan and @NaveenChander are you also interested in this functionality on Windows, or do you have any need for this on other platforms?

At the moment the Unix platforms (Linux and Mac) don't even support a parity of 'space' (or 'mark') therefore I'm inclined to consider this a windows only feature request. If anyone has any non-windows usecases then please shout otherwise I will consider this windows specific (in the same way that low latency mode is currently Linux specific)

NaveenChander commented 3 years ago

Thanks for taking time and looking into it !!! In my specific case Unix is fine as I use raspberry pi for the most part

GazHank commented 3 years ago

@NaveenChander Do you have a situation where you need to change between odd, even and none on the fly? or do you require the ability to set parity to 'space' for this to be useful?

Since we currently don't support parity of 'space' or 'mark' on Linux; I fear we may need to first consider implementing those parity settings before this would be useful for you?

Ps - i should also call out that space and mark parity settings don't seem to be documented as supported under linux or mac (therefore in order to add them we probably need to call them out as unsupported features which users can try at their own risk???)

NaveenChander commented 3 years ago

In my case I had to switch between space and mark parity. I work for a casino company and all slot machines work based on this. This was a protocol that was written almost 20+ years back and it is hard to replace existing all slot machines and I am stuck with it.

GazHank commented 3 years ago

Thanks for the speedy response @NaveenChander I'll see if space and mark parity settings can be added to unix too. Would you be able to test on Linux / raspberry pi if I can share an updated fork with you?

@reconbot are you comfortable if we include the additional parity settings for unix but document them as unsupported/ hardware dependent?

reconbot commented 3 years ago

I'm pretty sure those settings don't work on Mac or Linux. They're very... old hardware specific parities. I got some extra info here https://tldp.org/HOWTO/Serial-HOWTO-20.html#ss20.3

We can try to support them in the platform specific bindings. I'm comfortable.

GazHank commented 3 years ago

@NaveenChander I've updated the unix fork if you would like to test this? It includes space and mark functionality on supported systems (based on #if defined(CMSPAR))

you should be able to use the same resolution approach I suggested earlier, and if you are using raspberry Pi I assume you are pretty well setup to build from source, but please shout if you need any assistance

You might want to play with the settings for tcsetattr since I'm not sure if you want to use now, flush or drain : https://github.com/GazHank/node-serialport/blob/6660a0d2aeaec632894847bafc7bbb2e6d4d9a5d/packages/bindings/src/serialport_unix.cpp#L407-L413

you can find more info about that setting @ https://www.gnu.org/software/libc/manual/html_node/Mode-Functions.html

While it does seem that I can set the parity to space or mark on Linux (ubuntu LTS seems to allow this), I can't be certain if this really works as intended, since I don't have any suitable old hardware to hand (slot machines or otherwise). I'm also not sure if changing parity on the fly works on linux for the same reason. Per @reconbot I don't think mac os supports this at all - hopefully #if defined(CMSPAR) identifies supported systems, but I'd like to make sure we check this

GazHank commented 3 years ago

It looks like we should try to address https://github.com/serialport/node-serialport/issues/1113 as part of any change for this issue...

Depending on where we land with this issue, I'll try to update the docs to match the changes and give extra info on the platforms which support the different settings

emeryao commented 3 years ago

I'm sorry but the very device I mentioned above is at the site of one of our clients which is not reachable for me now 😅

GazHank commented 3 years ago

Thanks for the heads up @Emeryao

I will await testing feedback from yourself or one of the other users; I appreciate that physical access to devices is a little more challenging at the moment.

Since we have a testable fork for windows and unix, I won't create a pull request for this until we have some successful test results

mikeho commented 8 months ago

Hi! I wanted to circle back on this thread -- was this ever implemented into the main branch?

I have a need to support changing parity on the fly as well (similar, in the casino industry). However, when calling port.update(), I can't pass in parity. It seems to only allow changes to baudRate.

Is there any way to change the parity on the fly?

(I attempted to merge the changes from @GazHank , even manually -- but it looks like the serialport code has been significantly refactored since the earlier commits, so the files don't even exist anymore)

I have full access to machines and I'll be able to test immediately on macOS and RPi. Let me know, thanks!

mikeho commented 8 months ago

Okay, so a bit more context about this:

What this means is that we would like to be able to do on-the-fly switching of the parity between even and odd.

But it doesn't seem that SerialPort has this capability out-of-the-box -- when calling port.update(), the only setting I am able to change is baudRate?

Fortunately, I've been able to do a workaround where I literally just close the port, and then re-open the port with the new settings whenever I need to switch from even to odd (or vice versa). I've attached the proof-of-concept code which uses port.close() and re-creates/re-opens the port whenever we need to switch parity. At the very least, I can confirm that this does work. Basically, you can see in sendByte() is where we check the parity, and "switch" between even and odd parity prior to calling port.write().

However, I'm a bit nervous about having my app constantly closing and re-opening the port whenever the parity needs to be switched (which may end up being dozens of times per minute).

So it'd be great if this could be done, maybe via a call to .update()? (which would essentially replace lines 82-94 with just a single call to .update() and then my call to .write())

Appreciation for any assistance that can be provided on the matter. Thanks!!! index.js.txt

mikeho commented 8 months ago

Hello everyone! Just wanted to "bump" this and see if anyone would be able to take a look at this for us? We're more than happy to provide a modest bounty on successful implementation of this. Please let us know, thanks!

mikeho commented 6 months ago

Hello, wanted to bring up this issue again. @reconbot @GazHank just wondering if someone would be able to take a look at this?

We're happy to provide a modest bounty for getting this new feature in there.

Let me know, thanks!!!