# BeaconPlus iOS Software Development Kit Guide

  • Updating…

This SDK only support devices based on miniBeaconPlus firmware, not supporting products produced by other companies anymore. BeaconSET+ SDK support more feature than BeaconSET SDK. We encountered some issues in the development process, So, please read this document carefully in order to help you get started as soon as possible. At the same time, this document will also inform the notes and issues.

Please read the part of this document which you need, part 1 we will explain the architecture of this SDK, part 2 will help developers to get started, part 3 will explain notes in your developing progress, part 4 you can get error codes and descriptions.

# Design instructions

We divide the communications between SDK and devices into two stages: Scanning stage, Connection stage. For ease of understanding, let's take a look at the related classes and the relationships between them.

MTCentralManager: global manager, check system's bluetooth status, listen status changes, the most important is scan and connect to devices;

MTPeripheral: instance of devices, MTCentralManager will create an MTPeripheral instance while it found a physical device, a device corresponds to an instance. every MTPeripheral instance has a MTFrameHandler property and a MTConnectionHandler property(These two properties are explained below);

MTFrameHandler: Advertisement frame analysis, it can analyze all frames from advertisement data of a device. in other words, it's the core of the scanning stage;

MTConnectionHandler: connection Operator. this class control all the operation of device in connection stage.

MTSensorHandler: sensor Operator, this class control all the sensor operation of device in connection stage.

**MinewFrame:**data frame, every minewframe(or subclass) instance corresponds to a data frame, usually created by "MTFrameHandler", if a device advertises mutiple data frames(such as iBeacon, UID, URL) "MTFrameHandler" will create multiple corresponding MinewFrame instances.

MTOTAManager: OTA, use this class for update device's firmware only.

# Overall structure

BeaconSET+

in this stage, MTCentralManager will scan and analyze the advertisement data of miniBeaconPlus devices, MTCentralManager will create "MTPeripheral" instance for every physical devices, developers can get all advertisement data by its MTFrameHandler property.

# Connection Stage

After a MTPeripheral connected, developer can make some changes of the device by MTConnectionHandler(a Property of MTPeripheral instance).

# OTA Operations

In general, OTA operations is complicated, so we encapsulates the MTOTAManager to perform firmware update operations, please note developer can update devices only in connection status.

# Get Started

# Prepare

# Development environment:

  • Xcode9+, due to the DFU and Zip Framework based on Swift4.0, so please use Xcode9 or high version to develop;
  • iOS8, we limit the minimum iOS system version to 8.0;

# Import to Project

# Manually

  1. copy the framework files to your project folder,include "MTBeaconPlus.framework", "iOSDFULibrary.framework", "Zip.framework", then add them to your project, make sure the "target" is checked. as the screenshot below: add frameworks

  2. find: "Target" -> General -> Embedded Binaries, click the "+" below, add that 3 framework files. at the same time, make sure add them to "Linked Frameworks and Librarys", as the screenshot blew:

    make sure frameworks

  3. *about using swift, the developer should add a "Objective C BridgingHeader.h" file to the project(please do this by yourself), then add "import < MTBeaconPlus/MTBeaconPlus.h >" to the file.

  4. *using Objective-C, find: “Target” -> Building Settings -> Always Embed Swift Standard Libraries" ,then set yes

  5. !!!on iOS 10 and above, Apple add authority control of bluetooth, you need add the string to "info.plist" file of your project: Privacy - Bluetooth Peripheral Usage Description - "your description". as the screenshot below.

    bp_access

    1. !!! In iOS13 and above, Apple added permission restrictions on Bluetooth APi. You need to add a string to the project's info.plist file: Privacy-Bluetooth Always Usage Description-"Your usage description".

# Start Developing

# Get sharedInstance of Manager

First of all, the developer should get the sharedInstance of Manager:

// get sharedInstance
MTCentralManager *manager = [MTCentralManager sharedInstance];

// listen the change of iPhone bluetooth
// *** also get from "state" property.
// *** this SDK will work normally only while state == PowerStatePoweredOn!
manager.stateBlock = ^(PowerState state) {
     NSLog("current bluetooth state:%d",state);
};
1
2
3
4
5
6
7
8
9
# Scan devices

start scanning task to find devices around you, then you can get their advertisement content, connect to device and change parsameters.

/*
  manager: sharedInstance of MTCentralManager
*/

// start scanning task
[manager startScan:^(NSArray<MTPeripheral *> *peris){
  
   // Traverse the array,get instance of every device.
   // ** you can also display them on views.
    for(NSInteger i = 0; i < peris.count; i ++){
        MTPeripheral *peri = peris[i];
        
        // get FrameHandler of a device.
        // **some properties maybe nil
        MTFrameHandler *framer = peri.framer; 
        NSString *name = framer.name;          // name of device, may nil
        NSInteger rssi = framer.rssi;          // rssi
        NSInteger battery = framer.battery;    // battery,may nil
        NSString *mac = framer.mac;            // mac address,may nil
        NSArray *frames = framer.advFrames;    // all data frames of device(such as:iBeacon,UID,URL...)
    }
}];

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

at the sometime, you can stop the scanning task in this way:

/*
  manager: sharedInstance of MTCentralManager
*/

// stop the task.
[manager stopScan];
1
2
3
4
5
6

now the developer can get all advertisement data of device in this way. Next, we will talk about how to get frame data, such as iBeacon, URL, UID and etc...

Please refer to the code example below.

/*
  aFrameHandler: a MTFrameHandler instance.
*/


NSArray *frames = aFrameHandler.advFrames;
for (NSInteger i = 0; i < frames.count; i ++){
    MinewFrame *frame = frames[i];
    
    switch(frame.frameType){
      case FrameiBeacon:
        {
          MinewiBeacon *bea = (MinewiBeacon *)frame;
          NSLog(@"iBeacon:%@, %ld, %ld, %@",bea.uuid, bea.major, bea.minor, bea.lastUpdate);
        }
           break;
        
      case FrameUID:
        {
           MinewUID *uid = (MinewUID *)frame;
           NSLog(@"UID:%@, %@, %ld, %@", uid.namespaceId, uid.instanceId, uid.txPower, uid.lastUpdate);
        }
           break;
        
        case FrameDeviceInfo:
        {
            MinewDeviceInfo *info = (MinewDeviceInfo *)frame;
            NSLog(@"DeviceInfo: %ld, %@, %@, %@", (long)info.battery, info.mac, info.name, info.lastUpdate);
        }
            break;
        
        case FrameTLM:
        {
            MinewTLM *tlm = (MinewTLM *)frame;
            NSLog(@"TLM: %ld, %f, %ld, %ld, %@", tlm.batteryVol, tlm.temperature, tlm.advCount, (long)tlm.secCount, tlm.lastUpdate);
        }
            break;
        
        case FrameURL:
        {
            MinewURL *url = (MinewURL *)frame;
            NSLog(@"URL: %ld, %@, %@", url.txPower, url.urlString, url.lastUpdate);
        }
            break;
        
        case FrameLineBeacon:
        {
            MinewLineBeacon *lineBeacon = (MinewLineBeacon *)frame;
            // If necessary, vendorKey and lotKey can be obtained after the connection by other operations. For details, refer to the section "Getting the data of each channel".
            NSLog(@"LineBeacon:%@, %@, %@, %ld, %@", lineBeacon.hwId, lineBeacon.authenticationCode, lineBeacon.timestamp, lineBeacon.txPower, lineBeacon.lastUpdate);
        }
            break;
                    
      /*
         You can handle other types of data if you need to. 
      */
    }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59

Important: for all types of sensor value, if it equals to MTNAValue(a not available value we defined, in file "MTPublicHeader.h"), it means that this value is not available.

Please refer to the code example below:

/*
    aHT: a MinewHTSensor instance
    aLight: a MinewLightSensor instance
    aAcc:a MinewAccSensor instance
*/

if (aHT.temperature == MTNAValue) {
    NSLog(@"this value is not available.")
}

if (aLight.luxValue == MTNAValue) {
    NSLog(@"this value is not available.")
}

if (aAcc.XAxis == MTNAValue) {
    NSLog(@"this value is not available.")
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# Connect to device

Connect to the device in order to do more operations(change parameter, OTA). you will find that when connect to device password may need, so the "password Validating Block" must not be NULL, otherwise the app will crash!!!!

Please refer to the code example below.

/*
  manager: a MTCentralManager sharedInstance
  aMTPeripheral: a MTPeripheral instance
*/

// listen the change of device connection state
aMTPeripheral.connector.statusChangeHandler = ^(ConnectionStatus status, NSError *error) {
    
    /*
     typedef NS_ENUM(NSInteger, ConnectionStatus) {
         StatusConnectFailed = -2,
         StatusDisconnected = -1,
         StatusUndifined = 0,
         StatusConnecting,
         StatusConnected,
         StatusReadingInfo,
         StatusDeviceValidating,
         StatusPasswordValidating,
         StatusSycingTime,
         StatusReadingConnectable,
         StatusReadingFeature,
         StatusReadingFrames,
         StatusReadingTriggers,
         StatusReadingSensorInfo,
         StatusCompleted,
     };
     */
     
    /*
     there is mutiple state when connect to the device,
     only "status == StatusCompleted" means connection operations success.
     if exception appears, error will not be NULL
    */
    
};

// Connect to the device
// the aMTPeripheral is a device instance
// !!!:Warnning: passwordRequire must not be NULL!!!
[manager connectToPeripheral:aMTPeripheral passwordRequire:^(MTPasswordBlock passwordBlock){
     // the length of password string must be 8.
    // !!! read the input content from the UITextField as a password in development.
    NSString *password = @"minew123";
    passwordBlock(password);
}];

// disconnec from the device.
[manager disconnectFromPeriperal:aMTPeripheral];
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# Get base information

the developer can get device information and modify parameters when a device connected.

the code example below let the developer get the base data of the device.

/*
   aMTPeripheral:a MTPeripheral instance
*/

MTConnectionHandler *con = aMTPeripheral.connector;

ConnectionStatus conSte = con.status;  // current connection status
NSDictionary *infoDict = con.infoDict; // device info, such as:(Firmware Version: 0.9.1);
NSString *mac = con.macString; // mac address;
Connectable able = con.connectable; // device connectable,None Unknown,No disable,Yes enable
Version version = con.version; // Version of firmware;
PasswordStatus pwdStatus = con.passwordStatus; // password require or not. None, Require

MTConnectionFeature *feature = con.feature; // device features
NSInteger slotAtitude = feature.slotAtitude; // atitude of slot(s), 
FeatureSupported feaSup = feature.featureSupported; // parameters can be modified:none,adv,txpower,adv/txpower
NSArray<NSNumber *> *supFrames = feature.supportedSlots; // frames supported(multiple)
NSArray<NSNumber *> *supTxpower = feature.supportedTxpowers; // Txpower supported(multiple)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

PS: MTConnectionHandler’s Version property.

The version value comes form firmware version, check the version value to find out functions the device support:
 
// init value
VersionUndefined

// base version, base function only.
VersionBase

// this version or above support custom connection password and device info frame.
Version0_9_8

// this version or above support remote shut down.
Version0_9_9

// this version or above support triggers.
Version2_0_0

// this version or above support triggers with adv configs.
Version2_2_60

// ideal value, support all features.
VersionMax = 1000
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# Get data of each Slot

Next, let talk about the parameter data of every slot, the reason why we speak about this is because all the content of changing parameters is here.

Slot :Before read the code, let's talk about slot, you can think slot as a advertisement tool, it advertise the content of advertisement data even "don't know" what the content is. such as the 6 slots may like this:

Slot Number 0 1 2 3 4 5
Adv content iBeacon TLM UID URL HTSensor None
Adv interval(ms) 1000 2000 500 900 3000 0
RSSI@0/1m(dbm) -1 0 -4 -10 -3 0
Txpower(dbm) 4 0 -4 4 0 0

By meaning of the table, the No.0 slot will advertise iBeacon data, the No.1 slot will advertise TLM data, …, the No.5 slot will not advertise any data. each of them have their own advertising interval, Txpower and Calibration RSSI. They are independent of each other.

PS: Calibration RSSI(RSSI@0/1m) is the RSSI when device @ 0/1m(iBeacon is 1, others 0).

How to get the slot advertisement data? please refer to the code example below.

/*
    con: a MTConnectionHandler instance
*/

// each slot has a frame of current device.
// atitude of this array is equals to slot atitude(feature.slotAtitude)
// 
// In strict accordance with the order of the slot,such as:0. -> MinewiBeacon,1. -> MinewUID ...
NSArray<MinewFrame *> *frames = con.allFrames;

/*
   We assume the No.3 slot has iBeacon data, the No.4 slot has UID data.
   let's try to analyze the data of No.3 slot.
*/

// due to the defualt point is MinewFrame(the superclass of MinewiBeacon), so we need make a conversion.

// get the frame of No.3 slot
MinewFrame *frame = frames[2];

// check this slot has iBeacon data or not,
// *You can not check if you confirm its type.
for (NSInteger i = 0; i < frames.count; i ++){
MinewFrame *frame = frames[i];

switch (frame.frameType) {
case FrameiBeacon:
{
    MinewiBeacon *iBeacon = (MinewiBeacon *)frame;

    // iBeacon
    NSString *uuid = iBeacon.uuid;   // uuid
    NSInteger major = iBeacon.major;  // major
    NSInteger minor = iBeacon.minor;  // minor

    // The parameters of the slot
    NSInteger slotNumber = iBeacon.slotNumber;           // number of the slot
    NSInteger slotAdvInterval = iBeacon.slotAdvInterval; // advertisement interval
    NSInteger slotAdvTxpower = iBeacon.slotAdvTxpower;   // iBeacon:RSSI@1m others: RSSI@0m
    NSInteger slotRadioTxpower = iBeacon.slotRadioTxpower; // radio Txpower  
}
    break;
    
case FrameURL:
{
    // URL
    MinewURL *url = (MinewURL *)frame;
    NSString *urlStr = url.urlString;
    
    // The parameters of the slot are obtained in the same way
}
    break;
    
case FrameUID:
{
    // UID
    MinewUID *uid = (MinewUID *)frame;
    NSString *namespaceId = uid.namespaceId;
    NSString *instanceId = uid.instanceId;
    
    // The parameters of the slot are obtained in the same way
}
    break;

case FrameLineBeacon:
{
    // LineBeacon(The acquisition method is special)
    MTLineBeaconData *lineBeaconData = self.currentPeripheral.connector.slotHandler.slotFrameDataDic[FrameTypeString(FrameLineBeacon)];
    NSString *hwid = lineBeaconData.hwId;
    NSString *vendorKey = lineBeaconData.vendorKey;
    NSString *lotKey = lineBeaconData.lotKey;
    
    // The parameters of the slot are obtained in the same way
}
    break;
/*
   You can handle other types of data if you need to. 
*/
default:
    break;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81

You can analyze the data of other slots in the same way, it's worth noting that when frameType == FrameNone means the slot has no data: From another perspective it means this slot is closed.

# Change slot data

The developer can modify advertisement and parameters of every slot freely via our APi.

We divide the data frame into static frames and dynamic frames:

  • Static frame: advertisement data will not change when it was advertise, such as iBeacon, UID, URL
  • Dynamic frame: advertisement data will change while it was advertise, such as TLM, Sensor

Please refer to the code example below:

/*
   aConnectionHandler:a MTConnectionHandler instance
*/

// create a uid instance
MinewUID *uid = [[MinewUID alloc]init];

// set "namespaceId" and "instanceId" of UID
uid.namespaceId = @"0123456789abdcdcba12";
uid.instanceId = @"0123456789dc";

// the other parameters of slot
uid.slot = 1;  // The number of slot which you want to modify
uid.slotAdvInterval = 600;  // advertisement interval
uid.slotAdvTxpower = -3;    // RSSI@0m
uid.slotRadioTxpower = 4;   // Radio txpower.

// write to device.
// detail: 1.let No.1 slot advertise UID data, namespaceId:0123456789abdcdcba12 instanceId:0123456789dc
//         2.set No.1 slot advertisement interval to 600ms, RSSI@0m to -3dbm, radio txpower to 4dbm 
[aConnectionHandler writeFrame:uid completion:^(BOOL success, NSError *error){
     if (success) {
        NSLog(@"write frame to device successfully.");   
     } 
     else if(error) {
        NSLog(@"Error:%@", error)
     }
}];
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

Becareful, the slot parameter has ranges:

  • Advertisement interval: 100 - 5000 (ms)
  • RSSI@0m: -127 - 0 (dbm)

The most import: Radio txpower is not a range, it's grade, such as: -8, -4, 0, 4. you can get all supported Radio Txpowers from the feature property of the "MTConnectionHandler"

/*
   feature: a property of MTConnectionHandler.
*/

// get all supported Radio txpower of current device.
NSArray<NSNumber *> *supTx = feature.supportedTxpowers
1
2
3
4
5
6

OK, you can modify any slot in the way above, if you want to close a slot, only need to create a MinewFrame instance and make its frameType property to FrameNone, then write this frame to device. oh don't forget to set a slotnumber for the slot which you want to close.

# Set lineBeacon

The LineBeacon frame needs to call writeFrame method, and then the following two methods are called to set the lineBeacon's hwid, vendorKey, and lotKey.

// lotKey:Length of 16, hwid:Length of 10,vendorKey:Length of 8,include a-f/A-F/0-9.

// set LineBeacon's lotKey
[self.currentPeripheral.connector.slotHandler lineBeaconSetLotkey:@"0011223344556677" completion:^(BOOL success) {
    if (success) {
        NSLog(@"Set LineBeacon's lotKey success");
    } else {
        NSLog(@"Set LineBeacon's lotKey failed");
    }
}];


// set LineBeacon's hwid LineBeacon's vendorKey
[self.currentPeripheral.connector.slotHandler lineBeaconSetHWID:@"0011223344" VendorKey:@"00112233" completion:^(BOOL success) {
    if (success) {
        NSLog(@"Set LineBeacon's hwid and vendorKey success");
    } else {
        NSLog(@"Set LineBeacon's hwid and vendorKey failed");
    }
}];

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# Change global parameter

Global parameter of device is a device level feature, such as connectable, password require, reset to default and etc.

Please refer to the code example below.

/*
   aConnectionHandler: a MTConnectionHandler instance
*/
// reset the device
[aConnectionHandler resetFactorySettings:^(BOOL success, NSError *error){
    if(success){
        NSLog(@"Operation success!");
    }
    else {
        NSLog(@"Opertion failed!");
    }
}];

// update connectable settings
// ConnectableYES: app can connect to the device, ConnectableNO app can't connect to the device.
// if you set connectableNO, you can connect to device by press the button on device maybe next time.
// DANGER!!!:if there is no button on device and set ConnectableNO, the app can't connect to device even forever.
[aConnectionHandler updateConnectable:ConnectableYES completion:^(BOOL success, NSError *error){
    if(success){
        NSLog(@"Operation success!");
    }
    else {
        NSLog(@"Opertion failed!");
    }
}];

// Modify/Add password
// !!!: the password string length must be 8, digits or letters;
// it will add password if device has no password, update password if device has a password
[aConnectinoHandler modifyPassword:@"12345678" completion:^(BOOL success, NSError *error){
    if(success){
        NSLog(@"Operation success!");
    }
    else {
        NSLog(@"Opertion failed!");
    }
}];

// remove password
[aConnectionHandler removePassword:^(BOOL success, NSError *error){
    if(success){
        NSLog(@"Operation success!");
    }
    else {
        NSLog(@"Opertion failed!");
    }
}];

// remote shut down the device.
// DANGER!!!: please make sure there a button on device, otherwise it may not boot again.if the Model Number String is Beacon Plus-BL,not work.
[aConnectionHandler poweroff^(BOOL success, NSError *error){
    if(success){
        NSLog(@"Operation success!");
    }
    else {
        NSLog(@"Opertion failed!");
    }
}];
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# Sensor data

BeaconPlus devices integrated a variety of sensors: HT(Temperature and Humidity ), Light, Acceleration and etc, currently we provide APi for read HT/Sixaxis/Magnetometer/AtmosphericPressure History data and set PIR param data.

Please make sure the device has HT Sensor, otherwise you can't get data correctly.

Please refer to the code example below.

/*
   aConnectionHandler: a MTConnectionHandler instance
*/

// read HT History from the device
[aConnectionHandler.sensorHandler readSensorHistory:^(MTSensorData *data){
  
   // a record corresponds to an instance
   NSInteger time = ((MTSensorHTData *)data).timestamp;   // the Unix timestamp;
   double temp = ((MTSensorHTData *)data).temperature;    // temperature data;
   double humi = ((MTSensorHTData *)data).humidity;       // humidity data;
   NSInteger index = ((MTSensorHTData *)data).index;      // number of this data;
  
   if (((MTSensorHTData *)data).endStatus == EndStatusNone){
       NSLog(@"there is no data.");
   }
   else if (((MTSensorHTData *)data).endStatus == EndStatusSuccess) {
       NSLog(@"sensor data sync successfully!");
   }
   else if (((MTSensorHTData *)data).endStatus == EndStatusError) {
       NSLog(@"something wrong in syncing progress.");   
   }
}];
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

you can vividly display these data with the curve, table or other.

Please make sure the device has PIR Sensor, otherwise you can't get data correctly.

Please refer to the code example below.

/*
   aConnectionHandler: a MTConnectionHandler instance
   aRepeat: a bool,whether to allow repeated triggers
   aTime:trigger time, the infrared sensor can be triggered again after the trigger time
*/

// set PIR param to the device
[aConnectionHandler.sensorHandler pirSet:aRepeat andDelayTime:aTime completion:^(MTSensorData *data){
   
    if (data.status) {
        NSLog(@"success");
    }
    else {
        NSLog(@"failed");
    }
}];
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# Set triggers

BeaconPlus device has triggers, you can set triggers for every slot, the device will advertise the corresponding slot only when the trigger condition is met.

Please refer to the code example below.

/*
   aConnectionHandler: a MTConnectionHandler instance
*/

NSInteger sn = 2;                          // Target slot:2
TriggerType type = TriggerTypeTempAbove;   // Triggering condition:temperature above
NSInteger value = 10;                      // value:10

// create a trigger instance
// this trigger means when temperature > 10 meet the condition.
MTTriggerData *trigger = [[MTTriggerData alloc]initWithSlot:sn triggerType:type value:value];

// write to the device.
[aConnectionHandler writeTrigger:trigger completion:^(BOOL success, NSError){
    if(success){
        NSLog(@"write trigger successfully!");
    }
    else {
        NSLog(@"write trigger failed!");
    }
}];

NSInteger slotAtitude = 2;                 // Target slot:2
TriggerType type = TriggerTypeTempAbove;   // Triggering condition:temperature above
NSInteger value = 10;                      // temperature above:10

// create a trigger instance
// this trigger means when temperature > 10 meet the condition.
MTTriggerData *trigger = [[MTTriggerData alloc] initWithSlot:slotAtitude paramSupport:true triggerType:type value:value];

// Continue broadcasting after triggering if necessary
trigger.always = true;        // Whether to continue broadcasting after triggering
trigger.advInterval = 100;    // The broadcast interval
trigger.radioTxpower = -20;   // The broadcast signal strength

// write to the device.
[self.connectedPeripheral.connector writeTrigger:trigger completion:^(BOOL success) {
    if(success){
        NSLog(@"write trigger successfully!");
    }
    else {
        NSLog(@"write trigger failed!");
    }
}];

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45

Set and query whether the vibration is turned on, the broadcast frame of the vibration sensor will be received when the vibration is turned on, and the broadcast frame of the vibration sensor will not be broadcast when the vibration is turned off.

   
 	//    MTVibrationTypeOpen,
	//    MTVibrationTypeClose,
	//    MTVibrationTypeError,
  [self.currentPeripheral.connector.sensorHandler setVibrationStatus:MTVibrationTypeOpen CompletionHandler:^(BOOL isSuccess) {

  }];


  [self.currentPeripheral.connector.sensorHandler queryVibrationStatu:^(BOOL isSuccess, MTVibrationType type) {

  }];
1
2
3
4
5
6
7
8
9
10
11
12

Set and query the sensitivity of the vibration sensor.

    //    MTSensitivityTypeSuperHigh,
    //    MTSensitivityTypeHigh,
    //    MTSensitivityTypeMiddle,
    //    MTSensitivityTypeLow,
    //    MTSensitivityTypeSuperLow,
    [self.currentPeripheral.connector.sensorHandler setSensitivity:MTSensitivityTypeHigh CompletionHandler:^(BOOL isSuccess) {
        
    }];
    

    [self.currentPeripheral.connector.sensorHandler querySensitivity:^(BOOL isSuccess, MTSensitivityType type) {
        
    }];
1
2
3
4
5
6
7
8
9
10
11
12
13

Set and query the vibration sensor warning time interval. The start time must be less than the end time, accurate to the hour and minute. In addition, the parameters need to be calculated. For example, from 6:10 in the morning to 10:00 in the evening, startTime = 6 * 3600 + 10 * 60 = 22200, endTime = 22 * 3600 + 0 * 60 = 79200.

    // timeZone = hours*3600 + minutes*60
    // 22200 = 6*3600 + 10*60 = 6:30
    [self.currentPeripheral.connector.sensorHandler setFirstAlarmTimeIntervalWithAlarmStatus:MTVibrationTypeOpen StartTime:22200 EndTime:79200 CompletionHandler:^(BOOL isSuccess) {
        
    }];
    
    [self.currentPeripheral.connector.sensorHandler queryFirstAlarmTimeInterval:^(BOOL isSuccess, MTVibrationType type, uint32_t startTime, uint32_t endTime) {
        NSLog(@"vibrationType:%@, startTime:%dhour %dminute, endTime:%dhour %dminute", type == MTVibrationTypeOpen ? @"Open" : @"Close or Error", startTime/3600, startTime%3600/60, endTime/3600, endTime%3600/60);
    }];
    
    [self.currentPeripheral.connector.sensorHandler setSecondAlarmTimeIntervalWithAlarmStatus:MTVibrationTypeOpen StartTime:22200 EndTime:79200 CompletionHandler:^(BOOL isSuccess) {
        
    }];
    
    [self.currentPeripheral.connector.sensorHandler querySecondAlarmTimeInterval:^(BOOL isSuccess, MTVibrationType type, uint32_t startTime, uint32_t endTime) {
        
    }];
    
    [self.currentPeripheral.connector.sensorHandler setThirdAlarmTimeIntervalWithAlarmStatus:MTVibrationTypeOpen StartTime:22200 EndTime:79200 CompletionHandler:^(BOOL isSuccess) {
        
    }];
    
    [self.currentPeripheral.connector.sensorHandler queryThirdAlarmTimeInterval:^(BOOL isSuccess, MTVibrationType type, uint32_t startTime, uint32_t endTime) {
        
    }];
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

# Set broadcast rate

When the model is MBM01 and the firmware version is 2.5.x, you can set the Bluetooth 4.0 1Mbps broadcast rate or Bluetooth 5.0 125Kbps broadcast rate for the frame channel.

Each of the six broadcast channels occupies a value. When the value is set to 0, it represents the Bluetooth 4.2 1Mbps broadcast mode, and when the value is set to 1, it represents the Bluetooth 5.0 125Kbps broadcast mode.

**It should be noted that iOS currently cannot obtain the radio package with a radio frequency of 125Kbps, and Android does not have this problem. That is, the frame channel of the Bluetooth 5.0 broadcast rate is set to 125Kbps on iOS. After the setting is completed, the frame cannot be scanned on the iPhone, but the frame can be scanned on the Android. **

    [self.currentPeripheral.connector.sensorHandler queryBroadcastSpeed:^(BOOL isSuccess, NSArray * _Nonnull broadcastSpeedOfSlotArray) {
        NSLog(@"The broadcast rate of the first channel is %@", [broadcastSpeedOfSlotArray[0] intValue] == 1 ? @"Bluetooth5.0 125Kbps" : @"Bluetooth4.0 1Mbps");
    }];
    
    // When setting the broadcast rate, the incoming array has six values, and each value corresponds to six channels. 0 means that the broadcast rate of Bluetooth 4.0 is 1Mbps, and 1 means that the broadcast rate of Bluetooth 5.0 is 125Kbps. For example, if the first and second channels are set to 125Kbps broadcast, and the other channels are set to 1Mbps broadcast, then the settings are as follows:
    [self.currentPeripheral.connector.sensorHandler setBroadcastSpeed:@[@1,@1,@0,@0,@0,@0] CompletionHandler:^(BOOL isSuccess) {
        
    }];
1
2
3
4
5
6
7
8

# Set the parameter configuration items of the configurable firmware of the Acc sensor

This function belongs to the exclusive supporting function of customized firmware, please consult relevant business personnel before using it.

Acc sensor can be configured with firmware and parameter configuration items that can be set.

ODR ( Output rate ) :

description value
1Hz 0
10Hz 1
25Hz 2
50Hz 3
100Hz 4
200Hz 5
400Hz 6
1600Hz(low power) 7
1344HZ (HR/normal) /5000HZ(low power) 8

wakeup_threshold ( mg ) : 0 ~ 2000

wakeup_duration ( ms ) : 0 ~ 127000

    [self.currentPeripheral.connector.sensorHandler queryAccSensorParameterWithCompletionHandler:^(BOOL isSuccess, NSInteger odr, NSInteger wakeupThreshold, NSInteger wakeupDuration) {  
      
    }];    

		[self.currentPeripheral.connector.sensorHandler setAccSensorParameterWithOdr:0 WakeupThreshold:200 WakeupDuration:1000 CompletionHandler:^(BOOL isSuccess) {   
      
    }];
1
2
3
4
5
6
7

At the end of this part, you can refer all code above to develop. Of course we made a note for every APi in the SDK, if there is something new, we will update this document.

# Notes

  1. In development progress, you may find there are multiple MTPeripheral instance correspond to a physical device. On this point, we consulted Apple's engineers. they told us that currently on the iOS platform, CoreBluetooth framework unfriendly to the multiple slot devices(especially the advertisement data in changing). due to that sometimes app can't connect to the device, Google Eddystone solve this issue by press button on eddystone devices, our device support this operation too.

    iOS11 doesn't has this issue.

  2. In scanning stage, some properties may nil, especially MAC address(restriction of iOS),if current device advertise DeviceInfo frame, then you can get name, MAC address and battery.

  3. After 5 minus the app connected to device, the device will take the initiative to disconnect.

  4. If the running display cannot find the path after adding the SDK, remove the package and add it again at General-> Frameworks,Libraries,and Embedded Content

# Other

BeaconPlus SDK is also used in our BeaconSET+ app. If you need a more intuitive understanding of our beaconPlus equipment and the corresponding functions of the SDK, you can also download the BeaconSET+ app to learn more. (Reminder: BeaconSET+ app and BeaconPlus SDK need to be used with equipment produced by our company)

# Change log

  • 2017.10.11 v1.0 first version;
  • 2019.01.07 v1.1 second version;
  • 2019.07.11 v1.2 change the poweroff;
  • 2020.03.27 v1.10.0 add LineBeacon;
  • 2020.07.27 v1.10.1 Optimize getting and setting of LineBeacon frame
  • 2020.10.27 v1.10.2 Added lastUpdate property for each broadcast frame
  • 2021.4.21 v1.11.0 Added Sixaxis/Magnetometer/AtmosphericPressure sensor
  • 2021.4.28 v1.11.1 Added vibration sensor
  • 2021.09.16 v1.13.0 Added pir sensor
  • 2021.10.9 v1.14.0 Newly set Bluetooth 5.0 broadcast rate
  • 2021.12.27 v1.14.1 Added new parameter configuration items for adaptable acceleration sensor configurable firmware
  • 2022.5.10 Support parameter modification of ACC frame
  • 2022.6.1 v1.16.0 Added IN100 broadcast frame MinewMBeaconInfo
  • 2023.11.13 v1.17.0 Fixed WriteFrame crash; support background scanning
Last Updated:: 4/12/2024, 9:45:36 AM