iOS + BLE (part 1, getting connected)
 Page :   [ 1 ]    [ 2 ]  

You'll need to use the Red Bear BLEFramework in your XCode project.  Then in the file called BLEDefines.h you'll see some defines that need to be changed to use with the HM11.

// RBL Service

//#define RBL_SERVICE_UUID    "713D0000-503E-4C75-BA94-3148F18D941E"
//#define RBL_CHAR_TX_UUID    "713D0002-503E-4C75-BA94-3148F18D941E"
//#define RBL_CHAR_RX_UUID    "713D0003-503E-4C75-BA94-3148F18D941E"

#define RBL_SERVICE_UUID    "FFE0"
#define RBL_CHAR_TX_UUID    "FFE1"
#define RBL_CHAR_RX_UUID    "FFE1"

#define RBL_BLE_FRAMEWORK_VER    0x0200

If you deploy their sample app called "SimpleControls" on your phone and press the connect button it should connect to the first HM11 it finds.

I wanted to use the RedBear BLE class as a singleton so I needed to make a wrapper class for a singleton that would manage the RedBear BLE class.

So I made a class called "BLEManager".

The existing Red Bear code scanned for peripherals and left it to front-end code to connect.  In the case of their sample app it just connects to the first module it finds.

What I wanted to do was have an app that connected to a module with a particular name (in this case HMSoft)

Theres a method in BLE.m called "scanTimer:" that stops the scan for peripherals after a certain period of time.  I Wanted to go a step further and auto connect to a module called HMSoft so I had to swizzle the scanTimer: method to make my own functionality to auto connect.

I needed to make this category to swizzle "scanTimer:" and my "newScanTimer:"

 

//
//  BLE+timer.h
//

#import <Foundation/Foundation.h>
#import "BLE.h"

@interface BLE (timer)

@end

 

//
//  BLE+timer.m
//

#import "BLE+timer.h"
#import <objc/runtime.h>

@implementation BLE (timer)

- (void) newScanTimer:(NSTimer *)timer
{

    [self newScanTimer:nil];

    // wanted to automatically connect to a particular one
    
    if (self.peripherals.count > 0) {

        for (CBPeripheral * per in self.peripherals){
            
            // to successfully change names and also update
            // the ios cache of the name then do the following
            
            // AT+NAMEHMSoft
            // AT+RESET
            
            // then connect twice with the ios app here but
            // comment out the "if" logic below so that it just auto connects
            
            // connect twice so it becomes aware of the change
            
            // this seems to need to be done for any phone that has
            // cached data (should test on a non cached phone to be sure)
            
            
            // additional commands
            // AT+BAUD1     // sets to 19200
            // AT+PIO11     // sets pio 1 to not blink when ble not connected
            // AT+RESET
            // in arduino serial console the ble module is at 19200 and serial console is 38400
            // when ble is at default 9600 baud then serial console needs to be slower than 38400 .. so set to 19200
            
            if ([per.name isEqualToString:@"HMSoft"]){
                [self connectPeripheral:per];
            }
            
        }

    }
    
}

+(void)load{
    
    static dispatch_once_t onceToken;

    dispatch_once(&onceToken, ^{

        SEL oSel = @selector(scanTimer:);
        SEL nSel = @selector(newScanTimer:);
        
        Method origMethod = class_getInstanceMethod(self.class, oSel);
        Method newMethod = class_getInstanceMethod(self.class, nSel);
        
        if (origMethod && newMethod){
            if (class_addMethod(self,oSel,method_getImplementation(newMethod),method_getTypeEncoding(newMethod))){
                class_replaceMethod(self,nSel,method_getImplementation(origMethod),method_getTypeEncoding(origMethod));
            } else {
                method_exchangeImplementations(origMethod, newMethod);
            }
        }
        
    });
    
}

@end

Then here is my singleton BLEManager class:

 

//
//  BLEManager.h
//

#import "BLE+timer.h"

/*
 remember to use these in redbears BLEDefines.h
 
 #define RBL_SERVICE_UUID                            "FFE0"
 #define RBL_CHAR_TX_UUID                            "FFE1"
 #define RBL_CHAR_RX_UUID                            "FFE1"
*/

@protocol myBLEDelegate <NSObject>
@optional
-(void) bleConnected;
-(void) bleDisconnected;
-(void) bleUpdateRSSI:(NSNumber *) rssi;
-(void) bleReceivedData:(NSMutableArray *)data;
@required
@end

@interface BLEManager : NSObject <BLEDelegate> {

}

@property (nonatomic,assign) id <myBLEDelegate> delegate;

+ (id)sharedManager;
-(void)sendPayload:(float)val;
-(BOOL)isConnected;
-(void)start;

@end

 

//
//  BLEManager.m
//

#import "BLEManager.h"
#import "AppDelegate.h"

@interface BLEManager ()

@property (strong, nonatomic) BLE *ble;

@end

@implementation BLEManager

@synthesize delegate;

+ (id)sharedManager {
    static BLEManager *sharedMyManager = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedMyManager = [[self alloc] init];
    });
    return sharedMyManager;
}

- (id)init {
    if (self = [super init]) {
        
        _ble = [[BLE alloc] init];
        [_ble controlSetup];
        _ble.delegate = self;
        
        [self start];
        
    }
    return self;
}


-(void)bleDidConnect{
    
    if ([self.delegate respondsToSelector:@selector(bleConnected)]) {
        [self.delegate bleConnected];
    }
    
}


-(void)bleDidDisconnect{
    if ([self.delegate respondsToSelector:@selector(bleDisconnected)]) {
        [self.delegate bleDisconnected];
    }
}


-(void) bleDidUpdateRSSI:(NSNumber *) rssi{
    //  if ([self.delegate respondsToSelector:@selector(bleUpdatedRSSI:)]) {
    //      [self.delegate bleUpdatedRSSI:rssi];
    //  }
}


-(void)start{
    
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 1 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
        [_ble findBLEPeripherals:5];
    });
    
}


-(void) bleDidReceiveData:(unsigned char *)data length:(int)length
{
    
    // the RBL lib sends a char array.
    // i just massage it a bit here and send it to the app to deal with
    
    NSLog(@"Length: %d", length);
    
    NSMutableArray * dat = [NSMutableArray array];
    
    [delegate bleReceivedData:dat];
    
}

-(BOOL)isConnected{
    
    return _ble.isConnected;
    
}

-(void)sendPayload:(float )val{
    
    // the app sends some arbitrary payload
    // here i massage it and send it to the RBL library
    
    UInt8 buf[3] = {0x03, val, 0x00};
    
    NSData *data = [[NSData alloc] initWithBytes:buf length:3];
    
    [_ble write:data];
    
}

@end

 

That should get the app connecting to an arbitrarily named module.  Later I'll write about what to do next to make something useful.

 

(Page 2 of 2)