Testuję prędkość transmisji seryjnej mojego Arduino UNO. Do moich wymagań muszę przenieść 3KB/s z komputera PC do Arduino. Napisałem bardzo prosty program, który odsyła wynik z Serial.available()
, a następnie przetestował go w monitorze szeregowym Arduino IDE. Zacząłem wysyłać znaki, aż osiągnąłem maksimum, czyli 63 bajty. Byłem bardzo zaskoczony, ponieważ czytałem gdzieś, że Arduino ma bufor na 128 bitów Serial.Powolna transmisja szeregowa Arduino
W każdym razie, stworzyłem bardzo prosty protokół, który przesyła dane w 48 bajtowych pakietach (w rzeczywistości 49 bajtów z powodu znaku nagłówka). Host wysyła znak d
, a następnie 48 bajtów danych. Do testowania poprawności transmisji wysyłam sekwencję bajtów prostych od 0 do 47, która jest sprawdzana po stronie Arduino. Jeśli walidacja nie powiedzie się, UNO zacznie migać diodę LED na urządzeniu PIN13. Po wysłaniu bajtów host oczekuje na potwierdzenie, które jest prostym znakiem k
. Arduino wysyła to, gdy zakończy przetwarzanie rzeczywistego pakietu.
Program hosta mierzy liczbę przesłanych pakietów i wyświetla go po 1 sekundzie. Przy prędkości transmisji wynoszącej 9600 komputer z powodzeniem przesyła ~ 16 pakietów na sekundę (~ 800 bajtów/s), co jest całkiem w porządku. Próbowałem to poprawić, zwiększając prędkość transmisji z obu stron do 57600; jednak liczba wysłanych pakietów wzrasta tylko nieznacznie. Nie wiem, na czym polega problem. Może trafiłem na jakiś limit konwertera szeregowego USB?
Oto mój kod.
PC (Java, używam jSSC dla portu komunikacji szeregowej)
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');
}
}
Zadałem to samo pytanie na forach Arduino, jak również http://arduino.cc/forum/index.php/topic,104699.0.html – NagyI