iPhone和Arduino之间的BLE编码问题

时间:2015-03-09 03:28:03

标签: arduino bluetooth-lowenergy core-bluetooth

我正在开发基于Arduino的设备,它将通过BLE与iPhone进行通信。该器件基于TI CC2541芯片组。这是spec sheet

我需要能够从iPhone发送消息到设备,也可以从设备发送回iPhone。消息是短ASCII字符串。该设备只会与我的iPhone应用程序进行通信,因此并不需要GATT和CoreBluetooth的所有内容,但对于我正在使用的蓝牙是新手。如果您知道实现简单串行通信的方法,绕过所有CoreBluetooth / GATT脚手架 - 请告诉我!

无论如何,我已经能够将消息从iPhone发送到Arduino。但是消息到了乱码。对于接收的每个字节,低4位与发送的字节的低4位匹配。但高4位有所不同。

有谁知道这里使用的编码?或者你知道如何让它发送我想发送的内容,而不使用这种编码吗?

以下是详细信息。

连接到我的BT设备后,我遍历所有服务,特征和描述符。这是代码:



#pragma mark - CBCentralManagerDelegate

// CBCentralManagerDelegate - This is called with the CBPeripheral class as its main input parameter. This contains most of the information there is to know about a BLE peripheral.


// method called whenever the device state changes.
- (void)centralManagerDidUpdateState:(CBCentralManager *)central
{
    // Determine the state of the peripheral
    if ([central state] == CBCentralManagerStatePoweredOff) {
        NSLog(@"CoreBluetooth BLE hardware is powered off");
    }
    else if ([central state] == CBCentralManagerStatePoweredOn) {
        NSLog(@"CoreBluetooth BLE hardware is powered on and ready");
        
        //  This could pass a list of services, but we will just check all BT devices found, at least for now...
        
        [self.BTManager scanForPeripheralsWithServices:nil options:nil];
    }
    else if ([central state] == CBCentralManagerStateUnauthorized) {
        NSLog(@"CoreBluetooth BLE state is unauthorized");
    }
    else if ([central state] == CBCentralManagerStateUnknown) {
        NSLog(@"CoreBluetooth BLE state is unknown");
    }
    else if ([central state] == CBCentralManagerStateUnsupported) {
        NSLog(@"CoreBluetooth BLE hardware is unsupported on this platform");
    }
}

- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI
{
    NSString *localName = [advertisementData objectForKey:CBAdvertisementDataLocalNameKey];
    if ([localName length] > 0 && [localName isEqualToString: BTName]) {
        
        // Connect to the borg.  Note the RSSI parameter above.  This is the signal strength.  Might come in handy!
        NSLog(@"Found our device %@", localName);
        [self.BTManager stopScan];
        self.thePeripheral = peripheral;
        peripheral.delegate = self;
        [self.BTManager connectPeripheral:peripheral options:nil];
    }
}


// method called whenever you have successfully connected to the BLE peripheral
- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral
{
    peripheral.delegate = self;
    [peripheral discoverServices:nil];
    
    NSString *connected = [NSString stringWithFormat:@"Connected: %@", peripheral.state == CBPeripheralStateConnected ? @"YES" : @"NO"];
    NSLog(@"Connected to peripheral %@?  %@", peripheral.UUID, connected);
}


#pragma mark - CBPeripheralDelegate

// CBPeripheralDelegate - Invoked when you discover the peripheral's available services.
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error
{
    // Enumerate through all services on the connected peripheral.
    for (CBService * service in [peripheral services])
    {
        NSLog(@"Found service %@, %s", service.UUID, (service.isPrimary) ? "is primary" : "is secondary");
        
        // FFE0 is the service we will use to read/write
        if ([[service.UUID UUIDString] isEqualToString:@"FFE0"])
            self.txrxService = service;
        
        // Discover all characteristics for this service.
        [peripheral discoverCharacteristics:nil forService:service];
    }
}

// Invoked when you discover the characteristics of a specified service.
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error
{
    // Enumerate through all services on the connected peripheral.
    for (CBCharacteristic * character in [service characteristics])
    {
        // FFE1 is the characteristic we will use to read/write
        if ([[character.UUID UUIDString] isEqualToString:@"FFE1"])
            self.txrxCharacteristic = character;
        
        NSLog(@"Service %@ has characteristic %@", service.UUID, character.UUID);
        // Discover all descriptors for each characteristic.
        [peripheral discoverDescriptorsForCharacteristic:character];
    }
}

- (void)peripheral:(CBPeripheral *)peripheral didDiscoverDescriptorsForCharacteristic:(CBCharacteristic *)characteristic
error:(NSError *)error
{
    for (CBDescriptor* descriptor in characteristic.descriptors) {
        NSLog(@"Found descriptor %@ for characteristic %@", descriptor.UUID, characteristic.UUID);
    }

}

// Invoked when you retrieve a specified characteristic's value, or when the peripheral device notifies your app that the characteristic's value has changed.
- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
{
}




这是输出:



Found service Device Information, is primary
Found service FFE0, is primary
Service Device Information has characteristic System ID
Service Device Information has characteristic Model Number String
Service Device Information has characteristic Serial Number String
Service Device Information has characteristic Firmware Revision String
Service Device Information has characteristic Hardware Revision String
Service Device Information has characteristic Software Revision String
Service Device Information has characteristic Manufacturer Name String
Service Device Information has characteristic IEEE Regulatory Certification
Service Device Information has characteristic PnP ID
Service FFE0 has characteristic FFE1
Found descriptor Client Characteristic Configuration for characteristic FFE1
Found descriptor Characteristic User Description for characteristic FFE1




(问题 - 请注意我打印UUID,但它们不是UUID,它们是描述性字符串。那是什么?)

有点随意,我选择服务FFE0,特色FFE1来发送我的串行数据。

以下是我用来将所有可打印ASCII字符发送到设备的一些测试代码:



// Test sending a range of ascii values
-(void)BTSendTest: (CBPeripheral*)peripheral forCharacteristic:(CBCharacteristic*)characteristic
{
    NSLog(@"Sending to peripheral: %@ characteristic: %@", peripheral, characteristic.UUID);
    
    for (int asciiCode = 32, i=0; asciiCode < 126; asciiCode++, i++) {
        NSString *string = [NSString stringWithFormat:@"%c", asciiCode];
        
        NSLog(@"%d) sending <%@> 0x%x", i, string, asciiCode);
        
        NSData* data = [string dataUsingEncoding:NSUTF8StringEncoding];
        if(characteristic.properties & CBCharacteristicPropertyWriteWithoutResponse)
            [peripheral writeValue:data forCharacteristic:characteristic type:CBCharacteristicWriteWithoutResponse];
        else
            [peripheral writeValue:data forCharacteristic:characteristic type:CBCharacteristicWriteWithResponse];
    }
}
&#13;
&#13;
&#13;

这是输出:

&#13;
&#13;
Sending to peripheral: <CBPeripheral: 0x156b1e60, identifier = 91DCFDD7-767E-65B7-6A66-48B5C7555CDC, name = TestDevice, state = connected> characteristic: FFE1
0) sending < > 0x20
1) sending <!> 0x21
2) sending <"> 0x22
3) sending <#> 0x23
4) sending <$> 0x24
5) sending <%> 0x25
6) sending <&> 0x26
7) sending <'> 0x27
8) sending <(> 0x28
9) sending <)> 0x29
10) sending <*> 0x2a
11) sending <+> 0x2b
12) sending <,> 0x2c
13) sending <-> 0x2d
14) sending <.> 0x2e
15) sending </> 0x2f
16) sending <0> 0x30
17) sending <1> 0x31
18) sending <2> 0x32
19) sending <3> 0x33
20) sending <4> 0x34
21) sending <5> 0x35
22) sending <6> 0x36
23) sending <7> 0x37
24) sending <8> 0x38
25) sending <9> 0x39
26) sending <:> 0x3a
27) sending <;> 0x3b
28) sending <<> 0x3c
29) sending <=> 0x3d
30) sending <>> 0x3e
31) sending <?> 0x3f
32) sending <@> 0x40
33) sending <A> 0x41
34) sending <B> 0x42
35) sending <C> 0x43
36) sending <D> 0x44
37) sending <E> 0x45
38) sending <F> 0x46
39) sending <G> 0x47
40) sending <H> 0x48
41) sending <I> 0x49
42) sending <J> 0x4a
43) sending <K> 0x4b
44) sending <L> 0x4c
45) sending <M> 0x4d
46) sending <N> 0x4e
47) sending <O> 0x4f
48) sending <P> 0x50
49) sending <Q> 0x51
50) sending <R> 0x52
51) sending <S> 0x53
52) sending <T> 0x54
53) sending <U> 0x55
54) sending <V> 0x56
55) sending <W> 0x57
56) sending <X> 0x58
57) sending <Y> 0x59
58) sending <Z> 0x5a
59) sending <[> 0x5b
60) sending <\> 0x5c
61) sending <]> 0x5d
62) sending <^> 0x5e
63) sending <_> 0x5f
64) sending <`> 0x60
65) sending <a> 0x61
66) sending <b> 0x62
67) sending <c> 0x63
68) sending <d> 0x64
69) sending <e> 0x65
70) sending <f> 0x66
71) sending <g> 0x67
72) sending <h> 0x68
73) sending <i> 0x69
74) sending <j> 0x6a
75) sending <k> 0x6b
76) sending <l> 0x6c
77) sending <m> 0x6d
78) sending <n> 0x6e
79) sending <o> 0x6f
80) sending <p> 0x70
81) sending <q> 0x71
82) sending <r> 0x72
83) sending <s> 0x73
84) sending <t> 0x74
85) sending <u> 0x75
86) sending <v> 0x76
87) sending <w> 0x77
88) sending <x> 0x78
89) sending <y> 0x79
90) sending <z> 0x7a
91) sending <{> 0x7b
92) sending <|> 0x7c
93) sending <}> 0x7d
&#13;
&#13;
&#13;

以下是接收BT消息的Arduino端的代码:

&#13;
&#13;
#include <SoftwareSerial.h>

SoftwareSerial bt(A1, A0); // RX, TX

void setup() {
  // put your setup code here, to run once:

  Serial.begin(9600);
  while (!Serial)
    ;
    
  Serial.println("BTTest");
  
  bt.begin(57600);
  
}

int rcvCount = 0;
void loop() {
  // put your main code here, to run repeatedly:
  if (bt.available()) {
    char _ch;
    while ((_ch = bt.read()) != -1) {
      unsigned char ch = (unsigned char)_ch;
      char str[2];
      str[0] = ch;
      str[1] = '\0';
      Serial.print(rcvCount++);
      Serial.print(") ");
      Serial.print(str);
      Serial.print("\t0x");
      Serial.println((unsigned int)(unsigned char)ch, HEX);
    };
  };
}
&#13;
&#13;
&#13;

这是输出:

&#13;
&#13;
BTTest
0) €	0x80
1) �	0x81
2) ‚	0x82
3) ƒ	0x83
4) „	0x84
5) …	0x85
6) †	0x86
7) §	0xA7
8) ˆ	0x88
9) ©	0xA9
10) ª	0xAA
11) «	0xAB
12) ¬	0xAC
13) ­	0xAD
14) ®	0xAE
15) ¯	0xAF
16) �	0x90
17) ‘	0x91
18) ’	0x92
19) “	0x93
20) ”	0x94
21) µ	0xB5
22) ¶	0xB6
23) ·	0xB7
24) ˜	0x98
25) ¹	0xB9
26) º	0xBA
27) »	0xBB
28) ¼	0xBC
29) ½	0xBD
30) ¾	0xBE
31) ¿	0xBF
32)  	0xA0
33) ¡	0xA1
34) ¢	0xA2
35) ƒ	0x83
36) ¤	0xA4
37) ¥	0xA5
38) †	0x86
39) ‡	0x87
40) ¨	0xA8
41) ©	0xA9
42) Š	0x8A
43) ‹	0x8B
44) Œ	0x8C
45) �	0x8D
46) ®	0xAE
47) �	0x8F
48) °	0xB0
49) ±	0xB1
50) ’	0x92
51) “	0x93
52) ´	0xB4
53) µ	0xB5
54) –	0x96
55) —	0x97
56) ¸	0xB8
57) ™	0x99
58) š	0x9A
59) ›	0x9B
60) œ	0x9C
61) �	0x9D
62) ž	0x9E
63) Ÿ	0x9F
64)  	0xA0
65) ¡	0xA1
66) ¢	0xA2
67) £	0xA3
68) ¤	0xA4
69) ¥	0xA5
70) ¦	0xA6
71) §	0xA7
72) ¨	0xA8
73) ©	0xA9
74) ª	0xAA
75) «	0xAB
76) ¬	0xAC
77) ­	0xAD
78) ®	0xAE
79) ¯	0xAF
80) °	0xB0
81) ±	0xB1
82) ²	0xB2
83) ³	0xB3
84) ´	0xB4
85) µ	0xB5
86) ¶	0xB6
87) ·	0xB7
88) ¸	0xB8
89) ¹	0xB9
90) º	0xBA
91) »	0xBB
92) ¼	0xBC
93) ½	0xBD
&#13;
&#13;
&#13;

所以,......把所有这些放在一起,看起来像十六进制40,60或80(十进制64,96,128)被添加到发送的字节中。但我没有看到一种模式。

有什么想法吗?

1 个答案:

答案 0 :(得分:0)

尝试降低ble通信的波特率。而不是57600使用9600.在19200波特率之后,arduino往往会运行不稳定。