通过蓝牙读取攀藤G5传感器的代码
3 min read

通过蓝牙读取攀藤G5传感器的代码

攀藤G5传感器通过串口访问,通过USB2TTY线连接即可

最简单的代码

#!/usr/bin/python

import serial
import time
import struct

port = serial.Serial("/dev/ttyUSB0", baudrate=9600, timeout=3)

while True:
    chs = port.read(32)
    frame = struct.unpack(">HHHHHHHHHHHHHHHH",chs)
    print("US PM1.0    %d    PM2.5    %d     PM10    %d"%(frame[2],frame[3],frame[4]))
    print("CN PM1.0    %d    PM2.5    %d     PM10    %d"%(frame[5],frame[6],frame[7]))
    print("---------------------------------")

为了通过远程访问,需要把攀藤G5传感器和HC05蓝牙串口进行连接。同时把传感器的使能端和HC05的使能端进行连接,这样只有进行蓝牙连接的时候才启动传感器,避免持续工作从而有效延长使用寿命,并可以降低功耗。

然后在树莓派上接了一个USB蓝牙适配器,用于跟HC05进行通讯。 当然,手机也可以直接跟HC05通讯。

下面是树莓派通过蓝牙适配器连接HC05的脚本,98:D3:31:xx:xx:xx是HC05的地址,使用cron定时执行pm25-statsd.py

蓝牙配对,只需手动执行一次


$ bluetooth-agent 1234  98:D3:31:xx:xx:xx

or

$ sudo bluetoothctl
[bluetooth]# agent on
[bluetooth]# default-agent
[bluetooth]# scan on
[bluetooth]# pair  98:D3:31:xx:xx:xx
[bluetooth]# exit

下面这行,添加到/etc/rc.local


rfcomm bind /dev/rfcomm0 98:D3:31:xx:xx:xx 1

数据读取后发送到Statsd服务器,用于记录。同时增加了容错处理,并且会跳过前面一段数据,以等传感器数据平稳(因蓝牙连接后才会启动传感器)。

pm25-statsd.py

import serial
import time
import struct
from socket import *


while True:
    port = serial.Serial("/dev/rfcomm0", baudrate=9600, timeout=10)
    chs = port.read(32)
    frame = struct.unpack(">HHHHHHHHHHHHHHHH",chs)
    if frame[0] != 0x424d:
        port.close()
        time.sleep(1)
        continue

    skip = 60
    while skip > 0:
        chs = port.read(32)
        skip -= 1

    port.close()

    frame = struct.unpack(">HHHHHHHHHHHHHHHH",chs)


    print(time.ctime())
    print("CN PM1.0    %d    PM2.5    %d     PM10    %d"%(frame[5],frame[6],frame[7]))
    print("----------------------------------------------------")
    s = socket(AF_INET, SOCK_DGRAM)
    s.sendto("home.pm25.indoor:"+str(frame[6])+"|g", ("statsd-server", 8125))
    s.sendto("home.pm10.indoor:"+str(frame[7])+"|g", ("statsd-server", 8125))

 
    break

Android手机连接HC05,需要先配对,然后通过下面的代码连接并创建串口服务即可


BluetoothSocket s;

protected void connect(){
        //BluetoothManager manager = (BluetoothManager) getSystemService(BLUETOOTH_SERVICE);
        //BluetoothAdapter adapter = manager.getAdapter();
        BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
        BluetoothDevice device = adapter.getRemoteDevice("98:D3:31:xx:xx:xx");


        try {
            //s = device.createRfcommSocketToServiceRecord(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"));

            Method m = device.getClass().getMethod("createRfcommSocket",new Class[]{int.class});
            s =(BluetoothSocket) m.invoke(device,1);

            if(s == null)
                throw new IOException();

            new AsyncTask<BluetoothSocket, Integer, Boolean>(

            ) {
                @Override
                protected Boolean doInBackground(BluetoothSocket... s) {

                    try {

                        s[0].connect();

                        InputStream input = s[0].getInputStream();
                        if(input == null){
                             return false;
                        }

                         DataInputStream reader = new DataInputStream(input);

                        while (true){
                            if(reader.readShort() != 0x424d)
                                continue;

                            if(reader.readShort() != 28)
                                throw new RuntimeException("data error");

                            //skip us data
                            reader.skipBytes(6);

                            //skip pm1.0
                            reader.skipBytes(2);

                            int pm25 = (int)reader.readShort();
                            int pm10 = (int)reader.readShort();

                            publishProgress(pm25, pm10);

                            //skip rest data
                            reader.skipBytes(16);
                        }

                    } catch (IOException e) {
                        e.printStackTrace();
                    }

                    return false;
                }

                @Override
                protected void onProgressUpdate(Integer... progress) {
                    updatePm25(progress[0], progress[1]);       //换成你的代码!!!
                }

                @Override
                protected void onPostExecute(Boolean result){
                    if(!result)
                        Toast.makeText(getApplicationContext(), "Connect device fail!", Toast.LENGTH_LONG).show();

                }

            }.execute(s);



        } catch (IOException e) {
            Toast.makeText(this, "read data from device fail!", Toast.LENGTH_LONG).show();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }

    }

手机蓝牙读取

装配完成

最近一年的记录

今年的空气还不错!