阴鸦 2018-11-22 01:53 采纳率: 33.3%
浏览 694
已采纳

串口和串口轉usb的區別

圖一:
知道串口轉usb

圖二:
這是串口的

提問:圖一圖二可不可以都用下面的代碼獲取數據:(圖二可以用下面的代碼獲取數據,但是圖一不知道行不行,請各位大佬路過看看)

package com.lyf.test2;

import java.awt.Button;
import java.awt.Color;
import java.awt.Font;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Label;
import java.awt.Toolkit;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.JOptionPane;

import com.lyf.test2.SerialTool;

import gnu.io.SerialPort;
import gnu.io.SerialPortEvent;
import gnu.io.SerialPortEventListener;
import serialException.ExceptionWriter;
import serialException.NoSuchPort;
import serialException.NotASerialPort;
import serialException.PortInUse;
import serialException.ReadDataFromSerialPortFailure;
import serialException.SendDataToSerialPortFailure;
import serialException.SerialPortInputStreamCloseFailure;
import serialException.SerialPortOutputStreamCloseFailure;
import serialException.SerialPortParameterFailure;
import serialException.TooManyListeners;

/**
 * 主程序
 * @author zhong
 *
 */
public class Client extends Frame{

    private static final long serialVersionUID = 1L;

    /**
     * 程序界面宽度
     */
    public static final int WIDTH = 800;

    /**
     * 程序界面高度
     */
    public static final int HEIGHT = 620;

    /**
     * 程序界面出现位置(横坐标)
     */
    public static final int LOC_X = 200;

    /**
     * 程序界面出现位置(纵坐标)
     */
    public static final int LOC_Y = 70;

    private static SerialPort serialPort = null;    //保存串口对象

    private Font font = new Font("微软雅黑", Font.BOLD, 25);//文本框字體

    private Label weight = new Label("暫無數據", Label.CENTER); //重量

    private Button saveButton = new Button("保存");//设置button按钮

    Image offScreen = null; //用于双缓冲

    //设置window的icon(这里我自定义了一下Windows窗口的icon图标,因为实在觉得哪个小咖啡图标不好看 = =)
    Toolkit toolKit = getToolkit();//返回此窗体的工具包
    Image icon = toolKit.getImage(Client.class.getResource("computer.png"));//獲取當前類所在的包下面的圖片

    /**
     * 主方法
     * @param args  
     * @throws SerialPortOutputStreamCloseFailure 
     * @throws SendDataToSerialPortFailure 
     * @throws PortInUse 
     * @throws NoSuchPort 
     * @throws NotASerialPort 
     * @throws SerialPortParameterFailure 
     */
    public static void main(String[] args) throws SendDataToSerialPortFailure, SerialPortOutputStreamCloseFailure, SerialPortParameterFailure, NotASerialPort, NoSuchPort, PortInUse {
        new Client().launchFrame(); 
    }

    /**
     * 主菜单窗口显示;
     * 添加Label、按钮、下拉条及相关事件监听;
     */
    public void launchFrame() {
        this.setBounds(LOC_X, LOC_Y, WIDTH, HEIGHT);
        this.setTitle("CDIO工程项目");
        this.setIconImage(icon);
        this.setBackground(Color.white);
        this.setLayout(null);

        //改變按鈕的事件监听
        this.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent arg0) {
                if (serialPort != null) {
                    //程序退出时关闭串口释放资源
                    SerialTool.closePort(serialPort);
                }
                System.exit(0);
            }
        });

        //设置文本框位置、背景颜色、是否粗体、字体颜色
        weight.setBounds(140, 103, 225, 50);
        weight.setBackground(Color.black);
        weight.setFont(font);
        weight.setForeground(Color.white);
        add(weight);

        //添加保存按钮
        saveButton.setBounds(250, 490, 300, 50);
        saveButton.setBackground(Color.lightGray);
        saveButton.setFont(new Font("微软雅黑", Font.BOLD, 20));
        saveButton.setForeground(Color.darkGray);
        add(saveButton);

        //添加打开串口按钮的事件监听
        try {
            //指定端口名及波特率的串口对象
            serialPort = SerialTool.openPort("COM1", 4800);

            //在该串口对象上添加监听器
            SerialTool.addListener(serialPort, new SerialListener());
        } catch (SerialPortParameterFailure | NotASerialPort | NoSuchPort | PortInUse | TooManyListeners e1) {
            //发生错误时使用一个Dialog提示具体的错误信息
            JOptionPane.showMessageDialog(null, e1, "错误", JOptionPane.INFORMATION_MESSAGE);
        }

        this.setResizable(false);//设置此框架是否可由用户调整大小。
        this.setVisible(true);  //显示窗口

        new Thread(new RepaintThread()).start();    //启动重画线程
    }

    /**
     * 画出主界面组件元素
     * 设置button的字体颜色、设置字体样式  是否粗体  字体大小、文本、位置
     */
    public void paint(Graphics g) {
        g.setColor(Color.black);
        g.setFont(new Font("微软雅黑", Font.BOLD, 25));
        g.drawString(" 重量: ", 45, 130);
    }

    /**
     * 双缓冲方式重画界面各元素组件
     */
    public void update(Graphics g) {
        if (offScreen == null)  offScreen = this.createImage(WIDTH, HEIGHT);
        Graphics gOffScreen = offScreen.getGraphics();
        Color c = gOffScreen.getColor();
        gOffScreen.setColor(Color.white);
        gOffScreen.fillRect(0, 0, WIDTH, HEIGHT);   //重画背景画布
        this.paint(gOffScreen); //重画界面元素
        gOffScreen.setColor(c);
        g.drawImage(offScreen, 0, 0, null); //将新画好的画布“贴”在原画布上
    }

    /**
     * 以内部类形式创建一个串口监听类
     * @author zhong
     *
     */
    private class SerialListener implements SerialPortEventListener {
        /**
         * 处理监控到的串口事件
         */
        public void serialEvent(SerialPortEvent serialPortEvent) {
            try {
                // 等待1秒钟让串口把数据全部接收后在处理
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            switch (serialPortEvent.getEventType()) {
                case SerialPortEvent.BI: // 10 通讯中断
                    JOptionPane.showMessageDialog(null, "与串口设备通讯中断", "错误", JOptionPane.INFORMATION_MESSAGE);
                    break;
                case SerialPortEvent.OE: // 7 溢位(溢出)错误

                case SerialPortEvent.FE: // 9 帧错误

                case SerialPortEvent.PE: // 8 奇偶校验错误

                case SerialPortEvent.CD: // 6 载波检测

                case SerialPortEvent.CTS: // 3 清除待发送数据

                case SerialPortEvent.DSR: // 4 待发送数据准备好了

                case SerialPortEvent.RI: // 5 振铃指示

                case SerialPortEvent.OUTPUT_BUFFER_EMPTY: // 2 输出缓冲区已清空
                    break;

                case SerialPortEvent.DATA_AVAILABLE: // 1 串口存在可用数据
                    byte[] data = null;
                    try {

                        if (serialPort == null) {//判断串口对象是否为空
                            JOptionPane.showMessageDialog(null, "串口对象为空!监听失败!", "错误", JOptionPane.INFORMATION_MESSAGE);
                        }else {
                            data = SerialTool.readFromPort(serialPort); //读取数据,存入字节数组
                            //System.out.println(new String(data));
                            //自定义解析过程
                            if (data != null && data.length > 1) {  //检查数据是否读取正确
                                try {
                                    weight.setText(new String(data) + " g");
                                } catch (ArrayIndexOutOfBoundsException e) {
                                    JOptionPane.showMessageDialog(null, "数据解析过程出错,更新界面数据失败!请检查设备或程序!", "错误", JOptionPane.INFORMATION_MESSAGE);
                                    System.exit(0);
                                }
                            }else {
                                JOptionPane.showMessageDialog(null, "读取数据过程中未获取到有效数据!请检查设备或程序!", "错误", JOptionPane.INFORMATION_MESSAGE);
                                System.exit(0);
                            }
                        }   
                    } catch (ReadDataFromSerialPortFailure | SerialPortInputStreamCloseFailure e) {
                        JOptionPane.showMessageDialog(null, e, "错误", JOptionPane.INFORMATION_MESSAGE);
                        System.exit(0); //发生读取错误时显示错误信息后退出系统
                    }   
                    break;
            }
        }
    }

    /**
     * 重画线程(每隔30毫秒重画一次)
     */
    private class RepaintThread implements Runnable {
        public void run() {
            while(true) {
                //调用重画方法
                repaint();
                try {
                    Thread.sleep(30);
                } catch (InterruptedException e) {
                    String err = ExceptionWriter.getErrorInfoFromException(e);
                    JOptionPane.showMessageDialog(null, err, "错误", JOptionPane.INFORMATION_MESSAGE);
                    System.exit(0);
                }
            }
        }

    }

}

 package com.lyf.test2;

import java.io.IOException;
import java.io.InputStream;
import java.util.TooManyListenersException;

import gnu.io.CommPort;
import gnu.io.CommPortIdentifier;
import gnu.io.NoSuchPortException;
import gnu.io.PortInUseException;
import gnu.io.SerialPort;
import gnu.io.SerialPortEventListener;
import gnu.io.UnsupportedCommOperationException;
import serialException.*;

/**
 * 串口服务类,提供打开、关闭串口,读取、发送串口数据等服务(采用单例设计模式)
 * @author zhong
 *
 */
public class SerialTool {

    private static SerialTool serialTool = null;

    static {
        //在该类被ClassLoader加载时就初始化一个SerialTool对象
        if (serialTool == null) {
            serialTool = new SerialTool();
        }
    }

    //私有化SerialTool类的构造方法,不允许其他类生成SerialTool对象
    private SerialTool() {} 

    /**
     * 获取提供服务的SerialTool对象
     * @return serialTool
     */
    public static SerialTool getSerialTool() {
        if (serialTool == null) {
            serialTool = new SerialTool();
        }
        return serialTool;
    }

    /**
     * 打开串口
     * @param portName 端口名称
     * @param baudrate 波特率
     * @return 串口对象
     * @throws SerialPortParameterFailure 设置串口参数失败
     * @throws NotASerialPort 端口指向设备不是串口类型
     * @throws NoSuchPort 没有该端口对应的串口设备
     * @throws PortInUse 端口已被占用
     */
    public static final SerialPort openPort(String portName, int baudrate) throws SerialPortParameterFailure, NotASerialPort, NoSuchPort, PortInUse {

        try {
            //通过端口名识别端口
            CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier(portName);

            //打开端口,并给端口名字和一个timeout(打开操作的超时时间)
            CommPort commPort = portIdentifier.open(portName, 2000);

            //判断是不是串口
            if (commPort instanceof SerialPort) {

                SerialPort serialPort = (SerialPort) commPort;

                try {                       
                    //设置一下串口的波特率等参数
                    serialPort.setSerialPortParams(baudrate, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);                              
                } catch (UnsupportedCommOperationException e) {  
                    throw new SerialPortParameterFailure();
                }

                //System.out.println("Open " + portName + " sucessfully !");
                return serialPort;

            } else {
                //不是串口
                throw new NotASerialPort();
            }
        } catch (NoSuchPortException e1) {
          throw new NoSuchPort();
        } catch (PortInUseException e2) {
            throw new PortInUse();
        }
    }

    /**
     * 关闭串口
     * @param serialport 待关闭的串口对象
     */
    public static void closePort(SerialPort serialPort) {
        if (serialPort != null) {
            serialPort.close();
            serialPort = null;
        }
    }

    /**
     * 从串口读取数据
     * @param serialPort 当前已建立连接的SerialPort对象
     * @return 读取到的数据
     * @throws ReadDataFromSerialPortFailure 从串口读取数据时出错
     * @throws SerialPortInputStreamCloseFailure 关闭串口对象输入流出错
     */
    public static byte[] readFromPort(SerialPort serialPort) throws ReadDataFromSerialPortFailure, SerialPortInputStreamCloseFailure {

        InputStream in = null;
        byte[] bytes = null;

        try {
            in = serialPort.getInputStream();//取入数据
            int bufflenth = in.available();     //获取buffer里的数据长度

            while (bufflenth != 0) {                             
                bytes = new byte[bufflenth];    //初始化byte数组为buffer中数据的长度
                in.read(bytes);
                bufflenth = in.available();
            } 
        } catch (IOException e) {
            throw new ReadDataFromSerialPortFailure();
        } finally {
            try {
                if (in != null) {
                    in.close();
                    in = null;
                }
            } catch(IOException e) {
                throw new SerialPortInputStreamCloseFailure();
            }
        }

        return bytes;

    }

    /**
     * 添加监听器
     * @param port     串口对象
     * @param listener 串口监听器
     * @throws TooManyListeners 监听类对象过多
     */
    public static void addListener(SerialPort port, SerialPortEventListener listener) throws TooManyListeners {
        try {
            //给串口添加监听器
            port.addEventListener(listener);
            //设置当有数据到达时唤醒监听接收线程
            port.notifyOnDataAvailable(true);
          //设置当通信中断时唤醒中断线程
            port.notifyOnBreakInterrupt(true);

        } catch (TooManyListenersException e) {
            throw new TooManyListeners();
        }
    }
}

  • 写回答

1条回答 默认 最新

  • fool12 2018-11-22 02:19
    关注

    頂一下,Android的没试过,pc端工具这两种没区别,只有usb转串口的驱动装好了就行

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 MATLAB和mosek的求解问题
  • ¥20 修改中兴光猫sn的时候提示失败
  • ¥15 java大作业爬取网页
  • ¥15 怎么获取欧易的btc永续合约和交割合约的5m级的历史数据用来回测套利策略?
  • ¥15 有没有办法利用libusb读取usb设备数据
  • ¥15 为什么openeluer里面按不了python3呢?
  • ¥15 关于#matlab#的问题:训练序列与输入层维度不一样
  • ¥15 关于Ubuntu20.04.3LTS遇到的问题:在安装完CUDA驱动后,电脑会进入卡死的情况,但可以通过键盘按键进入安全重启,但重启完又会进入该情况!
  • ¥15 关于#嵌入式硬件#的问题:树莓派第一天重装配置python和opencv后第二天打开就成这样,瞎捣鼓搞出来文件夹还是没把原来的界面调回来
  • ¥20 Arduino 循迹小车程序电路出错故障求解