Я тестирую скорость последовательной передачи моего Arduino UNO. Для моих требований я должен передавать 3 КБ/с с хост-компьютера на Arduino. Я написал очень простую программу, которая возвращает результат Serial.available()
, а затем протестировал ее в мониторе Serial в Arduino IDE. Я начал отправлять символы, пока не достиг максимума, который составляет 63 байта. Меня это очень удивило, потому что я где-то читал, что Arduino имеет 128-байтный последовательный буфер.
Во всяком случае, я разработал очень простой протокол, который передает данные пакетами по 48 байт (фактически 49 байт из-за символа заголовка). Хост отправляет символ d
, затем 48 байтов данных. Для проверки правильности передачи я отправляю простую последовательность байтов от 0 до 47, которая проверяется на стороне Arduino. Если проверка не пройдена, UNO начинает мигать встроенным светодиодом на PIN13. Как только байты отправлены, хост ожидает подтверждения, которое представляет собой простой символ k
. Arduino отправляет это после завершения обработки фактического пакета.
Хост-программа измеряет количество переданных пакетов и отображает его через 1 секунду. При скорости 9600 бод ПК успешно передает ~16 пакетов/сек (~800 байт/сек), что вполне нормально.Я попытался улучшить это, увеличив скорость передачи данных с обеих сторон до 57600; однако количество отправленных пакетов увеличивается лишь незначительно. Я не знаю, в чем проблема. Может быть, я достиг какого-то предела последовательного преобразователя USB?
Вот мой код.
ПК(Java, я использую jSSCдля связи через последовательный порт)
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');
}
}