Communicating via BLE

This application note requires a ZentriOS-S product supporting the Zentri Streaming Service feature.

See BLE Services for a general description of the procedures required to connect BLE devices and communicate between a Central and a Peripheral.

This application note describes the platform-specific implementation of the procedural steps.


iOS

Code examples are provided below in Objective C, used in Apple iOS BLE development.

Interacting with a ZentriOS-S Device

The ZentriOS-S device acts as a Peripheral, and the BLE mobile device acts as a Central.

In the Objective C code examples below, the following definitions and declarations are assumed:

//ZentriOS BLE
#define SERVICE_TRUCONNECT_UUID                        @"175f8f23-a570-49bd-9627-815a6a27de2a"
#define CHARACTERISTIC_TRUCONNECT_PERIPHERAL_RX_UUID   @"1cce1ea8-bd34-4813-a00a-c76e028fadcb"
#define CHARACTERISTIC_TRUCONNECT_PERIPHERAL_TX_UUID   @"cacc07ff-ffff-4c48-8fae-a9ef71b75e26"
#define CHARACTERISTIC_TRUCONNECT_MODE_UUID            @"20b9794f-da1a-4d14-8014-a0fb9cefb2f7"
#define STREAM_MODE          1
#define LOCAL_COMMAND_MODE   2
#define REMOTE_COMMAND_MODE  3

CBCharacteristic *rxChar;   // corresponds to Rx characteristic
CBCharacteristic *txChar;   // corresponds to Tx characteristic
CBCharacteristic *modeChar; // corresponds to Mode characteristic

Scanning for a ZentriOS-S Device

Example of scanning for a ZentriOS-S device:

[manager scanForPeripheralsWithServices:@[[CBUUID UUIDWithString:SERVICE_TRUCONNECT_UUID]] options:nil ];

Accessing and Subscribing to Characteristics of the Zentri Streaming Service

See BLE Services, Accessing and Subscribing to Characteristics of the Zentri Streaming Service.

The code below loops through the peripheral services, and if is the Zentri Streaming Service, it sets local variables to point to the corresponding characteristics and subscribes to the appropriate characteristics by registering for notification when their values change. The callback function for all changed value notifications is didUpdateValueForCharacteristic.

- (void)peripheral:(CBPeripheral *)aPeripheral \
  didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error

{
    if ([characteristic.UUID
        isEqual:[CBUUID UUIDWithString:CHARACTERISTIC_TRUCONNECT_PERIPHERAL_TX_UUID]])
    {
       NSString *response = [[NSString alloc]
            initWithBytes:[characteristic.value bytes]
            length:characteristic.value.length
            encoding:NSUTF8StringEncoding];
    }
    else if ([characteristic.UUID
        isEqual:[CBUUID UUIDWithString:CHARACTERISTIC_TRUCONNECT_MODE_UUID]])
    {
       NSString *mode = [[NSString alloc]
            initWithBytes:[characteristic.value bytes]
            length:characteristic.value.length
            encoding:NSUTF8StringEncoding];
    }
}


for (CBService *service in peripheral.services)
{
    if([service.UUID isEqual:[CBUUID UUIDWithString:SERVICE_TRUCONNECT_UUID]])
    {
        for (CBCharacteristic *characteristic in service.characteristics)
        {
            if ([characteristic.UUID
                isEqual:[CBUUID UUIDWithString:CHARACTERISTIC_TRUCONNECT_PERIPHERAL_RX_UUID]])
            {
               rxChar = characteristic;
            }
            else if ([characteristic.UUID
                isEqual:[CBUUID UUIDWithString:CHARACTERISTIC_TRUCONNECT_PERIPHERAL_TX_UUID]])
            {
               txChar = characteristic;
               [peripheral setNotifyValue:YES forCharacteristic:characteristic]; // subscribe
            }
            else if ([characteristic.UUID
                isEqual:[CBUUID UUIDWithString:CHARACTERISTIC_TRUCONNECT_MODE_UUID]])
            {
               modeChar = characteristic;
               [peripheral setNotifyValue:YES forCharacteristic:characteristic]; // subscribe
            }
        }
    }
}

Reading from a ZentriOS-S Device Serial Interface

If you subscribe to the Tx characteristic, as shown in the subscription example above, the callback sets the value of the variable txChar to the characteristic value.

See BLE Services, Reading from a ZentriOS-S Device Serial Interface.

Writing to a ZentriOS-S Device Serial Interface

See BLE Services, Writing to a ZentriOS-S Device Serial Interface.

To write to the device serial interface, write to the Rx characteristic:

[peripheral writeValue:[stringToWriteToDevice dataUsingEncoding:NSUTF8StringEncoding]
                            forCharacteristic:rxChar
                            type:CBCharacteristicWriteWithResponse];

Switching to Remote Command Mode or Stream Mode

See BLE Services, Switching to Remote Command Mode or Stream Mode.

Switch the mode via BLE by writing to the Mode characteristic.

The following code demonstrates switching to REMOTE_COMMAND_MODE.

new_mode = REMOTE_COMMAND_MODE;
[peripheral writeValue:[NSData dataWithBytes:&new_mode length:1]
     forCharacteristic:modeChar type:CBCharacteristicWriteWithResponse];

The following code demonstrates switching to STREAM_MODE.

new_mode = STREAM_MODE;
[peripheral writeValue:[NSData dataWithBytes:&new_mode length:1]
     forCharacteristic:modeChar type:CBCharacteristicWriteWithResponse];

Check that the mode was changed successfully by reading back the modeChar characteristic's value:

{
    NSString *modeRead = [[NSString alloc] initWithBytes:[modeChar.value bytes]
       length:modeChar.value.length encoding:NSUTF8StringEncoding];
    if *modeRead != new_mode
    {
        //...error handling...
    }
}

Sending a ZentriOS-S Command

First switch to REMOTE_COMMAND_MODE as described above.

Then, write the command to the ZentriOS Streaming Service Rx characteristic. See Writing to a ZentriOS-S Device Serial Interface above.

Up to 20 bytes can be written to Rx in a single write. Repeated writes are required for longer strings.

Read the response back as described in Reading from a ZentriOS-S Device Serial Interface.

All commands must be terminated by CR-LF (\r\n), adding two bytes to the length.

It may be more convenient to read responses to ZentriOS-S commands if echo is turned off and response headers are turned on.

The code below shows how to create the command string to turn echo off:

NSString *commandEchoOff = @"set sy c e 0\r\n";

The code below shows how to create the command string to turn headers on:

NSString *commandResponseHeadersOn = @"set sy c h 1\r\n";

See Serial Interface for details of response format.