【JAVA】通过串口获取BLE蓝牙消息

本文讲述了作者在开发小程序与未联网硬件通信时遇到的问题,需通过串口接收蓝牙消息。作者介绍了使用jSerialComm库进行串口监听的方法,并提到了可能需要调整的参数和注意事项。
摘要由CSDN通过智能技术生成

最近在做一个小程序和硬件连接有关的项目,硬件是一块没有联网的开发板,首先要通过BLE蓝牙发送消息,将wifi账号和密码通过蓝牙发送到板子上,结果这个硬件厂商比较奇葩的是,他们板子的蓝牙消息走的是串口,直接去监听ubuntu系统的蓝牙还监听不到蓝牙消息,这就很奇葩了,问过厂家后才知道他们蓝牙走的是串口,那直接去监听蓝牙肯定监听不到了,没办法,改代码吧,从串口获取蓝牙消息。

比较常用的有两种方法,第一种是使用jSerialComm串口监听方式,第二种是rxtx串口监听方式,第二种官网下载jar包的时候出现404,目前我也还没有找到合适的jar包,有兴趣的可以了解一下,所以这里就只上第一种方法了。

好了,话不多说,上代码

一、maven引入

        <dependency>
            <groupId>com.fazecast</groupId>
            <artifactId>jSerialComm</artifactId>
            <version>2.6.0</version>
        </dependency>

二、代码


import com.fazecast.jSerialComm.SerialPort;
import com.fazecast.jSerialComm.SerialPortDataListener;
import com.fazecast.jSerialComm.SerialPortEvent;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Component;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;



@Component
@Slf4j
public class jSerialCommUtil {



        // 当前串口对象引用
        static SerialPort serialPort;

        // 堵塞队列:用来存放串口发送到服务端的数据
        public BlockingQueue<String> msgQueue = new LinkedBlockingQueue();

        // 线程控制标识
        public static boolean flag = true;





        /**
         * 打开电脑上指定的串口
         *
         * @param portName 端口名称,如 COM1,为 null 时,默认使用电脑中能用的端口中的第一个
         * @param b        波特率(baudrate),如 9600
         * @param d        数据位(datebits),如  8
         * @param s        停止位(stopbits),如  1
         * @param p        校验位 (parity),如 0
         * @return 打开的串口对象,打开失败时,返回 null
         */
        public final SerialPort openSerialPort(String portName, int b, int d, int s, int p) {

            SerialPort[] commPorts = SerialPort.getCommPorts();
            for (SerialPort itemPort : commPorts) {
                System.out.println("板子的串口名称---------"+itemPort.getSystemPortName());
                if (portName.equals(itemPort.getSystemPortName())) {
                    //判断串口是否打开,如果没打开,就打开串口。
                    if (itemPort.isOpen()) {
                        System.out.println("串口 " + portName + "已打开...");
                        return null;
                    }
                    //设置超时
                    itemPort.setComPortTimeouts(SerialPort.TIMEOUT_READ_BLOCKING | SerialPort.TIMEOUT_WRITE_BLOCKING, 1000, 1000);
                    // 第一个参数为波特率,默认9600;
                    // 第二个参数为每一位的大小,默认8,可以输入5到8之间的值;
                    // 第三个参数为停止位大小,只接受内置常量,可以选择(ONE_STOP_BIT, ONE_POINT_FIVE_STOP_BITS, TWO_STOP_BITS);
                    // 第四位为校验位,同样只接受内置常量,可以选择 NO_PARITY, EVEN_PARITY, ODD_PARITY, MARK_PARITY,SPACE_PARITY。
                    itemPort.setComPortParameters(b, d, s, p);
                    //设置串口的控制流,可以设置为disabled,或者CTS, RTS/CTS, DSR, DTR/DSR, Xon, Xoff, Xon/Xoff等
                    //serialPort.setFlowControl(SerialPort.FLOW_CONTROL_DISABLED);
                    boolean isOpen = itemPort.openPort();
                    if (isOpen) {
                     
                        serialPort = itemPort;

                        System.out.println("打开串口 " + portName + " 成功...");
                        try {
                            Thread.sleep(1000);//打开串口后要休眠一段时间才能接收到输入流
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        itemPort.addDataListener(new SerialPortDataListener() {
                            @Override
                            public int getListeningEvents() {
                                return SerialPort.LISTENING_EVENT_DATA_RECEIVED;
                            }

                            @Override
                            public void serialEvent(SerialPortEvent serialPortEvent) {
                                byte[] newData = serialPortEvent.getReceivedData();
                                String weight = new String(newData);
                                if (StringUtils.isNotBlank(weight)) {
                                    msgQueue.add(weight);
                                }

                              System.out.println(String.format("串口%s接收到数据大小:%s,串口数据内容:%s"
                                        , serialPortEvent.getSerialPort().getSystemPortName(), newData.length, new String(newData)));

                        //TODO 这里已经从串口获取到蓝牙消息了,处理你自己的业务逻辑

                            }
                        });

                        return serialPort;
                    } else {

                        System.out.println("打开串口 " + portName + " 失败...");
                    }
                }
            }
            if (serialPort == null) {

                System.out.println("打开串口 " + portName + " 失败...,请检查串口名称是否正确,或是否被占用");
            }
            return null;
        }

}

OK,到此就搞定了,已经可以从串口获取到蓝牙消息。

最后别忘了关闭串口,当然是否关闭串口也要根据自己的业务逻辑来


        /**
         * 关闭串口
         *
         * @param serialPort 要关闭的串口对象
         */
        public Boolean closeSerialPort(SerialPort serialPort) {
            if (serialPort != null) {
                //关闭串口。该函数同样会返回一个boolean值,表明串口是否成功关闭
                return serialPort.closePort();
            }
            return false;
        }

这个方法有个好处就是,不用写个死循环去一直监听,也不用使用webscoket一直去访问,也算是大大减轻了服务器压力。但是得看硬件厂家是不是也和这家一样奇葩,走的是串口

方法到这里就结束了,然后把这个打成jar包,部署到开发板上,通过BLE调试助手app,就可以试着发送蓝牙消息了。

注意:板子中的波特率这个不一定都是9600,这个要咨询一下开发板的硬件厂家,串口名称也需要问一下厂家。数据位,停止位,校验位一般情况下都是固定的,8、1、0写死就行。

  • 7
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
要在安卓中获取BLE蓝牙设备,你需要使用Android提供的BluetoothLeScanner类和BluetoothAdapter类。下面是获取BLE设备的基本步骤: 1. 检查设备是否支持BLE蓝牙 在你的应用程序中,你需要检查设备是否支持BLE蓝牙。你可以使用BluetoothManager类和BluetoothAdapter类来完成此操作。你可以使用以下代码检查设备是否支持BLE: ``` // 初始化BluetoothManager BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE); // 获取BluetoothAdapter BluetoothAdapter bluetoothAdapter = bluetoothManager.getAdapter(); // 检查设备是否支持BLE蓝牙 if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) { Toast.makeText(this, "设备不支持BLE蓝牙", Toast.LENGTH_SHORT).show(); finish(); } ``` 2. 开启蓝牙 在你的应用程序中,你需要确保蓝牙已经开启并且可以被发现。你可以使用以下代码开启蓝牙: ``` // 检查蓝牙是否已经开启,如果没有开启,则开启蓝牙 if (!bluetoothAdapter.isEnabled()) { Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT); } // 延长蓝牙可见性时间 Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE); discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300); startActivity(discoverableIntent); ``` 3. 扫描BLE设备 使用BluetoothLeScanner类扫描BLE设备。你可以使用以下代码扫描BLE设备: ``` // 初始化BluetoothLeScanner BluetoothLeScanner bluetoothLeScanner = bluetoothAdapter.getBluetoothLeScanner(); // 设置扫描回调接口 ScanCallback scanCallback = new ScanCallback() { @Override public void onScanResult(int callbackType, ScanResult result) { BluetoothDevice device = result.getDevice(); // 处理扫描到的设备 } @Override public void onScanFailed(int errorCode) { // 处理扫描失败事件 } }; // 开始扫描BLE设备 ScanFilter scanFilter = new ScanFilter.Builder() .setServiceUuid(ParcelUuid.fromString(YOUR_SERVICE_UUID)) .build(); ScanSettings scanSettings = new ScanSettings.Builder() .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY) .build(); bluetoothLeScanner.startScan(Arrays.asList(scanFilter), scanSettings, scanCallback); ``` 以上是获取BLE设备的基本步骤。在实际开发中,你需要根据实际情况对代码进行修改。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值