As we know that keeping social distance can reduce the risk of getting COVID-19. Here I think we can use Bluetooth beacon RSSI value to calculate the distance between each other. Almost everyone has a smartphone, the best solution is smartphone APP. But I don't know how to program the APP, AI2 doesn't support beacon, I will propose use hardware boards.
System overviewHere I use two LinkIt™ 7697 boards, each one both broadcast iBeacon and scan peripherals. After scan, if find iBeacon device and UUID is matching with preset, calculate the distance. If distance <1.5m lighting LED.
LinkIt™ 7697 x 2 : Learn more about Linktit 7697 here.
SoftwareI combine two example ScanPeripherals and BeaconAdvertisement.
Setting iBeacon at setup function (line 39~49)
//tx
// configure our advertisement data as iBeacon.
LBLEAdvertisementData beaconData;
// This is a common AirLocate example UUID.
//LBLEUuid uuid("E2C56DB5-DFFB-48D2-B060-D0F5A71096E0");//
LBLEUuid uuid(keep_distance_UUID);//
beaconData.configAsIBeacon(uuid, Beacon_major, Beacon_minor, one_meter_RSSI);
Serial.print("Start advertising iBeacon with uuid=");
Serial.println(uuid);
// start advertising it
LBLEPeripheral.advertise(beaconData);
//tx end
Loop function scan Beacon and check the device every two seconds.
LBLECentral.scan();
for(int i = 0; i < 2; ++i)
{
delay(1000);
Serial.print(".");
}
warring_flag = 0;
for (int i = 0; i < LBLECentral.getPeripheralCount(); ++i) {
printDeviceInfo(i);
}
Action(warring_flag);
LBLECentral.stopScan();
In function printDeviceInfo check devices' UUID. If the same with preset calculate distance.
if(uuid==keep_distance_UUID)
{
Serial.println();
Serial.print("Find someone:");
Serial.print("\tRSSI:");
Rssi_AVG=0;
for (int j = 0; j < RSSI_AVG_cnt; j++)
{
Rssi_AVG += LBLECentral.getRSSI(i);
}
Rssi_AVG /= RSSI_AVG_cnt;
Serial.print(Rssi_AVG);
Serial.print("\tMajor:");
Serial.print(major);
Serial.print("\tMinor:");
Serial.print(minor);
distance = calculateAccuracy(txPower,Rssi_AVG);
if(distance<1.5)
{
warring_flag=1;
}
Serial.print("\tDistance:");
Serial.print(distance);
}
calculate distance code copy from https://stackoverflow.com/a/20434019
static double calculateAccuracy(int txPower, double rssi)
{
if (rssi == 0) {
return -1.0; // if we cannot determine accuracy, return -1.
}
double ratio = rssi*1.0/txPower;
if (ratio < 1.0) {
return pow(ratio,10);
}
else {
double accuracy = (0.89976)*pow(ratio,7.7095) + 0.111;
return accuracy;
}
}
If the distance calculated results smaller than 1.5 meters do the action function.
Here I turn on the onboard LED.
void Action(uint8_t flag)
{
if(flag)
{
digitalWrite(LED_PIN, 1);
Serial.println();
Serial.println("Warning Keep distance!!!");
}
else
{
digitalWrite(LED_PIN, 0);
}
}
After first-time download firmware must calibration one meter RSSI. Use nRF Connect APP to scan and put LinkIt™ 7697 one meter away from the phone. Replace #define one_meter_RSSI -70 with reading data and re-build code download firmware again.
#define one_meter_RSSI -70
Use Beacon Scanner APP to scan.
I use APP to re-calibrated RSSI value.
Use Serial USB Terminal APP to read serial data from USB.
Since I use the smartphone RSSI value calibrated, the distance calculates have lot of offsets when device to device.
When two devices close each other LED light.
Future WorkSmartphone or wristband APP: can install APP and use it directly without buying another device.
Calculate function improve: from video, RSSI was not stable so the distance wasn't always correct.
Use audio or vibrate as warming:
Referencehttps://os.mbed.com/blog/entry/BLE-Beacons-URIBeacon-AltBeacons-iBeacon/#iBeacon
https://docs.labs.mediatek.com/resource/linkit7697-arduino/en
Comments