java - serie - velocidad de transmision puerto serial
TransmisiĆ³n en serie lenta Arduino (4)
Encontré la solución. La función writeByte de jSSC es altamente ineficiente en este caso. Si hice previamente el búfer de 49 bytes en Java y luego lo paso de inmediato a jSSC, recibo un aumento de velocidad muy grande.
byte[] sendBuffer = new byte[49];
sendBuffer[0] = ''d'';
for (byte i = 0; i < 48; i++) {
sendBuffer[i + 1] = i;
}
port.writeBytes(sendBuffer);
En el foro de Arduino, un miembro me sugirió la velocidad en baudios 345600 que ahora me da ~ 240 paquetes / seg (~ 12KB / seg).
Estoy probando la velocidad de transmisión serie de mi Arduino UNO. Para mis requisitos, tengo que transferir 3KB / s desde la PC host al Arduino. Serial.available()
un programa muy simple que contesta el resultado de Serial.available()
y luego lo probé en el monitor Serial IDE de Arduino. Empecé a enviar caracteres hasta que alcancé el máximo, que es de 63 bytes. Estaba bastante sorprendido de eso porque leí en alguna parte que el Arduino tiene un búfer en serie de 128 bytes.
De todos modos, inventé un protocolo muy simple que transmite datos en paquetes de 48 bytes (en realidad 49 bytes debido al carácter del encabezado). El host envía un caracter d
luego 48 bytes de datos. Para probar la validez de la transmisión, estoy enviando una secuencia de bytes simple de 0 a 47 que se valida en el lado de Arduino. Si la validación falla, UNO comienza a parpadear el LED integrado en PIN13. Una vez que se envían los bytes, el host espera un acuse de recibo que es un simple carácter k
. El Arduino lo envía una vez que termina de procesar el paquete real.
El programa host mide el número de paquetes transmitidos y lo muestra después de 1 segundo. Con una velocidad en baudios de 9600, la PC transmite con éxito ~ 16 paquetes / segundo (~ 800 bytes / seg), lo que está bastante bien. Intenté mejorar esto aumentando la velocidad en baudios en ambos lados a 57600; sin embargo, la cantidad de paquetes enviados aumenta solo un poco. No sé cuál es el problema. Tal vez he alcanzado algún tipo de límite del convertidor serial USB?
Aquí está mi código.
PC (Java, estoy usando jSSC para comunicación de puerto serie)
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'');
}
}
Recientemente, utilicé este tutorial para conectar el dispositivo Arduino UNO a la PC por cable: Arduino y Java .
NagyI, el método jSSC writeByte (byte b) es el mismo writeBytes (new byte [] {b}). Por ejemplo:
serialPort.writeByte((byte)0xFF);
serialPort.writeBytes(new byte[]{(byte)0xFF});
Estas cadenas son equivalentes. El método writeByte () crea una nueva matriz de bytes para cada byte que desea enviar. Crear un objeto es una operación costosa en Java, por eso, si necesita una transferencia de datos de alta velocidad, use matrices de bytes preparadas como en su respuesta. Saludos, Alexey.
¿Has intentado agregar esta línea a tu función Arduino setup () ?:
Serial.setTimeout(100); //this will make the Arduino wait a max of only 100ms per incoming set of serial data, before moving on
Lea aquí: http://arduino.cc/en/Serial/SetTimeout
Arduino tiene de forma predeterminada un tiempo de espera de 1 segundo que debe transcurrir si simplemente utiliza Serial.read () para leer datos nuevos. Vea mi respuesta aquí para más información y una forma más limpia de manejar esto: la interfaz serie de Matlab con Arduino es muy lenta