-
Notifications
You must be signed in to change notification settings - Fork 1k
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
Serial port read returns no data with Arduino Leonardo #164
base: main
Are you sure you want to change the base?
Conversation
…ectly without having to be initialized by another application.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the pull request! I had some comments and requested changes, but after those I think it should be ok to take them.
@@ -70,7 +70,7 @@ Serial::SerialImpl::open () | |||
0, | |||
0, | |||
OPEN_EXISTING, | |||
FILE_ATTRIBUTE_NORMAL, | |||
FILE_ATTRIBUTE_NORMAL, // FILE_FLAG_OVERLAPPED |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change doesn't seem to do anything, can you please remove it?
dcbSerialParams.fNull = FALSE; | ||
dcbSerialParams.fRtsControl = RTS_CONTROL_ENABLE; | ||
dcbSerialParams.fAbortOnError = FALSE; | ||
dcbSerialParams.fOutxCtsFlow = FALSE; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some of these settings are set lower in this function, so it seems this line will not have any effect. Can you only set the ones that are not set elsewhere? These are the ones I see that are redundant, but you should double check me :)
fOutX
fInX
fRtsControl
fOutxCtsFlow
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fwiw I was seeing the same thing with an Arduino uno and was able to get it working by adding only the following line:
dcbSerialParams.fDtrControl = DTR_CONTROL_ENABLE;
On the off-chance that some of this is generally useful.
Like @tmpvar, I was able to get Arduino Leonardo (compatible) to work with a simple change to DTR. I also enabled RTS, for standard compatibility with terminals, and I have not tested to be sure that is not needed for Leonardo, but in my opinion not relevant. The DTR and RTS signals out of an RS232 port have more or less standard meanings. And a standard port those signals are always being output (whether or not the device at other end of the cable receives or implements those signals). The settings The normal handshake on a device (from the old days of RS232) would be to wait for DTR to be turned "on" before attempting communication. Then the RTS "on" condition would allow transfer of data (but this is part of the flow control handshake). So normally one would turn both signals "on" unless they were specifically in use for flow control as a default, in case the hardware at the far end did depend upon them, even if flow control is not implemented. (By the way, flow control on RTS would then turn RTS on to allow transfer of data, and off to stop transfer--thus the default of "on" when not using flow control at the PC end just in case so it does not stop such data transfer .) All this said, I made the following code changes in win.cc's The key point is that after these changes, the Arduino Leonardo started to work. And these changes should make the defaults more compatible for other applications. // setup flowcontrol
if (flowcontrol_ == flowcontrol_none) {
dcbSerialParams.fOutxCtsFlow = false;
dcbSerialParams.fOutxDsrFlow = false; // [GLE]
dcbSerialParams.fRtsControl = RTS_CONTROL_ENABLE; // RTS_CONTROL_DISABLE; // [GLE] enable
dcbSerialParams.fDtrControl = DTR_CONTROL_ENABLE; //DTR_CONTROL_DISABLE; // [GLE] add, enable
dcbSerialParams.fOutX = false;
dcbSerialParams.fInX = false;
}
if (flowcontrol_ == flowcontrol_software) {
dcbSerialParams.fOutxCtsFlow = false;
dcbSerialParams.fOutxDsrFlow = false; // [GLE]
dcbSerialParams.fRtsControl = RTS_CONTROL_ENABLE; // RTS_CONTROL_DISABLE; // [GLE] enable
dcbSerialParams.fDtrControl = DTR_CONTROL_ENABLE; //DTR_CONTROL_DISABLE; // [GLE] add, enable
dcbSerialParams.fOutX = true;
dcbSerialParams.fInX = true;
}
if (flowcontrol_ == flowcontrol_hardware) {
dcbSerialParams.fOutxCtsFlow = true;
dcbSerialParams.fOutxDsrFlow = false; // [GLE]
dcbSerialParams.fRtsControl = RTS_CONTROL_HANDSHAKE;
dcbSerialParams.fDtrControl = DTR_CONTROL_ENABLE; //DTR_CONTROL_DISABLE; // [GLE] add, enable
dcbSerialParams.fOutX = false;
dcbSerialParams.fInX = false;
}
if (flowcontrol_ == flowcontrol_hardware_DTR_DSR) {
dcbSerialParams.fOutxCtsFlow = false;
dcbSerialParams.fOutxDsrFlow = true; // [GLE]
dcbSerialParams.fRtsControl = RTS_CONTROL_ENABLE; // RTS_CONTROL_DISABLE; // [GLE] enable
dcbSerialParams.fDtrControl = DTR_CONTROL_HANDSHAKE; // [GLE]
dcbSerialParams.fOutX = false;
dcbSerialParams.fInX = false;
} Also note that @wjwood commented on the line To answer the question @wjwood asked, these settings continue with their default values (off in the original code) until a top level function invokes the DTR or RTS function. Either an RTS or a DTR on setting is required for the Arduino to communicate via the port. The example code does not do this, thus for an Arduino the RTS and DTR signals are off, apparently stopping it from working. (Another interesting note is that an Arduino Leonardo has no actual hardware port, and these settings are virtual in software port--furthermore the baud rate is ignored and communicates at full rate of the USB bus.) How this should be handled is an interesting question. If an application is going to control those functions then the defaults shown here are probably wrong, and the "DISABLE" variants should probably be the default, so that the high level program enables those. However the example serial code does not do that, and using those high level functions to enable DTR would most likely allow the Leonardo to work as well. If used, it makes more sense that the Data Terminal Ready (the PC is the "Data Terminal" in its role using the old terminology of RS232) and it should not be made ready until the application is ready. So the above is not a complete or compelling set of changes, rather just a demonstration of a method that works when the high level application does not enable the pins. Perhaps a better method would be to revert to default 'DISABLE' states for both RTS and DTR, or build a more complex tracking mechanism so the reconfiguration follows a state variable for each. The tracking problem exists because if the high level code set RTS, then changed to flow control on RTS, then back to no flow control, the high level setting of "on" would need to be preserved, or else it would mysteriously turn off or would need to be re-implemented after the flow control change. That could be the subject of a future change (beyond the topic here -- but at the heart of the problem that causes the Arduino and/or Arduino Leonardo to not work in the example code). By the way, there are other issues with Windows 10 implementation that must be fixed to work with Arduino, also separate topics. Turning on DTR seems to allow Arduino to work. |
I switched from an Arduino Nano (328P) to an Arduino Nano 33 BLE and ran into the issue that commands sent via serial to the Arduino were no longer executed. By using the proposed patch of @GordonLElliott , I could solve my issue. |
I ran into a problem with an Arduino Leonardo board. When first plugged I was able to open the serial port without error, but could not read any data from the device. I tried explicitly setting each of the serial parameters, but the only thing that was working for me was to run PuTTY before running my own code that uses 'serial', in which case the port would work correctly, only to fail again the next time I plugged in the board.
This patch borrows the boilerplate device control block settings from PuTTY to initialize the serial device, which fixes the problem with 'serial'.