java - 解析从 Arduino 上的多个传感器读取的数据

标签 java parsing user-interface serial-port arduino

这是我们为 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
}

最佳答案

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

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

关于java - 解析从 Arduino 上的多个传感器读取的数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15424056/

相关文章:

java - 如何在 Web ui 中更新使用服务帐户 api 上传的 Google Drive 文档?

parsing - 您如何处理 Lex 中的关键字?

java - Gui 显示文本文档 - 如何分割行

java - 为什么 AbstractCollection.toArray() 处理大小更改的情况?

java - "rename"文件项

python - 解析的部分评估

android - 如何为 Android Wear 使用 setOnApplyWindowInsetsListener

C++ Qt 插槽错误

javascript - JSNI - $wnd.location.assign() 未立即触发

javascript - 将函数序列化和反序列化到 JSON 或从 JSON 反序列化