views:

510

answers:

2

hi, i'm reading data from serial port for average interval say 1 second,and at the same time writing read data to textArea and textfile,problem is i'm not getting correct data at some time,may be because i'm doing all three process in a single program,how to do writing to text area and text file by separate thred?

this is my code:

import java.io.BufferedWriter;
import java.io.File;

import java.io.FileWriter;

import java.io.IOException;
import java.io.InputStream;

import java.text.SimpleDateFormat;

import java.util.Date;
import java.util.Iterator;

import java.util.TooManyListenersException;
import java.util.TreeMap;

import javax.comm.CommPortIdentifier;
import javax.comm.SerialPort;
import javax.comm.SerialPortEvent;
import javax.comm.SerialPortEventListener;
import javax.comm.UnsupportedCommOperationException;
import javax.swing.JOptionPane;

import com.pressure.constants.Constants;

import com.pressure.online.OnlineStartWindow;

public class SerailReader implements SerialPortEventListener {

    // DECLARES INPUT STREAM TO READ SRIAL PORT
    private InputStream inputStream;
    // DECLARES PORT
    private CommPortIdentifier port;
    private SerialPort serialPort;

    // DATE TO CREATE FILE NAME
    private static final SimpleDateFormat SDF = new SimpleDateFormat("dd-MM-yy");


    private int index = 0;

    private File file;

    private OnlineStartWindow onlineStartwindow;

    private int[] tempIntArray = new int[233];
    private int newData = 0;

    private String outFolder;

    private String filename = "0";

    private FileWriter fileWriter;

    private BufferedWriter buffOut;
    private StringBuffer line;
    private String packetFilename;

    TreeMap<Integer, Float> channelMap = new TreeMap<Integer, Float>();

    ThreadPrintsAndWrites p;

    public FileWriter getFileWriter() {
     return fileWriter;
    }

    public void setFileWriter(FileWriter fileWriter) {
     this.fileWriter = fileWriter;
    }

    public BufferedWriter getBuffOut() {
     return buffOut;
    }

    public void setBuffOut(BufferedWriter buffOut) {
     this.buffOut = buffOut;
    }

    // SETTER GETTER TO OnlineStartwindow OBJECT
    public OnlineStartWindow getOnlineStartwindow() {
     return onlineStartwindow;
    }

    public void setOnlineStartwindow(OnlineStartWindow onlineStartwindow) {
     this.onlineStartwindow = onlineStartwindow;
    }

    // SETTER GETTER TO SERIALPORT
    public SerialPort getSerialPort() {
     return serialPort;
    }

    public void setSerialPort(SerialPort serialPort) {
     this.serialPort = serialPort;
    }

    // ********* connects to serial port ***********//
    public void SerialReadmethod(OnlineStartWindow onlineStartwindow,
      String outFolderPath) throws Exception {

     setOnlineStartwindow(onlineStartwindow);
     outFolder = outFolderPath;
     // SELECTS PORT NAME SELECTED

     port = CommPortIdentifier.getPortIdentifier(getOnlineStartwindow()
       .getComPort());
     System.out.println("port name " + port);

     // CHEAK WETHER SELECTED PORT AVAILABLE OR NOT
     if (port.getPortType() == CommPortIdentifier.PORT_SERIAL) {

      if (port.getName().equals(getOnlineStartwindow().getComPort())) {

       JOptionPane.showMessageDialog(null, "Successpully opened port",
         "Online Dump", JOptionPane.INFORMATION_MESSAGE);

      }

     }

     // OPENS SERAIL PORT
     serialPort = (SerialPort) port.open("SimpleReadApp1111", 1000);

     // OPENS SERIAL PORT INPUT STREAM TO READ DATA
     try {
      inputStream = serialPort.getInputStream();

     } catch (IOException e) {
      System.out.println("IO Exception");
     }

     // ADDS LISTNER TO SERIALPORT
     try {
      serialPort.addEventListener(this);

     } catch (TooManyListenersException e) {
      System.out.println("Tooo many Listener exception");
     }

     // EVENT GENERATED WHEN DATA WILL BE AVAILABELE ON SERIALPORT
     // INPUTSTREAM
     serialPort.notifyOnDataAvailable(true);

     try {

      // SETS SELECTED BAUDRATE

      int BAUDRATE = Integer.parseInt((getOnlineStartwindow()
        .getBaudRate()).trim());

      // SETS SELECTED DATA BITS

      int DATABITS = Integer.parseInt(getOnlineStartwindow()
        .getDataBits().trim());
      if (DATABITS == 8) {
       DATABITS = SerialPort.DATABITS_8;
      } else if (DATABITS == 7) {
       DATABITS = SerialPort.DATABITS_7;
      } else if (DATABITS == 6) {
       DATABITS = SerialPort.DATABITS_6;
      } else if (DATABITS == 5) {
       DATABITS = SerialPort.DATABITS_5;
      }

      // SETS SELECTED STOPBITS
      int STOPBITS = 0;

      if (getOnlineStartwindow().getStopBits() == "1") {
       STOPBITS = SerialPort.STOPBITS_1;
      } else if (getOnlineStartwindow().getStopBits() == "1.5") {
       STOPBITS = SerialPort.STOPBITS_1_5;
      } else if (getOnlineStartwindow().getStopBits() == "2") {
       STOPBITS = SerialPort.STOPBITS_2;
      }

      // SETS SELECTED PARITY
      int PARITY = 0;
      if (getOnlineStartwindow().getParity() == "NONE") {
       PARITY = SerialPort.PARITY_NONE;
      } else if (getOnlineStartwindow().getParity() == "EVEN") {
       PARITY = SerialPort.PARITY_EVEN;
      } else if (getOnlineStartwindow().getParity() == "ODD") {
       PARITY = SerialPort.PARITY_ODD;
      }

      // SETS SELECTED FLOW CONTROL
      int FLOWCONTROL = 0;
      if (getOnlineStartwindow().getFlowControl() == "NONE") {
       FLOWCONTROL = SerialPort.FLOWCONTROL_NONE;
      } else if (getOnlineStartwindow().getFlowControl() == "XON/XOFF") {
       FLOWCONTROL = SerialPort.FLOWCONTROL_XONXOFF_IN;
      }

      serialPort
        .setSerialPortParams(BAUDRATE, DATABITS, STOPBITS, PARITY);

      // no handshaking or other flow control
      serialPort.setFlowControlMode(FLOWCONTROL);


     } catch (UnsupportedCommOperationException e) {
      System.out.println("UnSupported comm operation");
     }

    }

    // *********this method will automaticaly calls when u get data on port and
    // arranges packet from start frame to end frame *************//
    public void serialEvent(SerialPortEvent event) {

//   switch (event.getEventType()) {
//
//   case SerialPortEvent.DATA_AVAILABLE:

     if(event.getEventType()==SerialPortEvent.DATA_AVAILABLE){

       //dataAvailabel = inputStream.available();

       // READING DATA CHARECTER BY CHARECTER

       while (newData != -1) {
        try {
         newData = inputStream.read();
         if (newData == -1) {
          break;
         }
         if (Constants.SF == (char) newData) {
          index = 0;
          // System.out.println("start frame");
         }
         tempIntArray[index] = newData;

         if (Constants.EF == (char) newData) {
          selectToDispalyAndWrite(tempIntArray);
          // disp(tempIntArray);

         }
         index++;

        } catch (IOException ex) {
         System.err.println(ex);
         // return;
        }
       }
       // ///////////////// completes
     }




    }

    // DISPLYS PACKET TO TEXT AREA AND CREATES .PSI FILE
    public void selectToDispalyAndWrite(int[] readBufferArray) {

     if (getOnlineStartwindow().getDump().isSelected()) {
      packetFilename = Integer.toString(readBufferArray[1])
        + Integer.toString(readBufferArray[2])
        + Integer.toString(readBufferArray[3]);


      try {
       if (getOnlineStartwindow().getFileTypeSelection() == "text") {

        displayAndWriteToTextFile(readBufferArray);

       } else {
        displayAndWriteToExcelFile(readBufferArray);
       }
      } catch (IOException e) {
       e.printStackTrace();
      }
     } else {
      printToTextArea(readBufferArray);
     }
    }

    public void printToTextArea(int[] readBufferArray) {
     int i = 0;
     int portname = 0;
     Float portval = 0.0f;


     int len = 0;
     i = 0;
    writeloop:  while (len != readBufferArray.length) {
      // while ((char) readBufferArray[i] != Constants.EF) {
      if ((char) readBufferArray[i] == Constants.SF) {

       // WRITES DASH LINE TO TEXT AREA
       getOnlineStartwindow()
         .getTextArea()
         .append(
           "\r\n\r\n-----------------------------------------------------------------------\r\n");

       getOnlineStartwindow().getTextArea().append(
         "Time :" + readBufferArray[i + 4] + " Min "
           + readBufferArray[i + 5] + " Sec.");
       getOnlineStartwindow()
         .getTextArea()
         .append(
           "\r\n-----------------------------------------------------------------------\r\n");



      }
      if ((char) readBufferArray[i] == Constants.EF) {
       for (Iterator<Integer> iterator = channelMap.keySet()
         .iterator(); iterator.hasNext();) {

        int key = iterator.next();
        Float value = channelMap.get(key);

        getOnlineStartwindow().getTextArea().append(
          "Port_" + key + "           " + value + "\r\n");

       }
       channelMap.clear();
       break writeloop;
      }
      i++;
     }

    }

    public void displayAndWriteToTextFile(int[] readBufferArray)
      throws IOException {
     int i = 0;
     int portname = 0;
     Float portval = 0.0f;

     if (!(filename.equalsIgnoreCase(packetFilename))) {
      filename = packetFilename;
      if (buffOut != null && fileWriter != null) {
       drawLine('*');
       buffOut.close();
       fileWriter.close();

      }

      // GET CURRENT DATE
      Date date = new Date();
      file = new File(outFolder + "\\" + SDF.format(date) + "-"
        + packetFilename + ".txt");

      if (!file.exists()) {
       fileWriter = new FileWriter(file, true);
       buffOut = new BufferedWriter(fileWriter);

       drawLine('*');

       drawLine('*');
      } else {
       fileWriter = new FileWriter(file, true);
       buffOut = new BufferedWriter(fileWriter);
      }

     }

     // LOOP TO DISPLY ALL PORT NAME AND PRESSURE VALUES
     int len = 0;
     i = 0;
     writeloop: while (len != readBufferArray.length) {
      // while ((char) readBufferArray[i] != Constants.EF) {
      if ((char) readBufferArray[i] == Constants.SF) {

       // WRITES DASH LINE TO TEXT AREA
       getOnlineStartwindow()
         .getTextArea()
         .append(
           "\r\n\r\n-----------------------------------------------------------------------\r\n");

       getOnlineStartwindow().getTextArea().append(
         "Time :" + readBufferArray[i + 4] + " Min "
           + readBufferArray[i + 5] + " Sec.");
       getOnlineStartwindow()
         .getTextArea()
         .append(
           "\r\n-----------------------------------------------------------------------\r\n");

       drawLine('-');
       buffOut.write("TIME: " + readBufferArray[i + 4] + " Min "
         + readBufferArray[i + 5] + " Sec." + "\r\n\r\n");

      }
      if ((char) readBufferArray[i] == Constants.ST) {

       portname = readBufferArray[i + 1];
       portval = getFloatValue(i);
       channelMap.put(portname, portval);

      }
      if ((char) readBufferArray[i] == Constants.EF) {
       for (Iterator<Integer> iterator = channelMap.keySet()
         .iterator(); iterator.hasNext();) {

        int key = iterator.next();
        Float value = channelMap.get(key);

        getOnlineStartwindow().getTextArea().append(
          "Port_" + key + "           " + value + "\r\n");



       }
       channelMap.clear();
       break writeloop;
      }
      i++;
     }

    }
}

Thanks in advance

A: 

I was under the impression that Java does not support serial port for Windows, it only does it for Solaris or Linux. your class should implement the Runnable Interface. and create a thread that reads from the serial port in its run method. The Main thread could do the writing part to the TextArea. You may need to do some synchronization between the Main Thread and the Runnable so that writing to the TextArea/File only takes place after appropriate data has been read from the port.

Kevin Boyd
+1  A: 

Here an approach from a design standpoint.

  1. Create a class type for the data. This will be a container (inherit the appropriate queue). And inside of this class as you set and get the data make sure you lock.
  2. Create a new thread in main to start the serial port and read the messages. Pass the thread one object (your list class object). The serial port will chuck data into this list. This will be sets in the object.
  3. You main thread (the window) will have a timer that fires and reads the data from queue. You may have to play with the timer some. You don't want it firing too often and eating all your processing time in the main window. However if it is too slow you may not be updating enough and getting messages out of the queue when they are available. This timer should get all of the data out the queue and display it.

The queue and the lock are the important part here. The queue will keep messages in order. The lock will make sure you don't try to write new data to your queue while you are in the middle of reading data.

Maestro1024