Когда вы пишете о печати данных на консоли и в файле, вы не делаете одно и то же. Вы печатаете необработанные данные на консоли, поэтому не видите никаких проблем, пока обрабатываете свои данные в методе write (), который может вызвать некоторые проблемы.
Проблема не в вашем методе write (), а в том, как вы его используете. Как только у вас есть данные, вы распечатываете их. Дело в том, что вы, возможно, не получили все данные, поэтому распечатываете их слишком рано.
Это довольно распространено в потоке данных: операционная система предупреждает вас, когда данные доступны, но она может получать только (скажем) 3 байта из 5, отправленных Arduino, когда она предупреждает вас. Операционная система сама по себе не может знать, что вы ждали 5 байтов, а не только 3.
Таким образом, вы должны хранить и объединять свои данные, пока не узнаете, что все они были получены. Для этого есть две возможности:
- Если вы знаете, что будет отправлено n байтов, сохраняйте данные до тех пор, пока не получите n байтов
- Дождитесь флага символа, обозначающего конец ваших данных: я полагаю, вы используете метод Serial.println () в Arduino, это означает, что конец ваших данных будет иметь "\ r \ n" в конце. Кстати, именно поэтому у вас есть несколько новых строк в файле при печати данных, так как вы не сказали Jave создавать новые строки: -)
Код мог бы быть лучше, но для простоты, поскольку я не уверен в вашем уровне в Java, и для сохранения вашего кода вы могли бы сделать что-то подобное (предупреждение, я не проверял это):
// Should be outside of your serialEvent method
StringBuilder buffer = new StringBuilder();
public synchronized void serialEvent(SerialPortEvent oEvent) {
if (oEvent.getEventType() == SerialPortEvent.DATA_AVAILABLE) {
try {
int available = input.available();
byte chunk[] = new byte[available];
input.read(chunk, 0, available);
// We store data in a buffer
buffer.append(new String(chunk));
// We check if we received the characters indicating
// the end of your data
int endOfLineIndex = buffer.indexOf("\r\n");
// We don't, so we leave and wait for more data
if (endOfLineIndex == -1) {
return;
}
// The "+2" is to keep the "\r\n"
String print = buffer.substring(0, endOfLineIndex+2);
// Do not forget to remove what was used in the buffer
buffer.delete(0, endOfLineIndex+2);
test.write(print);
System.out.print(print);
} catch (Exception e) {
System.err.println(e.toString());
}
}
// Ignore all the other eventTypes, but you should consider the other ones.
}
Кстати, если вы не видите никаких проблем при прямой печати данных в консоли, это происходит потому, что символы новых строк происходят из Arduino, а не из кода Java. Таким образом, вы печатаете поток данных, который не разбит, потому что вы ничего не вставляете между символами, которые вы печатаете на экране. В вашем примере вы сначала получаете «60», затем «4 \ r \ n». Это своего рода автоматическая конкатенация на экране.