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

Feature requests: DCD & DSR events, DTR toggle #291

Closed echicken closed 7 years ago

echicken commented 10 years ago

It'd be useful (to me) to be able to attach callbacks to events that get fired off when the state of the DCD and DSR pins change (with the argument supplied to the callback being the current state of the pin in question.) Being able to raise and lower DTR would also be helpful.

voodootikigod commented 10 years ago

Any chance you could provide a little more details about what DCD and DSR are (these are new to me).

Thanks,

Chris

On Mon, Jan 13, 2014 at 7:26 PM, echicken notifications@github.com wrote:

It'd be useful (to me) to be able to attach callbacks to events that get fired off when the state of the DCD and DSR pins change (with the argument supplied to the callback being the current state of the pin in question.) Being able to raise and lower DTR would also be helpful.

— Reply to this email directly or view it on GitHubhttps://github.com/voodootikigod/node-serialport/issues/291 .

Chris Williams

@voodootikigod http://twitter.com/voodootikigod | GitHubhttp://github.com/voodootikigod

The things I make that you should check out: SaferAging http://www.saferaging.com/ | JSConf http://jsconf.com/ | RobotsConf http://robotsconf.com/ | RobotsWeeklyhttp://robotsweekly.com/

Help me end the negativity on the internet, share thishttp://jsconf.eu/2011/an_end_to_negativity.html .

echicken commented 10 years ago

These pages put it better than I likely could (not much need to read past the first paragraph):

http://en.wikipedia.org/wiki/Data_Carrier_Detect http://en.wikipedia.org/wiki/Data_Terminal_Ready

In general DCD is used by a peripheral to send a status change to the computer it's connected to. In the case of an external modem, for example, a change from low to high on this pin means that a connection has been made, and from high to low means that the call has ended.

DSR and DTR are used for flow control purposes. When DSR is low, the peripheral is not ready to receive data; when DSR is high it is ready. DTR serves the same purpose, but in the opposite direction - the computer signalling its readiness to the peripheral. (It's possible that DTR/DSR flow control is already being handled at a lower level by this module - I do see that a toggle was added some time ago. Being able to toggle DTR would still be a bonus, if for some reason I wanted to tell the peripheral not to send data to me for a while.)

voodootikigod commented 10 years ago

Awesome, thanks!

On Tue, Jan 14, 2014 at 11:11 AM, echicken notifications@github.com wrote:

These pages put it better than I likely could (not much need to read past the first paragraph):

http://en.wikipedia.org/wiki/Data_Carrier_Detect http://en.wikipedia.org/wiki/Data_Terminal_Ready

In general DCD is used by a peripheral to send a status change to the computer it's connected to. In the case of an external modem, for example, a change from low to high on this pin means that a connection has been made, and from high to low means that the call has ended.

DSR and DTR are used for flow control purposes. When DSR is low, the peripheral is not ready to receive data; when DSR is high it is ready. DTR serves the same purpose, but in the opposite direction - the computer signalling its readiness to the peripheral. (It's possible that DTR/DSR flow control is already being handled at a lower level by this module - I do see that a toggle was added some time ago. Being able to toggle DTR would still be a bonus, if for some reason I wanted to tell the peripheral not to send data to me for a while.)

— Reply to this email directly or view it on GitHubhttps://github.com/voodootikigod/node-serialport/issues/291#issuecomment-32278464 .

Chris Williams

@voodootikigod http://twitter.com/voodootikigod | GitHubhttp://github.com/voodootikigod

The things I make that you should check out: SaferAging http://www.saferaging.com/ | JSConf http://jsconf.com/ | RobotsConf http://robotsconf.com/ | RobotsWeeklyhttp://robotsweekly.com/

Help me end the negativity on the internet, share thishttp://jsconf.eu/2011/an_end_to_negativity.html .

Rantanen commented 10 years ago

Ability to manually toggle DTR would be of great use for Arduino applications given Arduino has DTR wired up to the reset circuitry. Being able to force reset Arduino over the the serial connection would be great. Especially in the older revisions which have a bit weak reset circuitry that often ends up in a reset-loop .

The manual set_dtr method was there in commit 642070aa but was dropped in the massive f44e7e66f commit for some reason.

reconbot commented 10 years ago

Do we know the capabilities of the FTDI (and the chips arduino's other than the UNO use). DTR is probably pretty standard, but I know not all interfaces support all capabilities.

Rantanen commented 10 years ago

Uno, Mega, Nano: DTR (http://arduino.cc/en/Main/arduinoBoardMega2560)

Leonardo, Micro, Yun, Lilypad USB: The reset is triggered when the Leonardo's virtual (CDC) serial / COM port is opened at 1200 baud and then closed. (http://arduino.cc/en/Main/arduinoBoardLeonardo)

Due: Similar mechanism to Leonardo and Micro but instead of reset performs Reset + Erase which is less useful (http://arduino.cc/en/Main/ArduinoBoardDue)

Looking at Lilypad FTDI schematic the FTDI pins are: DTR, RXI, TXO, VCC, CTS, GND. The DTR is wired to the reset pin through a capacitor. So it seems atleast on the FTDI Lilypad the DTR is used to trigger the reset. Assuming the DTR of the FTDI is wired straight to the DTR of the USB bit in between.

Rantanen commented 10 years ago

Actually looking at the description on the Arduino Pro:

One of the pins on the six-pin header is connected to the reset line of the ATmega168 or ATmega328 via a 100 nanofarad capacitor. This pin connects to one of the hardware flow control lines of the USB-to-serial convertor connected to the header: RTS when using an FTDI cable, DTR when using the Sparkfun breakout board.

gyillikci commented 10 years ago

Voodoo It would be great to have DTR control.

dazhbog commented 10 years ago

+1

i3fox commented 10 years ago

For me it is important to manual control DTR

voodootikigod commented 10 years ago

Consolidating to ticket #384

jgillick commented 8 years ago

This has been closed by DCD & DSR have not been addressed. Is there any way to read these values with this library?

reconbot commented 8 years ago

I opened it back up, as far as I know, you can't read these states or get events when that happens.

jgillick commented 8 years ago

Thank you. For my purposes, I have a communication bus and need a way for any node on it to send a simple HIGH/LOW signal back to the host outside of the communication channel. The easiest way would be to attach that to the DCD or DSC line on an FTDI chip (FT232RL).

jgillick commented 8 years ago

A possible temporary work around: I haven't tried this yet, but it might be possible with a combination of node-serialport and ioctl. I assume it would look something like this:

const SerialPort = require("serialport");
const ioctl = require('ioctl');

// From ioctl.h
const TIOCMGET  = 0x741d;
const TIOCM_CAR = 0x100;

// Connect
var port = new SerialPort("/dev/tty-usbserial1");

// Get DCD value
var buff = new Buffer(1);
ioctl(port.fd, TIOCMGET, buff);
var dcd = buff[0] & TIOCM_CAR;
jgillick commented 8 years ago

I have some good news, and some bad news.

Good news

I was able to add support for this feature in a forked repo! (forked commit)

There's not a PR since I haven't written tests yet. I'm debating writing tests, based on the bad news...

Bad news

It seems like the standard FTDI driver (VCP serial port driver) does not make these values available. (at least that's the answer I got here). So for most USB to Serial adapters, this update won't provide anything useful.

Solution?

As far as I can tell, the only way to get these values from an FTDI chip is by using the D2XX driver. Then these values can be accessed directly from their C API. Unfortunately, it doesn't seem like you can access the device as a serial port when you're using this method. So this solution is moot for node-serialport. However, there is a solution for those who are stuck in this situation...

The node-ftdi module provides bindings to the D2XX APIs and I've submitted a PR to add bindings to make the modem status values available.

Conclusion?

So, I'm not sure where that leaves this feature request. The forked commit I made would probably be useful to real serial ports, but I'm not sure how common that would be.

echicken commented 8 years ago

Well, that sounds promising. Thanks for your efforts - I'll try this out soon. The "real serial ports" scenario probably isn't all that common, but it's the one I'm interested in.

At a glance the main problem with D2XX or node-ftdi would be the need to 'find' the device rather than access it via a name ('COM4') or path ('/dev/ttyUSBx', etc.), or otherwise figure out how to address it. Past that point the D2XX API seems to have everything that's needed.

Perhaps use of D2XX could be a config toggle for those who know that they need it. (Not that I want to complicate things. I can see why you're debating going further with this.)

jgillick commented 8 years ago

A nice thing about D2XX addressing, is when you set the VID/PID on the chip (via FT_PROG), you can target your device directly, instead of asking the user to select from the list of serial devices. I'm not entirely sure how to pick a good VID/PID though. For now I'm using the FTDI default VID and custom PID.

I haven't tested reading/writing to the device with node-ftdi yet.

jgillick commented 8 years ago

More good news. It looks like the problem in my earlier message, isn't really a problem. It turns out that the stock FTDI drivers on OS X are buggy and do not provide access to the control signals (original post). Downloading the drivers from FTDI fixes the problem...mostly.

I can now get the accurate signal status from a simple python script I wrote and the ruby script from the fore mentioned post. However, my updates to node-serialport still don't seem to read them. That's okay, though, this gives me hope.

jgillick commented 8 years ago

And it turned out to be a silly little typo in my code.

My fork of the code is now working on OS X, Windows (and I assume Linux)!

see diff

reconbot commented 8 years ago

@neilger we can support querying for the status but we don't currently have a way to support firing events when the status changes.

neilger commented 8 years ago

I can handle firing the event, but how is the status read? I thought your prior note said that you can't.

On Wed, Oct 5, 2016 at 5:49 PM, Francis Gulotta notifications@github.com wrote:

@neilger https://github.com/neilger we can support querying for the status but we don't currently have a way to support firing events when the status changes.

reconbot commented 8 years ago

It's possible for us to support polling, we don't currently. As far as I can tell we don't know how to support getting events when it changes.

neilger commented 8 years ago

In pyserial I do this by waiting:

     while (s.getDSR() != True):
        time.sleep(0.001)

That's the simple functionality I'd like to replicate.

On Wed, Oct 5, 2016 at 5:54 PM, Francis Gulotta notifications@github.com wrote:

It's possible for us to support polling, we don't currently. As far as I can tell we don't know how to support getting events when it changes.

jgillick commented 8 years ago

@reconbot If the work I did in my fork will help, I can submit a pull request. I haven't been able to get around to writing unit tests, so I haven't submitted the PR.

@neilger You can try it out and see if it works for you. I added a get method to retrieve these values. (although it might be better to call it something like status or modem or something else)

reconbot commented 8 years ago

I thought your fork was specific to the USB serial driver you were using?

On Fri, Oct 7, 2016, 12:09 AM Jeremy Gillick notifications@github.com wrote:

@reconbot https://github.com/reconbot If the work I did in my fork https://github.com/EmergingTechnologyAdvisors/node-serialport/compare/master...jgillick:master will help, I can submit a pull request. I haven't been able to get around to writing unit tests, so I haven't submitted the PR.

@neilger https://github.com/neilger You can try it out and see if it works for you. I added a get method to retrieve these values. (although it might be better to call it something like status or modem or something else)

— You are receiving this because you were mentioned.

Reply to this email directly, view it on GitHub https://github.com/EmergingTechnologyAdvisors/node-serialport/issues/291#issuecomment-252148794, or mute the thread https://github.com/notifications/unsubscribe-auth/AABlbrkjGcgWbZh4fXdSpDIcs94CGWZNks5qxcX6gaJpZM4BZe01 .

jgillick commented 8 years ago

No, sorry about the back and forth with the discussion above. That code should work for any standard serial port.

There were some problems with the driver on my side that initially led me down a path of a custom D2XX implementation. However, when I realized that I just needed to upgrade my driver, I went back to implementing something more standard. I've tested this code with FTDI devices using the standard driver on Mac and Windows.

reconbot commented 8 years ago

@jgillick well I suppose get and set do have a nice symmetry to them. Lets not worry naming yet and get this in beta 5. Please PR!

(We might consider chrome's getControlSignals and setControlSignals not that I love those names but they're more descriptive)

reconbot commented 7 years ago

Closing since this is now merged.