Closed NicoHood closed 8 years ago
I didn't throw an oscope on the serial port, but if I select 250K baud in Serial.begin() & in the serial monitor, data passes just fine on the current version of OSX.
No, we are talking about the USB CDC Serial, not the Hardware Serial. Please read the Problem fully. The OS passes wrong parameters to the USB device so the USB device sets the USART wrong. And the wrong baud is the last selected baud. This bug happens with 250k, 500k, 1m and 2m. Possibly with any other non standard baudrate.
WIth USB CDC serial on the Leonardo, the selected baud rate shouldn't matter at all, it is not used. So I presume you mean CDC serial on the 16u2 on e.g. a Uno, which connects to the HardwareSerial on the 328 side. Assuming that @BrentWilkins was using a Uno or similar, his test confirmed that the entire stack supports 250k, from Serial monitor to HardwareSerial.
IIRC reliably selecting non-standard baudrates is a bit tricky on Linux, so it's likely that his works on OSX, but breaks on Linux.
I quickly tested this sketch:
void setup() {
Serial.begin(250000);
Serial.println("Hello, world!");
}
void loop() {
}
Opening the serial monitor at 250000 shows a bit of garbage, suggesting that indeed the serial port wasn't opened at 250kbaud at the PC side. This is probaly something that needs to be fixed in the Java serial library used (Can't remember if that's rxtx or jssc).
As for selecting non-standard baudrates, see this post:
http://marc.info/?l=linux-serial&m=143049135615695&w=2
(conclusion is that it sucks to set non-standard baudrates, but I think 250000 might be "standard enough" to work with the right prodding)
Well I added a function to my core which lets you return the value of the CDC baud setting. Depending on this setting the HW Serial1 is set. And because the PC opens the CDc Serial not at those non standard values and switches to the last selection or 9600 250000 doesnt work properly with the UNO and other Arduinos. The bridge (16u2) get a wrong USART setting and though the data is not transferred correctly. Not with the IDE at least. minicom works perfectly.
Looking at the JSSC code for setting baudrates, this is not a standard baud rate that can be set normally.
JSSC also contains some code for setting arbitrary custom baudrates, based on the ASYNC_SPD_CUST
flag. However, as the mailing lis post linked above states, this is no supported by all drivers. In particular, the cdc_acm driver used by most Arduino boards does not support it (the ftdi_sio driver used by older boards with an FTDI chip does support it).
The mailing list post suggests using BOTHER
to set custom baudrates, but there are some unanswered portability questions with it. Also, this requires modifying JSSC to use this other API.
I think that, within Arduino, the best we can do here is disable the 250000 baudrates on Linux (and perhaps others which are not part of the standard baudrates listed in JSSC / the Linux kernel). This means it will also be disabled on the FTDI-based boards, where it is technically supported.
An alternative (or actually, a good idea in any case) is to check the return value of setParams
here (and probably also here). AFAICS, this should return false when the baudrate could not be set, allowing an error to be shown to the user instead of silently using the previous settings. This might actually be the best approach going forward.
Too bad. 2M would be so nice X_x A note would be nice, so people are not confused like I was. But there must be a way, I mean minicom can open the serial properly with ACM.
@NicoHood, 2M should be possible, since that is a standard baudrate in JSSC (and I think also supported by the kernel). Though there might be a different problem with such high speeds, I recall reading a mailing list thread or another bug report about that.
And indeed, minicom can do it, so I suppose that uses the BOTHER
API, as I mentioned in my comment, which is not (currently) supported by JSSC.
I recently had a problem with another linux application. Maybe that can help a bit. It seems that only root users can open non standard baud rates. Meaning the dialout group is not enough maybe.
I do not know if the root user could open the port with that baud rate, but it had at least the privileges to do that. Meaning it wont work with a normal user and no special rights. Idk, maybe this helps a bit.
Weird, I can't think of any reason why running as root would enable more custom baudrate options... Also, the report you link says that even though you didn't get an error as root, you also didn't get the requested baudrate, so I don't hink this is any help to us.
I dont know if I got the requested baud rate. I could not test it because the requested baud rate was wrong and out of sync with my Arduino. Even if it would set the rate correct I would not had a chance to check if its working correctly.
So I tested a few things...
I managed to get a 500k and 2M optiboot working on my Arduino Uno. This requires:
stty -F /dev/ttyACM1 2000000
AVRDUDECMD=avrdude -p m328p -P $(SERIAL_DEV) -b 2000000 -c arduino
This worked with 500k and 2M. These are baud rates I can also open with minicom. I cannot open 250k with minicom or use it as bootloader speed. So 250k needs some more stuff to implement. But maybe >500k, 1M and 2M can be patched. If a non standard baud rate is detected it could try the stty command. This way we could use faster bootloaders and also faster Serial Monitor rates. You should add a note that everything >115200 could cause problems on some systems.
Same problem for 74880 and maybe others as well. I was confused again. Totally kept me off from work. Not that this is a problem, its more that beginners will be confused as hell.
I tried this blindly myself now: https://github.com/NicoHood/Arduino/commit/3d418671eaf2b79dd1b231612d9aaeddf3f86a0f
The command cannot be executed for some reason. Manually entering the command works.
Uploading using selected port: /dev/ttyACM0
Test
stty -F /dev/ttyACM0 2000000
java.io.IOException: Cannot run program "stty -F /dev/ttyACM0 2000000": error=2, No such file or directory
at java.lang.ProcessBuilder.start(ProcessBuilder.java:1048)
at java.lang.Runtime.exec(Runtime.java:620)
at java.lang.Runtime.exec(Runtime.java:485)
at processing.app.helpers.ProcessUtils.exec(ProcessUtils.java:11)
at cc.arduino.packages.Uploader.executeUploadCommand(Uploader.java:115)
at cc.arduino.packages.uploaders.SerialUploader.uploadUsingPreferences(SerialUploader.java:156)
at processing.app.debug.Compiler.upload(Compiler.java:168)
at processing.app.Sketch.upload(Sketch.java:1174)
at processing.app.Sketch.exportApplet(Sketch.java:1148)
at processing.app.Sketch.exportApplet(Sketch.java:1120)
at processing.app.Editor$DefaultExportHandler.run(Editor.java:2421)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.io.IOException: error=2, No such file or directory
at java.lang.UNIXProcess.forkAndExec(Native Method)
at java.lang.UNIXProcess.<init>(UNIXProcess.java:248)
at java.lang.ProcessImpl.start(ProcessImpl.java:134)
at java.lang.ProcessBuilder.start(ProcessBuilder.java:1029)
... 11 more
Runtime.getRuntime().exec("stty -F " + userSelectedUploadPort + " 2000000");
instead works. I can upload at 2M! I am not that java pro and I also compiled the IDE for the first time, but there should be a way to implement this better on linux. Should not be too hard.
Edit2: uploading 27kb program to the arduino takes about 1sec less with 2M compared to 115200. This had nothing to do with the issue directly, but a faster bootloader wont save much here since programming the flash cells itself takes too long.
I think in your original attempt, you should specify each part of the command (the command name and each argument) as a separate array element. This part is normally handled by a shell (which translates from a single string to a list of arguments by splitting on whitespace), which I suspect what the exec method you're using in the latter attempt also does.
I'm closing this issue as a duplicate of arduino/serial-monitor#33, which addresses this issue a bit more generically.
As documentated and discussed here: https://github.com/urjaman/fast-usbserial/issues/1
If you open the Serial at baud 250000 it will open the Serial at the last selected baud instead. And thatswhy it doesnt work. This was tested on Ubuntu 14.04 x64 with IDE 1.6.5 release. It might be an OS issue due to a non standard baud. Or it is an IDE problem. Otherwise 250k could work. The program minicom can open it properly under Ubuntu. This was not tested on Windows. See discussion there for more information.