I am testing the serial transmission speed of the Arduino UNO. For my requirements, I have to transfer 3KB / s from the host to Arduino. I wrote a very simple program that is responsible for the result Serial.available(), and then tested it on an Arduino IDE serial monitor. I started sending characters until I reached a maximum value of 63 bytes. I was very surprised by this because I read somewhere that the Arduino has a 128 byte serial buffer.
In any case, I made up a very simple protocol that transmits data in 48-byte packets (actually 49 bytes due to the header character). The host sends the character d, and then 48 bytes of data. To check if the transfer is correct, I send a simple sequence of bytes from 0 to 47, which is checked on the Arduino side. If the test fails, UNO will start flashing with the integrated LED on PIN13. Once the bytes are sent, the host waits for confirmation, which is a simple character k. Arduino sends this after the processing of the actual packet is complete.
The host program measures the number of transmitted packets and displays them after 1 second. At a transmission speed of 9600 PCs successfully transmits ~ 16 packets / second (~ 800 bytes / s), which is quite normal. I tried to improve this by increasing the data transfer rate on both sides to 57600; however, the number of sent packets increases only slightly. I do not know what the problem is. Perhaps I hit some limit of the USB to serial converter?
Here is my code.
PC (Java, I use jSSC for serial communication)
package hu.inagy.tapduino.server;
import jssc.SerialPort;
import jssc.SerialPortException;
public class App
{
private static void testComm(SerialPort port) throws SerialPortException {
long runningSeconds = 0;
long time = System.currentTimeMillis();
long numberOfPackets = 0;
boolean packetSent = false;
while (runningSeconds < 10) {
long currentTime = System.currentTimeMillis();
if (currentTime - time > 1000) {
runningSeconds++;
time = currentTime;
System.out.println(numberOfPackets + " packets/s");
numberOfPackets = 0;
}
if (!packetSent) {
packetSent = true;
port.writeByte((byte) 'd');
for (int i = 0; i < 48; i++) {
port.writeByte((byte) i);
}
} else {
byte[] received = port.readBytes();
if (received != null) {
if (received.length > 1) {
throw new IllegalStateException("One byte expected, instead got: " + received.length);
}
char cmd = (char) received[0];
if ('k' != cmd) {
throw new IllegalStateException("Expected response 'k', instead got: " + cmd);
}
packetSent = false;
numberOfPackets++;
}
}
}
}
public static void main(String[] args)
{
SerialPort port = new SerialPort("COM7");
try {
if (!port.openPort()) {
throw new IllegalStateException("Failed to open port.");
}
port.setParams(57600, 8, 1, 0);
} catch (SerialPortException e) {
throw new IllegalStateException("Exception while setting up port.", e);
}
try {
Thread.sleep(1500);
} catch (InterruptedException e) {
throw new IllegalStateException("Interrupt while waiting?", e);
}
try {
testComm(port);
} catch (SerialPortException exc) {
throw new IllegalStateException("Failure while testing communication.", exc);
} finally {
try {
if (!port.closePort()) {
throw new IllegalStateException("Failed to close port.");
}
} catch (SerialPortException e) {
throw new IllegalStateException("Exception while closing port.", e);
}
}
}
}
Arduino
void setup() {
pinMode(13, OUTPUT);
Serial.begin(57600);
}
boolean error = false;
void loop() {
if (error) {
digitalWrite(13, HIGH);
delay(1000);
digitalWrite(13, LOW);
delay(1000);
} else {
while (Serial.available()<49);
char cmd = Serial.read();
if ('d'!=cmd) {
error=true;
return;
}
for (int i=0; i<48; i++) {
int r = Serial.read();
if (r!=i) {
error=true;
return;
}
}
Serial.write('k');
}
}