Takahiro Octopress Blog

-1から始める情弱プログラミング

REBL600FRの発信パラメータをiOSアプリで変更してみた!

| Comments

REBL600FRのパラメータ値を変更

前回はREBL600FRの検知&パラメータ値の読込みまでやってみました。
今日はREBL600FRが発信するパラメータ値をiOSアプリから変更してみます。

まず、UIButtonをタップしたときにmajorの値を固定値に変更するメソッドを作成してみます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// ViewController.m
// 書き込みテスト用のメソッド
- (IBAction)writeDataTestMethod:(id)sender {
  // ① majorの値を4661に設定
  NSInteger writeInt = 4661;
  // ② 10進数を16進数に変換して文字列にする
  NSString *witeString = [NSString stringWithFormat:@"%lX",(long)writeInt];
  // ③ 16進数のNSString型をNSData型に変換する処理
  NSData *writeData = [witeString dataFromHexString];
  NSLog(@"writeData: %@", writeData);
  
  // ④ データの書込み処理
  [self.connectedPeripheral writeValue:writeData forCharacteristic:self.majorChar type:CBCharacteristicWriteWithResponse];
  
}

上記メソッドの説明をします。
まず、majorの値を4661に変更したいとします。

【処理の順番】
① ユーザが入力する際には当然、10進数の値で考えると思うので、初めの入力値は 10進数 の4661とします。
② 次にREBL600FRが理解できるように16進数に変換する必要があります。
『NSInteger型かつ10進数』で表された4661を『NSString型かつ16進数』の値に変換します。
③ 書換えたい値をREBL600FRに送るためにNSData型に変換します。
④ 書込みたいデータが用意できたので、書込み処理を実行します。
self.majorCharには予め、major値のキャラクタリスティックを保持しています。

さて、③と④の処理について説明が不十分なので、説明します。
③ですが、NSString型のクラスを拡張し、 16進数のNSString型をNSData型に変換する メソッドを追加します。

1
2
3
4
5
6
7
8
9
// NSString+Conversion.h
#import <Foundation/Foundation.h>

@interface NSString (NSString_Conversion)

#pragma mark - Data Conversion
- (NSData *)dataFromHexString;

@end
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
// NSString+Conversion.m
#import "NSString+Conversion.h"

@implementation NSString (NSString_Conversion)

#pragma mark - Data Conversion
- (NSData *)dataFromHexString {
  const char *chars = [self UTF8String];
  NSUInteger i = 0, len = self.length;

  NSMutableData *data = [NSMutableData dataWithCapacity:len / 2];
  char byteChars[3] = {'\0','\0','\0'};
  unsigned long wholeByte;

  while (i < len) {
      byteChars[0] = chars[i++];
      byteChars[1] = chars[i++];
      wholeByte = strtoul(byteChars, NULL, 16);
      [data appendBytes:&wholeByte length:1];
  }

  return data;
}

@end

続いて、④について説明します。
self.majorCharにmajor値のキャラクタリステックを保持するために、前回の記事で説明した処理を少し書換えます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// ViewController.m
// Characteristicesが見つかったときに呼び出される処理
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error {
  
  for(CBCharacteristic *characteristic in service.characteristics) {
      // キャラクタリステックのUUID値を取得
      CBUUID *uuid = characteristic.UUID;
      NSString *uuidString = [NSString alloc] initWithFormat:@"%@", uuid];]

      if([uuidString isEqual:@"569A2013-B87F-490C-92CB-11BA5EA5167C"]) {
          // major値の場合はCharacteristicをメモリに保持
          self.majorChar = characteristic;
      }

      // 値が変わったときに通知を受けたい場合に実行
      [peripheral setNotifyValue:YES forCharacteristic:characteristic];
      // キャラクタリステックのvalueを知りたい場合に実行
      [peripheral readValueForCharacteristic:characteristic];
  }
}

上記処理のタイミングでself.majorCharをメモリに保持できるので、writeValueメソッドの引数として指定できます。
さて、writeValueメソッドを実行したときにエラーが発生する可能性があるので、下記メソッドを追加します。

1
2
3
4
5
6
7
8
// Characteristicの書き込み処理が完了した場合に呼び出される処理
- (void)peripheral:(CBPeripheral *)peripheral didWriteValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
{
  if(error) {
      NSLog(@"error: %@", error);
      return;
  }
}

以上の処理を実装した上でUIButtonを押して、LightBlueを使って確認してみると、確かに値が変更されていることがわかります。

これまでのソースはGitHubにアップしてありますので、興味がある方はご自由にお使いください。

参考:
10進数と16進数の変換
NSString hex to bytes

Comments