Sériová komunikácia – experimenty

Arduino – analog read + serial

int analogPin = 3;

void setup() {
   Serial.begin(9600);
}

void loop() {
   int val = analogRead(analogPin);
   Serial.println(val);
   delay(100);
}


Arduino kód

#define MAX_LINE_LEN 50

char lineBuffer[MAX_LINE_LEN];
int lineLen = 0;

void setup() {
  Serial.begin(9600);
}

void loop() {
  while (Serial.available() > 0) {
    char c = Serial.read();   
    lineBuffer[lineLen] = c;
    lineLen++;
    if ((c == '\n') || (lineLen == MAX_LINE_LEN)) {
      Serial.write(lineBuffer, lineLen);
      lineLen = 0;
    }
  }
}

Java kód

package sk.upjs.iot.serial;

import java.util.*;

import jssc.SerialPort;
import jssc.SerialPortException;

public class SerialLineIO {

  /**
   * Zapuzdreny seriovy port.
   */
  private final SerialPort port;

  /**
   * Vlakno realizujuce citanie.
   */
  private final Thread thread;

  /**
   * Priznak poziadavky na ukoncenie.
   */
  private volatile boolean stopFlag;

  /**
   * Riadky na odoslanie.
   */
  private Queue linesToSend = new LinkedList<>();

  /**
   * Synchronizacny zamok.
   */
  private final Object lock = new Object();

  public SerialLineIO(SerialPort port) {
    this.port = port;
    thread = new Thread(this::loop);
  }

  /**
   * Nastartuje IO.
   */
  public void start() {
    thread.start();
  }

  /**
   * Zastavi IO.
   */
  public void stop() {
    stopFlag = true;
    synchronized (lock) {
      lock.notifyAll();
    }
  }

  private void loop() {
    StringBuilder lineBuilder = new StringBuilder();
    try {
      while (!stopFlag) {
        // ak mame riadky na odoslanie, tak ich posleme
        String lineToSend = null;
        synchronized (linesToSend) {
          lineToSend = linesToSend.poll();
        }
        if (lineToSend != null) {
          port.writeString(lineToSend);
          continue;
        }

        // skusime precitat prijate data
        int[] receivedData = port.readIntArray();

        if (receivedData != null) {
          // ak mame nejake prijate data, tak ich spracujeme a hladame konce riadkov
          for (int b : receivedData) {
            if (b == '\n') {
              handleLine(lineBuilder.toString());
              lineBuilder.setLength(0);
            } else {
              lineBuilder.append((char) b);
            }
          }
        } else {
          // ak nemame data, tak uspime vlakno, aby sme umiernili cinne cakanie
          synchronized (lock) {
            try {
              lock.wait(100);
            } catch (InterruptedException ignore) {
              // nic na pracu
            }
          }
        }
      }
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      try {
        port.closePort();
      } catch (SerialPortException ignore) {

      }
    }
  }

  /**
   * Odosle riadok na seriovy port.
   * 
   * @param line
   *            riadok
   */
  public void sendLine(String line) {
    if (!line.endsWith("\n")) {
      line = line + "\n";
    }

    synchronized (linesToSend) {
      linesToSend.add(line);
    }

    // prerusime cakanie hlavneho vlakna
    synchronized (lock) {
      lock.notifyAll();
    }
  }

  /**
   * Spracuje prijaty riadok.
   * 
   * @param line
   *            prijaty riadok (bez znaku konca riadka).
   */
  private void handleLine(String line) {
    System.out.println(line);
  }
}

package sk.upjs.iot.serial;

import java.util.Scanner;

import jssc.SerialPort;
import jssc.SerialPortException;

public class App {
  public static void main(String[] args) {
    // Otvorime a pripravime seriovy port.
    SerialPort serialPort = new SerialPort("COM5");
    try {
      serialPort.openPort();
      serialPort.setParams(SerialPort.BAUDRATE_9600, SerialPort.DATABITS_8, SerialPort.STOPBITS_1,
          SerialPort.PARITY_NONE);
    } catch (SerialPortException ex) {
      System.out.println("Zlyhalo otvorenie serioveho portu: " + ex);
    }

    // Vytvorime a nastartujeme jednoduchy thread-safe wrapper pre seriovy port
    SerialLineIO lineIO = new SerialLineIO(serialPort);
    lineIO.start();

    // Citame vstup po riadkoch
    try (Scanner s = new Scanner(System.in)) {
      while (s.hasNextLine()) {
        lineIO.sendLine(s.nextLine());
      }
    }
  }
}