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

echicken opened this Issue Jan 14, 2014 · 20 comments


None yet

8 participants


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.


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


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


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 642070a but was dropped in the massive f44e7e6 commit for some reason.


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.


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.


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.


Voodoo It would be great to have DTR control.




For me it is important to manual control DTR


Consolidating to ticket #384


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

@reconbot reconbot reopened this May 26, 2016

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


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


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;
@reconbot reconbot added the backlog label Aug 22, 2016
@reconbot reconbot referenced this issue Aug 22, 2016

Roadmap #746

4 of 11 tasks complete

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.


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.


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.


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


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.


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 Sep 28, 2016 edited

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment