Wen-Liang Lin
Created April 3, 2020 © GPL3+

Keep social distance

Estimating distance using RSSI. Remind people to stay away from each other

BeginnerShowcase (no instructions)3 hours217
Keep social distance

Things used in this project

Software apps and online services

beacon scanner
Arduino IDE
Arduino IDE
nRF Connect SDK
Nordic Semiconductor nRF Connect SDK
Serial USB Terminal

Story

Read more

Code

7697_Keep_social_distance.ino

Arduino
/*
  Combine example ScanPeripherals and BeaconAdvertisement.
*/

#include <LBLE.h>
#include <LBLECentral.h>
#include <LBLEPeriphral.h>

double distance;
uint8_t warring_flag;

//line 41/42
#define keep_distance_UUID "4b454550-5f44-4953-5441-4e4345316d35" //HEX("KEEP_DISTANCE1m5")
#define Beacon_major 145
#define Beacon_minor 145
#define one_meter_RSSI -70 //need calibration


#define RSSI_AVG_cnt 8
#define LED_PIN 7
uint8_t LEDstate;


void setup() {
  //Initialize serial
  Serial.begin(115200);

  pinMode(LED_PIN, OUTPUT);

  // Initialize BLE subsystem
  Serial.println("BLE begin");
  LBLE.begin();
  while (!LBLE.ready()) {
    delay(10);
  }

  //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

}

void loop() {
  Serial.println("BLE ready, start scan (wait 2 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();
  Serial.println("------scan stopped-------");
}

void printDeviceInfo(int i) {
  if (LBLECentral.isIBeacon(i)) {
    LBLEUuid uuid;
    uint16_t major = 0, minor = 0;
    int8_t txPower = 0;
    int32_t Rssi_AVG;

    LBLECentral.getIBeaconInfo(i, uuid, major, minor, txPower);
    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);
    }
  }
  Serial.println();
}

//calculate distance code 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;
  }
} 

void Action(uint8_t flag)
{
  if(flag)
  {
    digitalWrite(LED_PIN, 1);
    Serial.println();
    Serial.println("Warning Keep distance!!!");
  }
  else
  {
    digitalWrite(LED_PIN, 0);
  }
}

Credits

Wen-Liang Lin

Wen-Liang Lin

28 projects • 34 followers
Hi, I am momososo

Comments