利用CoreLocation.framework很容易掃描獲得周邊藍牙設備,蘋果開源代碼AirLocate有具體實現,下載地址:
https://developer.apple.com/library/ios/samplecode/AirLocate/Introduction/Intro.html
所獲得的iBeacon在CoreLocation裏以CLBeacon表示,其中有RSSI值(接收信號強度),可以用來計算髮射端和接收端間距離。
計算公式:
d = 10^((abs(RSSI) - A) / (10 * n))
其中:
d - 計算所得距離
RSSI - 接收信號強度(負值)
A - 發射端和接收端相隔1米時的信號強度
n - 環境衰減因子
http://www.bubuko.com/infodetail-654649.html
計算公式的代碼實現
- (float)calcDistByRSSI:(int)rssi
{
int iRssi = abs(rssi);
float power = (iRssi-59)/(10*2.0);
return pow(10, power);
}
傳入RSSI值,返回距離(單位:米)。其中,A參數賦了59,n賦了2.0。
由於所處環境不同,每臺發射源(藍牙設備)對應參數值都不一樣。按道理,公式裏的每項參數都應該做實驗(校準)獲得。
當你不知道周圍藍牙設備準確位置時,只能給A和n賦經驗值(如本例)。
修改AirLocate的APLRangingViewController.m展現部分代碼,輸出計算距離
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *identifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
// Display the UUID, major, minor and accuracy for each beacon.
NSNumber *sectionKey = [self.beacons allKeys][indexPath.section];
CLBeacon *beacon = self.beacons[sectionKey][indexPath.row];
cell.textLabel.text = [beacon.proximityUUID UUIDString];
// NSLog(@"%@", [beacon.proximityUUID UUIDString]);
// NSString *formatString = NSLocalizedString(@"Major: %@, Minor: %@, Acc: %.2fm, Rssi: %d, Dis: %.2f", @"Format string for ranging table cells.");
// cell.detailTextLabel.text = [NSString stringWithFormat:formatString, beacon.major, beacon.minor, beacon.accuracy, beacon.rssi, [self calcDistByRSSI:beacon.rssi]];
NSString *formatString = NSLocalizedString(@"Acc: %.2fm, Rssi: %d, Dis: %.2fm", @"Format string for ranging table cells.");
cell.detailTextLabel.text = [NSString stringWithFormat:formatString, beacon.accuracy, beacon.rssi, [self calcDistByRSSI:beacon.rssi]];
return cell;
}
掃描結果
展現了每臺藍牙設備的Acc(精度)、Rssi(信號強度)和Dis(距離)。