looking for a simple linux uart application that handles /dev/ttyUSB0 things - Page 1
Forum section: electronics / general

author: legacy
author_rank: Super Contributor
timestamp: December 09, 2014, 04:15:40 pm
content: hii am having a lot of issue with an arduino 2009 interfaced to a linux host.i haven't understand if the problem is related to the arduino side, or to the linux side, my problem is … data lost in the linux host, so it is going like a nightmare to understand why.does anyone has a C source of a simple application that uses the serial port to communicate up to 115200bps ?i'd like to be sure i have implemented everything correctly in the linux side, if so, i will investigate the arduino sideunfortunately i do not have any python machine on such a machine, the arduino is soldered to a SoC, so we are speaking about OpenWRT application not a laptop application and for other reasons i am far away from any practical possibility to unsolder thingslet me know, more tests are neededthanks

author: legacy
author_rank: Super Contributor
timestamp: December 09, 2014, 04:31:44 pm
content: also, basically my linux side code is similar tothisone

author: zapta
author_rank: Super Contributor
timestamp: December 09, 2014, 05:05:01 pm
content: On mac osx I am using 'screen' to dump serial ports. E.g.screen /dev/tty.usbmodemfa131 115200You can try the same on Linux or just dump that serial device directly using cat or similar (Mac OSX has a problem with settty so cat didn't work for me).If you go the Python way, here is a sample serial dumperhttps://github.com/zapta/linbus/tree/master/tools/serial

author: Scrts
author_rank: Frequent Contributor
timestamp: December 09, 2014, 05:10:48 pm
content: Quote from: zapta on December 09, 2014, 05:05:01 pmUART device is a char device in linux, so you just open it as a simple file in your application and do a read or write. Take any example of file reading/writing and use /dev/ttyUSB0 as your file.In addition to screen:you can also use echo "test" > /dev/ttyUSB0 to send data or cat /dev/ttyUSB0 to read everything from the console. The problem is that you need to send or receive ascii chars in order to see them on the console properly.

author: suicidaleggroll
author_rank: Super Contributor
timestamp: December 09, 2014, 05:24:13 pm
content: kermit, minicom, screen, stty/echo/cat, or write your own in practically any programming language you want. Lots of options, which one to choose depends on what type of data is being sent and how much effort you want to put into this. For simple ascii I prefer either minicom or screen, for binary I typically write something in C.

author: zapta
author_rank: Super Contributor
timestamp: December 09, 2014, 05:45:25 pm
content: Quote from: Scrts on December 09, 2014, 05:10:48 pmYou can pipe it to a binary to ascii converter such as 'od'.

author: legacy
author_rank: Super Contributor
timestamp: December 09, 2014, 06:00:17 pm
content: Quote from: suicidaleggroll on December 09, 2014, 05:24:13 pmhave you read my first post ?i can useONLYC!else way i would have used python + pySerialunfortunately i can't

author: suicidaleggroll
author_rank: Super Contributor
timestamp: December 09, 2014, 06:05:33 pm
content: Quote from: legacy on December 09, 2014, 06:00:17 pmThen use C, where is the problem? There are hundreds of examples online that you can choose from, or you could actually post the code you're using here for people to debug.Once the serial protocol is set up, it's a simple matter of reading from the device.Here's the initialization routine from one of my codes that reads/writes to a serial port in C:Code:int serial_setup(const char *device){struct termios options;// Open the serial devicesfd = open(device, O_RDWR | O_NOCTTY | O_NDELAY);if(sfd == -1){fprintf(stderr, "Unable to open device: %s\n", device);return ERR_SERDEV;}fcntl(sfd, F_SETFL, FNDELAY); // Turn off bufferingtcgetattr(sfd, &options); // Load the options struct// Set the I/O speed to 2400 baudcfsetispeed(&options, B2400);cfsetospeed(&options, B2400);cfmakeraw(&options);// Configure for 8 data bits, 1 stop bit, no parity, no flow controloptions.c_cflag &= ~(PARENB | CSTOPB | CSIZE | CRTSCTS);options.c_cflag |= (CLOCAL | CREAD | CS8);// Set it to raw modeoptions.c_oflag &= ~(OCRNL | ONLCR | ONLRET | ONOCR | OFILL | OLCUC | OPOST);// Shut off echooptions.c_lflag &= ~(ECHO | ECHONL | ICANON | IEXTEN | ISIG);options.c_cc = 1; // Minimum number of characters for read = 1options.c_cc = 0; // Non-blocking readtcsetattr(sfd, TCSANOW, &options); // Commit the changesreturn 0;}This is 2400 8N1, no handshaking or flow control, non-blocking. You'll have to adapt it as necessary to suit your application.

author: legacy
author_rank: Super Contributor
timestamp: December 09, 2014, 06:09:19 pm
content: Quote from: suicidaleggroll on December 09, 2014, 06:05:33 pmso, if there are so many examples, provide me one which has been tested and it is known to be working !!!

author: suicidaleggroll
author_rank: Super Contributor
timestamp: December 09, 2014, 06:10:52 pm
content: Quote from: legacy on December 09, 2014, 06:09:19 pmSee my edit

author: suicidaleggroll
author_rank: Super Contributor
timestamp: December 09, 2014, 06:20:35 pm
content: Here's one that logs from the serial port at 115200 and dumps everything that comes in to binary files that split every 1 MiB.Code:#include <stdio.h>#include <stdlib.h>#include <string.h>#include <termios.h>#include <fcntl.h>#include <sys/ioctl.h>//#define BREAK_SIZE 0xA00000 // Split to a new file every 10 MiB#define BREAK_SIZE 0x100000 // Split to a new file every 1 MiBint main (){int sfd, ofd;int n,n2;int bytes;int incr = 0;int bytesum = 0;char filename;struct termios options;char buff;sfd = open("/dev/ttyO0", O_RDWR | O_NOCTTY | O_NDELAY);if (sfd == -1){fprintf(stderr, "unable to open serial port\n");exit(1);}else{fcntl(sfd, F_SETFL, FNDELAY);}tcgetattr(sfd, &options);cfsetispeed(&options, B115200);cfsetospeed(&options, B115200);cfmakeraw(&options);options.c_cflag &= ~(PARENB | CSTOPB | CSIZE | CRTSCTS);options.c_cflag |= (CLOCAL | CREAD | CS8);options.c_oflag &= ~OPOST; // select raw outputoptions.c_cc = 1;options.c_cc = 0;tcsetattr(sfd, TCSANOW, &options);n2 = sprintf(filename, "/data/imu/imu_data_%06d.dat", incr);ofd = open(filename, O_RDWR|O_CREAT);if (ofd == -1){fprintf(stderr, "unable to open output file\n");exit(2);}while (1){ioctl(sfd, FIONREAD, &bytes);if (bytes > 0){n = read(sfd, buff, 10000);//fprintf(stderr, "available/read: %d/%d\n",bytes,n);if (n < 0){fprintf(stderr, "read failed\n");}if (n > 0){if (bytesum > BREAK_SIZE){close(ofd);incr++;n2 = sprintf(filename, "/data/imu/imu_data_%06d.dat", incr);ofd = open(filename, O_RDWR|O_CREAT);if (ofd == -1){fprintf(stderr, "unable to open output file\n");exit(2);}bytesum = 0;}write(ofd, buff, n);bytesum += n;}}usleep(1000);}}I've used this exact code to log from an IMU at 115200 for days straight, no errors, no gaps.If you still have issues, then stick a logic analyzer on the bus and see if the uC is actually transmitting what you think it's transmitting.

author: legacy
author_rank: Super Contributor
timestamp: December 09, 2014, 06:27:43 pm
content: thank you

author: janoc
author_rank: Super Contributor
timestamp: December 09, 2014, 07:07:06 pm
content: If you are getting data but they are messed up every once in a while, the problem is most likely in your protocol. The driver, Linux, Arduino are obviously working.Without seeing your code it is hard to say what could be wrong, but remember that you may not read a whole "packet" at once or you may read some bits of one packet and then some of the following one in a single read because of the buffering in the device driver. Basically, you have to either use delimiters and read until you find one or (better), design your protocol in such way that it sends the length of the data first and then reads exactly that many bytes. This is not Unix-specific, the same is true for any FIFO-like transport - e.g. a pipe, network socket, etc. unless some special measures are taken.Btw, don't rely on stuff like fscanf() - you will get burned! It is safest to read the data into a buffer and then use sscanf() or whatever to parse them once you are sure you have got the complete packet.Good basic examples are in the Linux Serial-Programming-HOWTO:http://tldp.org/HOWTO/Serial-Programming-HOWTO/x115.html#AEN129Look at the non-canonical input part - canonical in Unix terminology means that some special characters are being handled specially (there is a "line discipline") - e.g. a DEL character will actually delete a character from your input buffer. This is old Unix heritage where the serial lines were used for dumb terminals, probably not what you want for transferring data!

author: legacy
author_rank: Super Contributor
timestamp: December 09, 2014, 07:34:32 pm
content: my code is perfectly working with a soft core i have developed on my fpga, i have an uart tap machine which communicates to the host at 115200 sending 16 byte of packet_out, and getting 16 byte of packet_inno problem at all, but in that application i was using a physical uart, while with arduino i am using an USB-SERIAL interfacedifferent kernel modules (COM vs USB_serial/FTDI232), so may be different behavior (e.g. teensy-v2 has a very different behavior when you use it as USB-serial)btw, in the application i am dealing now i have a lot of issues talking with arduino, and i want to be sure my linux C code is correct, it may be the problem is in the arduino side, or in the hw levelfor such a reason i asked a working code linux--arduinoQuote from: janoc on December 09, 2014, 07:07:06 pmi do not want any old-school tty interpretation of the data on the serial port, the protocol is raw binary, it has a lot of functions but basically it looks like thisHOST -> 'T' (which means "shot, give me the full frame acquired"Arduino -> '@', data,checksum <---- here sometimes i got something missing, one or two byte lost, checksum obviously corrupted'@' means "ok" -> function implemented'!' means "no" -> function not implemented

author: legacy
author_rank: Super Contributor
timestamp: December 09, 2014, 07:40:15 pm
content: it may be it doesn't matter, btw t have forced low latencyCode:echo 1 > /sys/bus/usb-serial/devices/ttyUSB0/latency_timer

author: legacy
author_rank: Super Contributor
timestamp: December 09, 2014, 07:44:10 pm
content: Quote from: janoc on December 09, 2014, 07:07:06 pmof course, i am using- read ( std, buffer[], size)- write ( std, buffer[], size)

author: rob77
author_rank: Super Contributor
timestamp: December 09, 2014, 08:00:43 pm
content: Quote from: legacy on December 09, 2014, 07:34:32 pmoh ... really ? explain me please how it was meant... both uart and USB_uart are providing a tty device - that's the purpose of the drivers (kernel modules) to provide a unified interface (tty in this case)Quote from: legacy on December 09, 2014, 07:34:32 pmexactly that's the reason why you should listen a and read the suggested documents ! you have to get rid of the line discipline to get your RAW data.and quite honestly... you making too much noise around a trivial issue - sorry for saying this... but if you're not able to troubleshoot a trivial issue, then most likely you'll not succeed

author: nctnico
author_rank: Super Contributor
timestamp: December 09, 2014, 08:10:28 pm
content: What is the USB interface speed? If it is the lowest speed (1.5Mb/s) the USB interface may not have enough bandwidth to get the packets across. Another problem could be insufficient buffering inside the FT232 or the Linux host reading data too slow. I'd start with setting the Arduino part to 9600 baud and see what that does.

author: legacy
author_rank: Super Contributor
timestamp: December 09, 2014, 08:39:04 pm
content: Quote from: nctnico on December 09, 2014, 08:10:28 pm9600 works perfectly with arduino19200 works perfectly with arduino38400 works perfectly with arduino115200 has data lost, sometimesthe SoC has a built-in USB1, so high speed, i suspect the problem is related to your suggestion

author: legacy
author_rank: Super Contributor
timestamp: December 09, 2014, 08:49:14 pm
content: Code:sint32_t uart_open(char_t port[],uint32_t baud,boolean_t is_timeout_enabled,uint32_t timeout){sint32_t fd;/* Try to open the uart port */fd = open(port, O_RDWR | O_NOCTTY);if (fd == IO_error){fprintf(stderr, "error, %s is unknown\n", port);}else{/** Apply the proper port settings to the port*/uart_setup(fd, baud, is_timeout_enabled, timeout);fprintf(stderr, "%s at %lubps, ", port, baud);fprintf(stderr, "opened\n");}return fd;}Code:void uart_setup(sint32_t fd,uint32_t baud,boolean_t is_timeout_enabled,uint32_t timeout){termios_t ios;p_termios_t p_ios;uint32_t iosbaud;p_ios = &ios;/* See what our baud rate is */switch (baud){case 1200:iosbaud = B1200;break;case 9600:iosbaud = B9600;break;case 19200:iosbaud = B19200;break;case 38400:iosbaud = B38400;break;case 115200:iosbaud = B115200;break;case 230400:iosbaud = B230400; /* untested */break;case 460800:iosbaud = B460800; /* untested */break;default:/* no deal with this baud rate */fprintf(stderr, "[!] error: Unknown baud rate %lu\n", baud);exit(1);break;}/* Zero out the new port settings */memset(p_ios, 0, sizeof(ios));/* Create the new port settings */ios.c_iflag = IGNBRK;ios.c_oflag = 0;ios.c_cflag = iosbaud | CS8 | HUPCL | CREAD | CLOCAL;ios.c_lflag = 0;if (is_timeout_enabled == True){/** apply a timeout of 0.x sec (x deciseconds)*/ios.c_cc = 0;ios.c_cc = timeout;}else{/** apply no timeout*/ios.c_cc = 1;ios.c_cc = 0;}uart_set_timeout(fd, is_timeout_enabled);/* Flush the input buffer to get rid of any lingering garbage */tcflush(fd, TCIFLUSH);/* Apply the new port settings */tcsetattr(fd, TCSANOW, p_ios);/* Flush the input buffer again */tcflush(fd, TCIFLUSH);}/** POSIX Control Characters* The c_cc character array contains control character definitions* as well as timeout parameters.* Constants are defined for every element of this array.** Setting Software Flow Control Characters** The VSTART and VSTOP elements of the c_cc array contain* the characters used for software flow control. N* ormally they should be set to DC1 (17) and DC3 (19),* representing the defacto standard XON and XOFF characters.** Setting Read Timeouts* UNIX uart interface drivers provide the ability* to specify character and packet timeouts.* Timeouts are ignored in canonical input mode.* Two elements of the c_cc array are used for timeouts: VMIN and VTIME.** VMIN specifies the minimum number of characters to read.* If it is set to 0, then the VTIME value specifies* the time to wait for every character read.* If it is non-zero, VTIME specifies* the time to wait for the first character read.* If a character is read within the time given,* any read will block (wait) until all VMIN characters are read.* That is, once the first character is read,* the uart interface driver expects* to receive an entire packet of characters (VMIN bytes total).* If no character is read within the time allowed,* then the call to read returns 0.* VTIME specifies the amount of time to wait for incoming characters* in tenths of seconds.* If VTIME is set to 0 (the default),* calls to read will block (wait) indefinitely* unless the NDELAY option is set on the port with open or fcntl*/void uart_set_timeout(sint32_t fd,boolean_t is_timeout_enabled){/** Reading Data from the Port* Reading data from a port is a little trickier.* When you operate the port in raw data mode,* each read(2) system call will return* however many characters are actually available in the uart input buffers.* If no characters are available, the call will block (wait)* until characters come in, an interval timer expires,* or an error occurs.* The read function can be made to return immediately* by doing the following:* fcntl(fd, F_SETFL, FNDELAY);* The FNDELAY option causes the read function to return 0* if no characters are available on the port.** To restore normal (blocking) behavior,* call fcntl() without the FNDELAY option:* fcntl(fd, F_SETFL, 0);** This is also used after opening a uart port with the O_NDELAY option.*/if (is_timeout_enabled isEqualTo True){/** don't block uart read*///fcntl(fd, F_SETFL, FNDELAY);}else{/** blocking behavior*/fcntl(fd, F_SETFL, 0);}}this is a part of my actual linux side, i have enabled the timeout support for the serial

author: legacy
author_rank: Super Contributor
timestamp: December 09, 2014, 08:54:12 pm
content: Code:void test_artuino_serial(){uint32_t n;sint32_t ans;uint8_t buff; /* useless, size = 1*/uint8_t frame[16486+2+1];uint32_t i;uint32_t iframe_top;printf("sfd=%ld\n", uart_fd);iframe_top = frame_size_y * frame_size_x;iframe_top += 1;n = 1;buff = CMD_PING;write(uart_fd, buff, n);if (ans < 1){printf("write error\n");return;}n = 1;ans = read(uart_fd, buff, n);printf("->%c\n", buff);n = 1;buff = CMD_TAKE_FRAME;write(uart_fd, buff, n);if (ans < 1){printf("write error\n");return;}buff = '-';while (buff != 'R'){n = 1;ans = read(uart_fd, buff, n);printf("%d ", buff);if (ans < 1){printf("read error\n");return;}}printf("OK1\n");for (i = 0; i < iframe_top + 1; i++){n = 1;read(uart_fd, buff, n);if (ans < 1){printf("read error\n");return;}frame = buff;printf("%d ", buff);}i--;printf("\n");printf("checksum ->%d\n", frame[i - 1]);printf("ans ->%c\n", frame);}this is the easy-dummy-test using the above code: simply trying to read 128x128+2 bytes from arduinoresults:at 9600: success, no timeout, checksum is OKat 38400: success, no timeout, checksum is OKat 115200: failure, sometimes 2 bytes lost, checksum error

author: nctnico
author_rank: Super Contributor
timestamp: December 10, 2014, 01:12:31 am
content: You may have to consider 115200 cannot work. Be sure to check the USB speed with the output from dmesg.

author: f1rmb
author_rank: Regular Contributor
timestamp: December 10, 2014, 05:34:03 am
content: What kind of atmega your arduino embed?Eg, you can't use 115200 with a Leonardo (32U4), the compiler will also tell you that begin() parameter is truncated.---Daniel

author: Psi
author_rank: Super Contributor
timestamp: December 10, 2014, 07:13:50 am
content: What crystal are you using on the arduino?If it's not a multiple of the baud rate you can expect error rates as high as 8%

author: Unknown
author_rank: Unknown
timestamp: December 10, 2014, 08:01:58 am
content: Quote from: Psi on December 10, 2014, 07:13:50 amThis.Based on experience, and depending on the hardware & software, RS-232-alike serial comms starts getting hairy when the difference between expected & actual baud rate is more than 2%~3%. On a 16MHz Arduino, 115.2k is going to be 3%~4% off.

author: legacy
author_rank: Super Contributor
timestamp: December 10, 2014, 08:29:13 am
content: this project has been developed by different guysfrom the hardware guy i got a board which looks like the Yunso there is a SoC (Atheros MIPS @400Mhz with built-in USB controller (1))interfaced to anATmega328(datasheet) @ 16MhzSoC ---- built in USB (OHCI->USB1) -------- FTDI232 -------- serial 5V -------- ATmega328 @ 16Mhz(1) the first problem is: why the firmware (linux side) guy has not used EHCI (USB2) instead of OHCI (USB1) ?i have to understand itbtw, the Arduino side looks like a clone of the board "Arduino 2009"wandering if i could get the same SoC around and the same board, in order to get more investigationsp.s.the YUN seems to have higher uart speedp.s.2from my point of view, the "teensy-v2" hardware is betteri have tested it on my laptop (laptop x86 ---USB2---teensy2 with built in USB device)up to 900Kbyte/sec over the usb-serial with the same software i am talking aboutno issues, no data corrupted, no timeout, everything works great

author: legacy
author_rank: Super Contributor
timestamp: December 10, 2014, 09:18:48 am
content: Quote from: nctnico on December 10, 2014, 01:12:31 amdmesg says the USB is handled by OHCI (wandering why not EHCI instead? .. i will try to recompile the kernel and see what happens)and the device3 (arduino) is USB1 full speed which should be 12M bit/secin theory it should be fine enough to handle 115K bit/secthe first problem is: what happens if linux gets a long burst stream (128x128+2=16386byte)in where every single URB/bulk has 1 byte instead of 64 ?supposing the baud rate drift is not relevantfor 115200bit/sec it means something like 10Kbyte/sec -> 10K URB / seci trust the kernelis perfectly able to handle it, even if …… it's not an ideal situation and probably it is not the best optimized ideateensy-v2 has no baud generator, so no drift issuesand the linux kernel side uses serial-class instead of a serial-driver, that permits to send 64byte per packetit means that you know exactly what happens in the chain, so you could organize your firmware that wayand in the linux application side you could also use read(fd,buffer,64) instead of 64 times for {read(fb,&ch,1)}just considerations … unfortunately i can ask the team to change the hardwarebtw i am suspecting the problem is related to the % error due to the baud rate (frequency drift)like you say, guys (thank your for your considerations)or something in the hardware layer

author: Monkeh
author_rank: Super Contributor
timestamp: December 10, 2014, 10:20:15 am
content: Quote from: legacy on December 10, 2014, 08:29:13 amBecause EHCI is used for high speed devices, and virtually every USB connected UART is a low speed or full speed device? This is not a choice made by your firmware guy.

author: legacy
author_rank: Super Contributor
timestamp: December 10, 2014, 11:07:19 am
content: Quote from: Monkeh on December 10, 2014, 10:20:15 amyou are absolutely right !my point is: while i am waiting for the kernel sources (someone should send me sooner) i have looked a the Carambola's kernel because it looks very similar to the SoC i am talking about: the kernel support for v3.3.8 i see these choicesCode:CONFIG_USB_EHCI_HCD: ?? ?? The Enhanced Host Controller Interface (EHCI) is standard for USB 2.0 ?? "high speed" (480 Mbit/sec, 60 Mbyte/sec) host controller hardware. ?? If your USB host controller supports USB 2.0, you will likely want to ?? configure this Host Controller Driver. ?? ?? EHCI controllers are packaged with "companion" host controllers (OHCI ?? or UHCI) to handle USB 1.1 devices connected to root hub ports. Ports ?? will connect to EHCI if the device is high speed, otherwise they ?? connect to a companion controller. If you configure EHCI, you should ?? probably configure the OHCI (for NEC and some other vendors) USB Host ?? Controller Driver or UHCI (for Via motherboards) Host Controller ?? Driver too.which has a combo EHCI/OHCI support and needs "EHCI support for AR7XXX/AR9XXX SoCs"so i should see EHCI and OHCI in the dmesg, initialized during the boot, while i am seeing only OHCI … andi wander why(and unfortunately the USB has no connector, everything is soldered on the PCB, so i can't plug an USB-hard drive to see what happens with a USB2 device, perhaps not without an hw hack)btw, these are the dmesg's line when the SoC sees ArduinoCode:usb 4-1: new full speed USB device number 3 using ohciusb 4-1: New USB device found, idVendor=0403, idProduct=6001usb 4-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3usb 4-1: Product: FT232R USB UARTusb 4-1: Manufacturer: FTDIusb 4-1: SerialNumber: A700emu6usb 4-1: usb_probe_deviceusb 4-1: configuration #1 chosen from 1 choiceusb 4-1: adding 4-1:1.0 (config #1, interface 0)usbserial_generic 4-1:1.0: usb_probe_interfaceusbserial_generic 4-1:1.0: usb_probe_interface - got idftdi_sio 4-1:1.0: usb_probe_interfaceftdi_sio 4-1:1.0: usb_probe_interface - got idftdi_sio 4-1:1.0: FTDI USB Serial Device converter detectedusb 4-1: Detected FT232RLusb 4-1: Number of endpoints 2usb 4-1: Endpoint 1 MaxPacketSize 64usb 4-1: Endpoint 2 MaxPacketSize 64usb 4-1: Setting MaxPacketSize 64usb 4-1: FTDI USB Serial Device converter now attached to ttyUSB0it's OHCI, USB1, full speedi'd like to test both endpoints with a maximal usage equal to MaxPacketSize, i mean 64byte per packetin the afternoon i will try to change the Arduino firmware in order to test this featurethe current firmware has the endpoints maximal usage equal to 1 byte per packet

author: legacy
author_rank: Super Contributor
timestamp: December 10, 2014, 11:19:14 am
content: about Arduino 2009, there 2 versions (due to the possibility to replace the DIP package MPU), the first with AtMega328, and the second with AtMega168, which looks quite similar (even if not exactly equals)i am reading the AtMega168data sheet: on page 197 it would seem to suggest that with a 16MHz clock the serial port can handle 1Mbps, in case … 1Mbps >> 115200bps, so it "should" be fine in my case, or notwhich is the maximum baud rate you have successfully experimented with Arduino 328/168 and a linux SoC ?

author: janoc
author_rank: Super Contributor
timestamp: December 10, 2014, 11:23:09 am
content: Um, silly question - since it fails only at higher baudrates, are you sure that the Arduino is actually using a crystal and not a (cheap) ceramic resonator? Some clones have these!

author: nctnico
author_rank: Super Contributor
timestamp: December 10, 2014, 11:29:33 am
content: Quote from: legacy on December 10, 2014, 11:07:19 amThen there is your problem. You really need to fill USB packets to the max because in USB there is a roundtrip time for each packet. If you fill a packet with only one byte then you limit the USB bandwidth way below the maximum bandwidth.

author: Monkeh
author_rank: Super Contributor
timestamp: December 10, 2014, 11:32:21 am
content: Quote from: legacy on December 10, 2014, 11:07:19 amWho cares? You don't need EHCI.

author: legacy
author_rank: Super Contributor
timestamp: December 10, 2014, 11:47:33 am
content: right, toojust curious

author: legacy
author_rank: Super Contributor
timestamp: December 10, 2014, 11:51:26 am
content: Quote from: janoc on December 10, 2014, 11:23:09 amGood question!The hardware may be described as "custom clone", practically speaking the Arduino side is like the "Arduino 2009 board" but developed by our hardware guys and integrated in the same PCB with an Atheros SoC: it looks like the Arduino Yun but it has a DIP-package MPU (AtMega 328)ummm you are right about a thing i have not considered yet: the board has cheap ceramic resonator

author: nctnico
author_rank: Super Contributor
timestamp: December 10, 2014, 12:15:42 pm
content: The baudrate doesn't have to be very accurate. There is a tolerance of 1% IIRC.

author: legacy
author_rank: Super Contributor
timestamp: December 10, 2014, 12:42:54 pm
content: @nctnicoyou get the issue fixed, definitively !i have changed both the arduino firmware and the linux application sides in order to packet things in 64byte (according to the size of the bulk endpoints)results9600 still Ok19200 still Ok38400 still Ok115200bps stable, no errors, no data lost, no corruption, good checksum230400bps stable, no errors, no data lost, no corruption, good checksum460800bps and upper bauds rates are untestedit worksbetterandfaster, thank your for your helpnow i have to contact the Arduino firmware guy, and make him to commit my patchlet me say, i am not the arduino firmware guy, about this project … in an ideal world my task should be relatedONLYto the linux application, an more specifically to the algorithm model (using matlab to experiment and tune up ideas into code) to process all the stream from the arduino, which is connected to an optical sensor.in the real world, as usual, i have to become the hardware/firmware/everythings guyno problem with this, except the fact that my knowledges are limited, sovery very thanks for your help, really, guys

author: janoc
author_rank: Super Contributor
timestamp: December 10, 2014, 01:48:38 pm
content: Quote from: nctnico on December 10, 2014, 12:15:42 pmIf the board has only a resonator, then it is going to be marginal at 115200bps - those things have a tolerance +-0.5% (crystals have ~0.001% typical).I would still change it for a crystal, just to be safe.

author: nfmax
author_rank: Super Contributor
timestamp: December 10, 2014, 02:28:43 pm
content: 'Asynchronous' serial communications actually synchronises each time a new start bit arrives, and most UARTs sample data during the middle third of each bit time. The bit times are based on the baud rate as set by the local UART clock; there is also a sampling uncertainty relative to this clock in knowing when the start bit arrived. Including parity and stop bits, a character is usually 10 bits long. For the sampling instant on the 10th bit not to have drifted out ofthe middle third, i.e. not by more than 1/6 bit time, the maximum clock error between sending & receiving clocks must be less than 1.667%. Allowing a margin for the uncertainty in the start bit detection time gives around 1.5% as the maximum tolerable error between the send & receive clocks. In practice, you can go a bit worse than this (in the absence of noise) as again most UARTs actually make multiple samples during each bit time & decide between 1 & 0 by the majority of the sample values.

author: westfw
author_rank: Super Contributor
timestamp: December 11, 2014, 10:22:59 am
content: QuoteI don't know why people keep repeating this. The ability of a uart to accurately receive data when the clock is "not quite right" is NOT dependent on the speed. Only on the percentage of error.That said, a 16MHz (exactly) AVR as used on most arduinos is "marginal" at 115200bps (2.1% off) because of the limitations of the bitrate generator. It works fine on most modern Arduino boards, because the USB/Serial converter is ALSO an AVR with the same logic, and the code is very careful to make sure the error goes in the same direction. If you happen to use some other USB/Serial logic that introduces error in the OTHER direction, you can easily have failures.(My FTDI-based older arduinos and derivatives seem to work fine at 115200, but ... I'm continually nervous, and I'm not sure they'd pass a long-term data test.)Also, 115200bps is one character every 86 microseconds (~1200 instruction times.) It's pretty easy to write code that doesn't service the uart often enough to avoid overruns.

author: legacy
author_rank: Super Contributor
timestamp: December 11, 2014, 10:51:11 am
content: so, 115200bps is the upper limits ?

author: legacy
author_rank: Super Contributor
timestamp: December 11, 2014, 03:59:03 pm
content: new tests applying the data-packet size patch (64 byte per packet over usb/BULK)setting 460800 on arduino side, 460800 on linux side not correctly recognized by linux, so not working, time out, 100% data lostsetting 460800 on arduino side, 500000 on linux side, is working at 500Kbps, no corruption, no data lost, everything is OK from a long run test (10Mbyte sent)wandering why 460800 on arduino side, and 500000 on linuxminicom is confirming that (not working if linux set to 460800bps, perfectly working if set to 500000)btw, i am going faster (500000bps) than expected (115200bps), excellent guys

author: westfw
author_rank: Super Contributor
timestamp: December 11, 2014, 06:14:08 pm
content: QuoteNo. People have reported success with 1Mbps; in that case the 16MHz yields an exactly correct bit rate.200k, 250k, and 500k should come out exactly work as well.(Of course, you have to be even more careful that your code is fast enough to handle the bitrate. The 1Mbps example I know if is the Arduino Optiboot Bootloader, which does ~256 byte flash sectors that it receives all at once (and nothing else at the same time, and not using interrupts), with "got it" and "send me the next" on either side.)

author: janoc
author_rank: Super Contributor
timestamp: December 12, 2014, 10:52:57 pm
content: Quote from: westfw on December 11, 2014, 10:22:59 amWhich is not in contradiction to what I have said. What you are saying is obviously true, but there is another thing to consider. If you have a resonator and its frequency is "wandering" with temperature, your bitrate is going to (obviously) wander as well.Quote from: westfw on December 11, 2014, 10:22:59 amI am not so sure about the "error going in the same direction" - it is not only about the clockspeed being a multiple of the bitrate so that you minimize the error but also frequency stability. The USB AVR uses a regular crystal on the new Arduino Uno. The main AVR is using a resonator. So if their frequences drift, it is going to be tougher and tougher to keep things in sync and error-free over long transmissions at high bitrates.

author: legacy
author_rank: Super Contributor
timestamp: December 14, 2014, 03:39:43 pm
content: Arduino vs TeensyThe atmega328p in the Arduino/Uno serie does serial transmit and receive, and a separate chip converts this into serial-over-USB. The Teensy uses a different AVR chip that has built-in USB support, so there is no need to go via serial. The manufacturer of the Teensy claims that the Teensy has direct 12 MBit/sec USB access and also claims for the RAWHID library functions: You can send up to 1000 packets per second in each direction, where each packet is 64 bytesmy protocol is able to work at 500Kbps over usb-serial just because it has acknowledges (send data packet and wait, then go on), but it's a dirty trick

author: legacy
author_rank: Super Contributor
timestamp: December 16, 2014, 01:14:22 pm
content: Quotefromhere, also … it seems the problem is kernel side and libc side, also i am not using the the termio2