通过Rumble从Bluetooth 5 LE DevBoard读取串行数据流

时间:2019-06-12 14:36:23

标签: rust bluetooth-lowenergy

我正在尝试读取来自蓝牙低功耗开发板的串行数据流。固件注册为UART仿真服务(自定义UUID),并通过Receive_Characteristic(自定义UUID)发送数据。正在发送的串行数据只是一个递增的数字。

使用rumble,我可以与设备建立连接,并读取内容,但不能读取流。以下是一个最小的工作代码示例:

    let manager = Manager::new().unwrap();

    let mut adapter = manager
        .adapters()
        .expect("could not list adapters")
        .into_iter()
        .find(|a| a.name == self.adapter_name)
        .expect("could not find adapter by name");

    println!("power cycle adapter");
    adapter = manager.down(&adapter).unwrap();
    adapter = manager.up(&adapter).unwrap();
    println!("connect adapter");

    let central = adapter.connect().unwrap();
    central.start_scan().unwrap();
    println!(
        "find desired {:?} peripheral...",
        &self.device_name
    );

    // keep scanning for 10 s
    std::thread::sleep(std::time::Duration::from_secs(1));
    central.stop_scan().unwrap();

    let peripherals = central.peripherals();



    let mdevice = central
        .peripherals()
        .into_iter()
        .find(|perf| {
            perf.properties()
                .local_name
                .iter()
                .any(|name| name.contains(&self.device_name))
        })
        .expect("could not find peripheral by name");

    std::thread::sleep(std::time::Duration::from_secs(1));

    match mdevice.connect() {
        Ok(d) => {
            println!("mdevice connected");
            d
        }
        Err(err) => {
            eprintln!("error connecting to mdevice: {:?}", err);
            panic!()
        }
    };
    std::thread::sleep(std::time::Duration::from_secs(1));
    println!("discovering characteristics");

    for ch in mdevice.discover_characteristics().unwrap().into_iter() {
        println!("found characteristic: {:?}", ch);
    }
    std::thread::sleep(std::time::Duration::from_secs(1));
    println!("get desired characteristic");
    let receive_characteristic = mdevice
        .discover_characteristics()
        .unwrap()
        .into_iter()
        .find(|c| {
            RECEIVE_CHARACTERISTIC == c.uuid
        })
        .expect("could not find given characteristic");


    // this is some testing code to print out received data
    let (tx, rx) = std::sync::mpsc::channel();

    std::thread::spawn(move || loop {
        let data = match mdevice.read(&receive_characteristic) {
            Ok(d) => d,
            Err(err) => { println!("received an error {:?}", err); 
                          Vec::new()}
        };
        println!("send : {:02?}", data);
        match tx.send(data) {
            Ok(d) => d,
            Err(e) => println!("error {:?}", e)
        };
    });    

    loop {
        let dd = rx.recv();
        println!("received : {:02?}", dd.unwrap());
    }

    Ok(())

使用隆隆声,我可以连接到设备,但获取流很奇怪。我在vec中总是得到相同的数字,但有时会得到一个在增量范围内的数字。读取串行流是否正确完成?

EDIT :我目前正在使用nRF52840-DK开发板。固件发出从0到255的递增数字,然后重复该序列。

1 个答案:

答案 0 :(得分:0)

解决了。

主要问题是,我不完全了解GATT配置文件以及蓝牙LE协议。该resource对这个主题进行了很好的介绍。

解决方案是在设备连接后预订数据(事件)更新,并注册事件处理程序,该处理程序对传入的数据做出反应。就这么简单。

// ... same code as before, but only the relevant pieces are shown.
mdevice.connect().expect("Could not connect to device");
std::thread::sleep(std::time::Duration::from_secs(1));

let chars = mdevice.discover_characteristics()
.expect("Discovering characteristics failed");

std::thread::sleep(std::time::Duration::from_secs(1));

let receive_characteristic = chars.clone().into_iter()
.find(|c| 
{
                // The constant is just a fixed array
                RECEIVE_CHARACTERISTIC == c.uuid
}).expect("Could not find given characteristic");

// subscribe to the event
mdevice.subscribe(&receive_characteristic)

mdevice.on_notification(Box::from(move |v : rumble::api::ValueNotification| 
{
// do something with the received data
}));