Java Logger для Arduino - PullRequest
       9

Java Logger для Arduino

2 голосов
/ 04 марта 2012

Я работаю над регистратором Arduino, написанным на Java.

Я начал использовать пример кода с детской площадки Arduino по адресу:

http://arduino.cc/playground/Interfacing/Java

Моя проблема здесь, я думаю:

if (oEvent.getEventType() == SerialPortEvent.DATA_AVAILABLE) {
        try {
            int available = input.available();
            byte chunk[] = new byte[available];
            input.read(chunk, 0, available);


            // Displayed results are codepage dependent
            String print = new String(chunk);
            test.write(print);
            System.out.print(print);


        } catch (Exception e) {
            System.err.println(e.toString());
        }

Я написал класс, который будет записывать данные в CSV-файл. Когда он печатает данные на консоль, это идеально. Когда я записываю его в файл, я получаю несколько прекрасных строк, а иногда и плохих, например:

60
4

5
28

Я хочу напечатать это как:

604
528

Мой метод записи:

public void write(String print)
{

    pw.print(System.currentTimeMillis());
    pw.print(",");
    pw.println(print);
}

Любой совет с благодарностью!

1 Ответ

1 голос
/ 04 марта 2012

Когда вы пишете о печати данных на консоли и в файле, вы не делаете одно и то же. Вы печатаете необработанные данные на консоли, поэтому не видите никаких проблем, пока обрабатываете свои данные в методе 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». Это своего рода автоматическая конкатенация на экране.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...