I'm testing my Arduino UNO's serial transmission speed. For my requirements I have to transfer 3KB/s from the host PC to the Arduino. I've written a very simple program which replies back the result of Serial.available()
and then tested it in the Arduino IDE's Serial monitor. I've started sending characters until I reached the maximum which is 63 bytes. I was quite surprised of that because I read somewhere that the Arduino has a 128byte Serial buffer.
Anyway, I've made up a very simple protocol which transmits data in 48 byte packets (actually 49 bytes because of the header character). The host sends a d
character then 48 bytes of data. For testing the validity of the transmission I'm sending a simple byte sequence from 0 to 47 which gets validated on the Arduino side. If the validation fails the UNO starts to blink the onboard LED on PIN13. Once the bytes are sent, the host waits for an acknowledgement which is a simple k
character. The Arduino sends this once it finishes processing the actual packet.
The host program measures the number of transmitted packets and displays it after 1 second. With a baud rate of 9600 the PC successfully transmits ~16 packets/second (~800 bytes/sec) which is quite ok. I've tried to improve this by increasing the baud rate on both sides to 57600; however, the number of sent packets increase only a little. I don't know what the problem is. Maybe I've hit some kind of limit of the USB serial converter?
Here is my code.
PC (Java, i'm using jSSC for serial port communication)
package hu.inagy.tapduino.server;
import jssc.SerialPort;
import jssc.SerialPortException;
/**
* Test Arduino communication.
*/
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 {
// Wait 1.5sec for Arduino to boot successfully.
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');
}
}
It's because you're using Serial. parseInt() . It uses a timeout to find the end of the data on the serial port, and while it's waiting for that timeout it can do nothing else.
By design, Serial port communications are very slow. On real serial port, maximum speed is 115200 bauds, which means 11520 chars par second if there is a continuous flow.
begin(9600)'. This starts serial communication, so that the Arduino can send out commands through the USB connection. The value 9600 is called the 'baud rate' of the connection. This is how fast the data is to be sent.
A synchronous serial interface always pairs its data line(s) with a clock signal, so all devices on a synchronous serial bus share a common clock. This makes for a more straightforward, often faster serial transfer, but it also requires at least one extra wire between communicating devices.
NagyI, jSSC method writeByte(byte b) is the same writeBytes(new byte[]{b}). For example:
serialPort.writeByte((byte)0xFF);
serialPort.writeBytes(new byte[]{(byte)0xFF});
These strings are equivalent. writeByte() method create a new byte array for every byte that you want to send. Creating an object is an expensive operation in Java, that's why, if you need hi-speed data transfer use prepared byte arrays like in your answer. Regards, Alexey.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With