1

这是我们为 Java GUI 实现的代码。问题是,由于串行数据是以位读取的,我们似乎无法想出一种方法来分离来自三个不同传感器(三个LM35温度传感器作为占位符)的数据。问题在于 serialevent 类。

import gnu.io.*;
import java.awt.Color;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Scanner;
import java.util.TooManyListenersException;

public class Communicator implements SerialPortEventListener
{
    //Passed from main GUI.
    GUI window = null;

    //For containing the ports that will be found.
    private Enumeration ports = null;
    //map the port names to CommPortIdentifiers
    private HashMap portMap = new HashMap();

    //This is the object that contains the opened port.
    private CommPortIdentifier selectedPortIdentifier = null;
    private SerialPort serialPort = null;

    //Input and output streams for sending and receiving data.
    private InputStream input = null;
    private OutputStream output = null;

    //Just a boolean flag that I use for enabling
    //and disabling buttons depending on whether the program
    //is connected to a serial port or not.
    private boolean bConnected = false;

    //The timeout value for connecting with the port.
    final static int TIMEOUT = 2000;

    //Some ASCII values for for certain things.
    final static int SPACE_ASCII = 32;
    final static int DASH_ASCII = 45;
    final static int NEW_LINE_ASCII = 10;

    //A string for recording what goes on in the program;
    //this string is written to the GUI.
    String logText = "";

    public Communicator(GUI window)
    {
        this.window = window;
    }

    //Search for all the serial ports
    //  Pre: none
    //  Post: adds all the found ports to a combo box on the GUI
    public void searchForPorts()
    {
        ports = CommPortIdentifier.getPortIdentifiers();

        while (ports.hasMoreElements())
        {
            CommPortIdentifier curPort = (CommPortIdentifier)ports.nextElement();

            //Get only serial ports
            if (curPort.getPortType() == CommPortIdentifier.PORT_SERIAL)
            {
                window.cboxPorts.addItem(curPort.getName());
                portMap.put(curPort.getName(), curPort);
            }
        }
    }

    //Connect to the selected port in the combo box
    //  Pre : ports are already found by using the searchForPorts method
    //  Post: the connected communications port is stored in commPort, otherwise,
    //        an exception is generated
    public void connect()
    {
        String selectedPort = (String)window.cboxPorts.getSelectedItem();
        selectedPortIdentifier = (CommPortIdentifier)portMap.get(selectedPort);

        CommPort commPort = null;

        try
        {
            //The method below returns an object of type CommPort
            commPort = selectedPortIdentifier.open("TigerControlPanel", TIMEOUT);
            //The CommPort object can be casted to a SerialPort object
            serialPort = (SerialPort)commPort;

            //For controlling GUI elements
            setConnected(true);

            //Logging
            logText = selectedPort + " opened successfully.";
            window.txtLog.setForeground(Color.black);
            window.txtLog.append(logText + "\n");
            window.txtLog1.setForeground(Color.black);
            window.txtLog1.append(logText + "\n");
            window.txtLog2.setForeground(Color.black);
            window.txtLog2.append(logText + "\n");

            //CODE ON SETTING BAUD RATE, ETC. OMITTED
            //XBEE PAIR IS ASSUMED TO HAVE THE SAME SETTINGS ALREADY

            //Enables the controls on the GUI if a successful connection is made
            window.keybindingController.toggleControls();
        }
        catch (PortInUseException e)
        {
            logText = selectedPort + " is in use. (" + e.toString() + ")";

            window.txtLog.setForeground(Color.RED);
            window.txtLog.append(logText + "\n");
            window.txtLog1.setForeground(Color.RED);
            window.txtLog1.append(logText + "\n");
            window.txtLog2.setForeground(Color.RED);
            window.txtLog2.append(logText + "\n");
        }
        catch (Exception e)
        {
            logText = "Failed to open " + selectedPort + "(" + e.toString() + ")";
            window.txtLog.append(logText + "\n");
            window.txtLog.setForeground(Color.RED);
            window.txtLog1.append(logText + "\n");
            window.txtLog1.setForeground(Color.RED);
            window.txtLog2.append(logText + "\n");
            window.txtLog2.setForeground(Color.RED);
        }
    }

    //Open the input and output streams
    //  pre: an open port
    //  post: initialized intput and output streams for use to communicate data
    public boolean initIOStream()
    {
        //Return value for whather opening the streams is successful or not
        boolean successful = false;

        try {
            input = serialPort.getInputStream();
            output = serialPort.getOutputStream();
            successful = true;
            return successful;
        }
        catch (IOException e) {
            logText = "I/O Streams failed to open. (" + e.toString() + ")";
            window.txtLog.setForeground(Color.red);
            window.txtLog.append(logText + "\n");
            window.txtLog1.setForeground(Color.red);
            window.txtLog1.append(logText + "\n");
            window.txtLog2.setForeground(Color.red);
            window.txtLog2.append(logText + "\n");
            return successful;
        }
    }

    //Starts the event listener that knows whenever data is available to be read
    //  pre: an open serial port
    //  post: an event listener for the serial port that knows when data is recieved
    public void initListener()
    {
        try
        {
            serialPort.addEventListener(this);
            serialPort.notifyOnDataAvailable(true);
        }
        catch (TooManyListenersException e)
        {
            logText = "Too many listeners. (" + e.toString() + ")";
            window.txtLog.setForeground(Color.red);
            window.txtLog.append(logText + "\n");
            window.txtLog1.setForeground(Color.red);
            window.txtLog1.append(logText + "\n");
            window.txtLog2.setForeground(Color.red);
            window.txtLog2.append(logText + "\n");
        }
    }

    //Disconnect the serial port
    //  pre : an open serial port
    //  post: clsoed serial port
    public void disconnect()
    {
        //Close the serial port
        try
        {
            serialPort.removeEventListener();
            serialPort.close();
            input.close();
            output.close();
            setConnected(false);
            window.keybindingController.toggleControls();

            logText = "Disconnected.";
            window.txtLog.setForeground(Color.red);
            window.txtLog.append(logText + "\n");
            window.txtLog1.setForeground(Color.red);
            window.txtLog1.append(logText + "\n");
            window.txtLog2.setForeground(Color.red);
            window.txtLog2.append(logText + "\n");
        }
        catch (Exception e)
        {
            logText = "Failed to close " + serialPort.getName() + "(" + e.toString() + ")";
            window.txtLog.setForeground(Color.red);
            window.txtLog.append(logText + "\n");
            window.txtLog1.setForeground(Color.red);
            window.txtLog1.append(logText + "\n");
            window.txtLog2.setForeground(Color.red);
            window.txtLog2.append(logText + "\n");
        }
    }

    final public boolean getConnected()
    {
        return bConnected;
    }

    public void setConnected(boolean bConnected)
    {
        this.bConnected = bConnected;
    }

    //What happens when data is received
    //  pre : serial event is triggered
    //  post: processing on the data it reads
    public void serialEvent(SerialPortEvent evt) {
        if (evt.getEventType() == SerialPortEvent.DATA_AVAILABLE)
        {
            try
            {
                byte singleData = (byte)input.read();
                //byte[] buffer = new byte[128];

                if (singleData != NEW_LINE_ASCII)
                {
                    logText = new String(new byte[] {singleData});
                    window.txtLog.append(logText);
                }
                else
                {
                    window.txtLog.append("\n");
                }
            }
            catch (Exception e)
            {
                logText = "Failed to read data. (" + e.toString() + ")";
                window.txtLog.setForeground(Color.red);
                window.txtLog.append(logText + "\n");
            }
        }
    }

    //Method that can be called to send data
    //  pre : open serial port
    //  post: data sent to the other device
}
4

1 回答 1

0

如果 Arduino 只是按顺序从每个传感器将温度作为字符串发送回(我假设它是,但您根本没有指定它发送的内容,所以我可能是错的)然后假设您没有禁用串行重置连接,你可以简单地记下温度的顺序——比如第一个温度读数来自传感器 1,第二个来自传感器 2,第三个来自传感器 3,第四个来自传感器 1,依此类推。

但是,为了更清晰、更可靠的方式,我建议修改 Arduino 代码以发回每个读数来自哪个传感器的详细信息,而不仅仅是发回原始位 - 以这种方式更改代码对于 Arduino 来说应该是相对微不足道的端,然后使解析数据 PC 端更容易。

于 2013-04-26T10:47:05.973 回答