1

我最近收到了一个用于蓝牙转串口的 BLE 设备。它使用 TruConnect,我正试图让它与我的串行设备通信。串行设备通过串行电缆接收通信,并回显发送给它的任何内容以及发送的命令的任何结果。

现在,我只是尝试向 BLE 设备发送 TruConnect 命令,以检查 BLE 设备设置的当前波特率。

我根据我发现的这个 TruConnect 指南编写了一些代码: https ://truconnect.ack.me/1.5/apps/communicating_via_ble#reading_from_a_truconnect_device_serial_interface 。

问题似乎是,每当我尝试从 tx 特征中读取任何应该有数据的东西时,数据都不正确。

设置 CBPeripheral 事件:

private void setupPerif(CBPeripheral perf)
{
    selectedPeripheral = perf;

    selectedPeripheral.UpdatedCharacterteristicValue += (sender, e) =>
    {
        var c = e.Characteristic;
        if (c != null)
        {
            var uuid = c.UUID.ToString(true).ToLower();
            if (uuid == UUID_RX)
            {
                //
            }
            else if (uuid == UUID_TX)
            {
                // expecting bytes to contain valid response data
                // it almost always contains twenty 0s.
                byte[] bytes = c.Value.Where(i => i != 13).ToArray();
                var invalidBytes = c.Value.Where(i => i > 127).ToArray();
                var nonZeros = c.Value.Where(i => i != 0).ToArray();
                if (nonZeros.Length < 1)
                {
                    return;
                }
                else
                {
                    foreach (byte b in bytes)
                        handler.handleByteReceived((char)b);
                }
            }
            else if (uuid == UUID_MODE)
            {
                //
            }
        }
    };

    selectedPeripheral.DiscoveredService += (sender, e) =>
    {
        var services = selectedPeripheral.Services;
        if (services != null)
        {
            foreach (CBService service in services)
            {
                if (service.UUID.ToString(true).ToLower() == UUID_TRUCONNECT)
                {
                    truConnect = service;
                    selectedPeripheral.DiscoverCharacteristics(truConnect);
                }
            }
        }
    };

    selectedPeripheral.DiscoveredCharacteristic += (sender, e) =>
    {
        if (truConnect != null && truConnect.Characteristics != null)
        {
            foreach (CBCharacteristic c in truConnect.Characteristics)
            {
                var uuidString = c.UUID.ToString(true).ToLower();
                if (uuidString == UUID_RX)
                {
                    rx = c;

                }
                else if (uuidString == UUID_TX)
                {
                    tx = c;
                }
                else if (uuidString == UUID_MODE)
                {
                    mode = c;
                    // set to stream mode
                    selectedPeripheral.WriteValue(NSData.FromArray(new byte[] { MODE_COMMAND }), mode, CBCharacteristicWriteType.WithResponse);
                }
            }
        }
    };
    selectedPeripheral.WroteCharacteristicValue += (sender, e) =>
    {
        // if UUID is for RX, we just wrote to RX. Drill down to
        // TX characteristic and read it. This will trigger
        // the UpdatedCharacteristicValue event.
        string uuid = e.Characteristic.UUID.ToString(true).ToLower();
        if (uuid == UUID_RX)
        {
            var services = selectedPeripheral.Services;
            if (services != null)
            {
                foreach (CBService s in services)
                {
                    if (s.UUID.ToString(true).ToLower() == UUID_TRUCONNECT)
                    {
                        var charachteristics = s.Characteristics;
                        if (charachteristics != null && charachteristics.Length > 0)
                        {
                            foreach (CBCharacteristic c in charachteristics)
                            {
                                if (c.UUID.ToString(true).ToLower() == UUID_TX)
                                {
                                    Timer t = new Timer(new TimerCallback(delegate(object o)
                                    {
                                        selectedPeripheral.ReadValue(c);
                                    }), null, TimeSpan.FromMilliseconds(100), TimeSpan.FromMilliseconds(-1));
                                }
                            }
                        }
                    }
                }
            }
        }
    };
    manager.ConnectPeripheral(selectedPeripheral);
}

写入 rx。这应该用于实际发送命令。

public void sendCommand(string command)
{
    command += endString + "\n";
    if (rx != null)
    {
        NSData d = NSData.FromString(command);

        foreach (CBService s in selectedPeripheral.Services)
        {
            if (s.UUID.ToString(true).ToLower() == UUID_TRUCONNECT)
                foreach (CBCharacteristic c in s.Characteristics)
                {
                    if (c.UUID.ToString(true).ToLower() == UUID_RX)
                        selectedPeripheral.WriteValue(NSData.FromString(command), c, CBCharacteristicWriteType.WithResponse);
                }
        }
    }
}

所以我的问题是,为什么在调用事件时我没有得到预期的数据CBPeripheral.UpdatedCharacteristicValue?偶尔我会得到预期的数据,但这种情况非常罕见,而且我似乎找不到任何合乎逻辑的原因或模式来解释为什么会发生这种情况。

4

1 回答 1

0

啊哈!我想到了!

问题是我需要为适当的特征设置通知值。之后,我不需要打电话了CBPeripheral.ReadValue(CBCharacteristic)

    selectedPeripheral.DiscoveredCharacteristic += (sender, e) =>
    {
        if (truConnect != null && truConnect.Characteristics != null)
        {
            foreach (CBCharacteristic c in truConnect.Characteristics)
            {
                var uuidString = c.UUID.ToString(true).ToLower();
                if (uuidString == UUID_RX)
                {
                    rx = c;
                }
                else if (uuidString == UUID_TX)
                {
                    tx = c;
                    // set the notify value to true and poof!
                    // now CBPeripheral.UpdatedCharacteristicValue
                    // event will be triggered at the appropriate time.
                    selectedPeripheral.SetNotifyValue(true, tx);
                }
                else if (uuidString == UUID_MODE)
                {
                    mode = c;
                    // set to remote command mode
                    selectedPeripheral.WriteValue(NSData.FromArray(new byte[] { MODE_COMMAND }), mode, CBCharacteristicWriteType.WithResponse);
                }
            }
        }
    };
于 2015-05-26T21:25:09.287 回答