Skip to content
Snippets Groups Projects
Commit f612ae8f authored by Marie Bureau's avatar Marie Bureau
Browse files

keep gates open by sending pulse

parent 411e6a94
Branches
Tags
1 merge request!4My gates ble
......@@ -20,8 +20,10 @@
#define STATE_OPEN_GATE 2 // STATE_OPEN_GATE : door is open. Keep the door open while receiving tram. Go to STATE_SCAN when not receiving tram after GO_TO_SCAN_STATE_DELAY
#define SCAN_TIME 2 // scan period in second
#define GO_TO_SCAN_STATE_DELAY 4 // if no trame was received during 4 sec, go to STATE_SCAN
#define DELAY_REJECT_TRAM 3 // if the last tram was received more than 3 seconds ago, the average RSSI is not computed and returns an average RSSI of -100
#define GO_TO_SCAN_STATE_DELAY 4 // if no trame was received during X sec, go to STATE_SCAN
#define DELAY_REJECT_TRAM 3 // if the last tram was received more than X seconds ago, the average RSSI is not computed and returns an average RSSI of -100
#define PULSE_DURATION 500 // pulse to open gate. duration in ms
#define DELAY_BETWEEN_PULSE 4 // to keep the gate open emit a pulse every X seconds
#define RSSI_THRESHOLD_OPEN_GATE -95 // if the average RSSI is above this threshold the gate can be open
// ***** definitions *****
......@@ -31,192 +33,195 @@ struct RSSI { // table contening the RSSI and time of the last 2 trams. Used to
int val = -100;
time_t time = 0;
} tabRSSI[2];
time_t tPulseGate = 0;
// ***** open gate *****
void openGate() {
Serial.println(" OPENING GATE"); //DEBUG
digitalWrite(RELAY1, HIGH); //activate relay1 for 0.5 sec
delay(PULSE_DURATION);
digitalWrite(RELAY1, LOW);
tPulseGate = t; // save time of the last pulse
}
class IBeaconAdvertised : public BLEAdvertisedDeviceCallbacks {
public:
public:
// BLE
void onResult(BLEAdvertisedDevice device) {
// check if iBeacon tram
if (!isIBeacon(device)) {
return;
}
// BLE
void onResult(BLEAdvertisedDevice device) {
// check if iBeacon tram
if (!isIBeacon(device)) {
return;
}
// check for NAVETTE_UUID
if (!isNavetteUUID(device)) {
return;
}
// check for NAVETTE_UUID
if (!isNavetteUUID(device)) {
return;
}
// received a trame FORCE GATE OPEN
if (HIGH2BITS_U16(getMinor(device)) == FORCEGATEOPEN) {
printIBeacon(device); // DEBUG
Serial.printf(" - force open tram\n"); // DEBUG
openGate();
updateRSSItab(getRSSI(device));
return;
}
// received a trame FORCE GATE OPEN
if (HIGH2BITS_U16(getMinor(device)) == FORCEGATEOPEN) {
printIBeacon(device); // DEBUG
Serial.printf(" - force open tram\n"); // DEBUG
openGate();
updateRSSItab(getRSSI(device));
return;
}
//check gate state (STATE_SCAN or STATE_OPEN_GATE)
switch (STATE) {
case STATE_OPEN_GATE:
// gate is already open, nothing to do
printIBeacon(device); // DEBUG
Serial.printf(" - gate is already open\n"); // DEBUG
updateRSSItab(getRSSI(device)); // save RSSI in the table
STATE = STATE_OPEN_GATE;
break;
case STATE_SCAN:
default:
//check if gate needs to be open
RSSI newRSSI = getRSSI(device); // get RSSI
int avRSSI = averageRSSI(newRSSI); // compute average RSSI (with 3 last values)
if (avRSSI > RSSI_THRESHOLD_OPEN_GATE) { // if the received signal power is above the threshold RSSI_THRESHOLD_OPEN_GATE
printIBeacon(device); // DEBUG
Serial.printf(" - RSSI average OK:%d\n", avRSSI); // DEBUG
openGate(); // open the gate
updateRSSItab(newRSSI); // save received tram RSSI in the table
STATE = STATE_OPEN_GATE; // change state and go to state STATE_OPEN_GATE
} else {
printIBeacon(device); // DEBUG
Serial.printf(" - RSSI average too low:%d\n", avRSSI); // DEBUG
updateRSSItab(newRSSI);
STATE = STATE_SCAN;
}
break;
}
}
//check gate state (STATE_SCAN or STATE_OPEN_GATE)
switch (STATE) {
private:
case STATE_OPEN_GATE:
// gate is open, keep the door open by sending a pulse every x sec
printIBeacon(device); // DEBUG
Serial.printf(" - gate is open\n"); // DEBUG
updateRSSItab(getRSSI(device)); // save RSSI in the table
// ***** open gate *****
void openGate() {
Serial.println(" OPENING GATE"); //DEBUG
digitalWrite(RELAY1, HIGH); //activate relay1 for 1 second
delay(1000);
digitalWrite(RELAY1, LOW);
}
break;
// ***** is frame iBeacon ? *****
bool isIBeacon(BLEAdvertisedDevice device) {
if (device.getManufacturerData().length() < 25) {
return false;
}
if (getCompanyId(device) != 0x004C) {
return false;
}
if (getIBeaconHeader(device) != 0x1502) {
return false;
case STATE_SCAN:
default:
//check if gate needs to be open
RSSI newRSSI = getRSSI(device); // get RSSI
int avRSSI = averageRSSI(newRSSI); // compute average RSSI (with 3 last values)
if (avRSSI > RSSI_THRESHOLD_OPEN_GATE) { // if the received signal power is above the threshold RSSI_THRESHOLD_OPEN_GATE
printIBeacon(device); // DEBUG
Serial.printf(" - RSSI average OK:%d\n", avRSSI); // DEBUG
openGate(); // open the gate
updateRSSItab(newRSSI); // save received tram RSSI in the table
STATE = STATE_OPEN_GATE; // change state and go to state STATE_OPEN_GATE
} else {
printIBeacon(device); // DEBUG
Serial.printf(" - RSSI average too low:%d\n", avRSSI); // DEBUG
updateRSSItab(newRSSI);
STATE = STATE_SCAN;
}
break;
}
}
return true;
}
// ***** is UUID_NAVETTE ? *****
bool isNavetteUUID(BLEAdvertisedDevice device) { // check if iBeacon tram UUID = NAVETTE_UUID
if (getProxyUuid(device).equals(BLEUUID(NAVETTE_UUID))) {
private:
// ***** is frame iBeacon ? *****
bool isIBeacon(BLEAdvertisedDevice device) {
if (device.getManufacturerData().length() < 25) {
return false;
}
if (getCompanyId(device) != 0x004C) {
return false;
}
if (getIBeaconHeader(device) != 0x1502) {
return false;
}
return true;
} else {
return false;
}
}
// ***** RSSI *****
RSSI getRSSI(BLEAdvertisedDevice device) { // get signal RSSI and reception time
RSSI newRSSI;
time(&t);
newRSSI.val = device.getRSSI();
newRSSI.time = t;
return newRSSI;
}
// ***** is UUID_NAVETTE ? *****
bool isNavetteUUID(BLEAdvertisedDevice device) { // check if iBeacon tram UUID = NAVETTE_UUID
if (getProxyUuid(device).equals(BLEUUID(NAVETTE_UUID))) {
return true;
} else {
return false;
}
}
// ***** update RSSI table *****
void updateRSSItab(RSSI newRSSI) { // save RSSI and time in the table tabRSSI
tabRSSI[1] = tabRSSI[0];
tabRSSI[0] = newRSSI;
}
// ***** RSSI *****
RSSI getRSSI(BLEAdvertisedDevice device) { // get signal RSSI and reception time
RSSI newRSSI;
time(&t);
newRSSI.val = device.getRSSI();
newRSSI.time = t;
return newRSSI;
}
// ***** compute average RSSI *****
int averageRSSI(RSSI newRSSI) {
if ((newRSSI.time - tabRSSI[0].time) > DELAY_REJECT_TRAM) { // if last trame was detected more than x sec ago, return an average RSSI of -100
updateRSSItab(newRSSI);
return -100;
} else {
int averageRSSI = (newRSSI.val + tabRSSI[0].val + tabRSSI[1].val) / 3; // compute the average RSSI using the last 3 RSSI values
updateRSSItab(newRSSI);
return averageRSSI;
// ***** update RSSI table *****
void updateRSSItab(RSSI newRSSI) { // save RSSI and time in the table tabRSSI
tabRSSI[1] = tabRSSI[0];
tabRSSI[0] = newRSSI;
}
}
// ***** companyId *****
unsigned short getCompanyId(BLEAdvertisedDevice device) {
const unsigned short *pCompanyId = (const unsigned short *)&device
// ***** compute average RSSI *****
int averageRSSI(RSSI newRSSI) {
if ((newRSSI.time - tabRSSI[0].time) > DELAY_REJECT_TRAM) { // if last trame was detected more than x sec ago, return an average RSSI of -100
updateRSSItab(newRSSI);
return -100;
} else {
int averageRSSI = (newRSSI.val + tabRSSI[0].val + tabRSSI[1].val) / 3; // compute the average RSSI using the last 3 RSSI values
updateRSSItab(newRSSI);
return averageRSSI;
}
}
// ***** companyId *****
unsigned short getCompanyId(BLEAdvertisedDevice device) {
const unsigned short *pCompanyId = (const unsigned short *)&device
.getManufacturerData()
.c_str()[0];
return *pCompanyId;
}
return *pCompanyId;
}
// ***** iBeacon Header *****
unsigned short getIBeaconHeader(BLEAdvertisedDevice device) {
const unsigned short *pHeader = (const unsigned short *)&device
// ***** iBeacon Header *****
unsigned short getIBeaconHeader(BLEAdvertisedDevice device) {
const unsigned short *pHeader = (const unsigned short *)&device
.getManufacturerData()
.c_str()[2];
return *pHeader;
}
return *pHeader;
}
// ***** iBEACON UUID *****
BLEUUID getProxyUuid(BLEAdvertisedDevice device) {
BLEUUID uuid;
std::string strManufacturerData = device.getManufacturerData();
uint8_t cManufacturerData[100];
strManufacturerData.copy((char *)cManufacturerData, strManufacturerData.length(), 0);
BLEBeacon oBeacon = BLEBeacon();
oBeacon.setData(strManufacturerData);
uuid = oBeacon.getProximityUUID();
return uuid;
}
// ***** iBEACON UUID *****
BLEUUID getProxyUuid(BLEAdvertisedDevice device) {
BLEUUID uuid;
std::string strManufacturerData = device.getManufacturerData();
uint8_t cManufacturerData[100];
strManufacturerData.copy((char *)cManufacturerData, strManufacturerData.length(), 0);
BLEBeacon oBeacon = BLEBeacon();
oBeacon.setData(strManufacturerData);
uuid = oBeacon.getProximityUUID();
return uuid;
}
// ***** iBEACON Major *****
uint16_t getMajor(BLEAdvertisedDevice device) {
std::string strManufacturerData = device.getManufacturerData();
uint8_t cManufacturerData[100];
strManufacturerData.copy((char *)cManufacturerData, strManufacturerData.length(), 0);
BLEBeacon oBeacon = BLEBeacon();
oBeacon.setData(strManufacturerData);
return ENDIAN_CHANGE_U16(oBeacon.getMajor());
}
// ***** iBEACON Major *****
uint16_t getMajor(BLEAdvertisedDevice device) {
std::string strManufacturerData = device.getManufacturerData();
uint8_t cManufacturerData[100];
strManufacturerData.copy((char *)cManufacturerData, strManufacturerData.length(), 0);
BLEBeacon oBeacon = BLEBeacon();
oBeacon.setData(strManufacturerData);
return ENDIAN_CHANGE_U16(oBeacon.getMajor());
}
// ***** iBEACON Minor *****
uint16_t getMinor(BLEAdvertisedDevice device) {
std::string strManufacturerData = device.getManufacturerData();
uint8_t cManufacturerData[100];
strManufacturerData.copy((char *)cManufacturerData, strManufacturerData.length(), 0);
BLEBeacon oBeacon = BLEBeacon();
oBeacon.setData(strManufacturerData);
return ENDIAN_CHANGE_U16(oBeacon.getMinor());
}
// ***** iBEACON Minor *****
uint16_t getMinor(BLEAdvertisedDevice device) {
std::string strManufacturerData = device.getManufacturerData();
uint8_t cManufacturerData[100];
strManufacturerData.copy((char *)cManufacturerData, strManufacturerData.length(), 0);
BLEBeacon oBeacon = BLEBeacon();
oBeacon.setData(strManufacturerData);
return ENDIAN_CHANGE_U16(oBeacon.getMinor());
}
// ***** iBEACON TxPower *****
int8_t getTxPower(BLEAdvertisedDevice device) {
std::string strManufacturerData = device.getManufacturerData();
uint8_t cManufacturerData[100];
strManufacturerData.copy((char *)cManufacturerData, strManufacturerData.length(), 0);
BLEBeacon oBeacon = BLEBeacon();
oBeacon.setData(strManufacturerData);
return oBeacon.getSignalPower();
}
// ***** iBEACON TxPower *****
int8_t getTxPower(BLEAdvertisedDevice device) {
std::string strManufacturerData = device.getManufacturerData();
uint8_t cManufacturerData[100];
strManufacturerData.copy((char *)cManufacturerData, strManufacturerData.length(), 0);
BLEBeacon oBeacon = BLEBeacon();
oBeacon.setData(strManufacturerData);
return oBeacon.getSignalPower();
}
// ***** print iBeacon device info *****
void printIBeacon(BLEAdvertisedDevice device) {
time(&t);
Serial.printf("time:%d name:%s uuid:%s major:%d minor:%d rssi:%d\r",
t,
device.getName().c_str(),
getProxyUuid(device).toString().c_str(),
getMajor(device),
getMinor(device),
device.getRSSI());
}
// ***** print iBeacon device info *****
void printIBeacon(BLEAdvertisedDevice device) {
time(&t);
Serial.printf("time:%d name:%s uuid:%s major:%d minor:%d rssi:%d\r",
t,
device.getName().c_str(),
getProxyUuid(device).toString().c_str(),
getMajor(device),
getMinor(device),
device.getRSSI());
}
};
void setup() {
......@@ -233,14 +238,21 @@ void setup() {
void loop() {
if (STATE == STATE_OPEN_GATE) { // if in STATE_OPEN_GATE (gate is already open)
time(&t); // get time
if ((t - tabRSSI[0].time) > GO_TO_SCAN_STATE_DELAY) { // if last tram was received more than x seconds ago (GO_TO_SCAN_STATE_DELAY)
STATE = STATE_SCAN; // change state : go to STATE_SCAN
Serial.printf("time:%d GO TO STATE_SCAN, last tram received at t:%d\n", t, tabRSSI[0].time); // DEBUG
}
else {
if((t- tPulseGate) > DELAY_BETWEEN_PULSE){ // send a pulse to keep the door open every X sec (DELAY_BETWEEN_PULSE)
Serial.printf("time:%d KEEPING GATE OPEN, last pulse sent at t:%d", t, tPulseGate); // DEBUG
openGate();
}
}
}
BLEScan *scan = BLEDevice::getScan(); // start scanning
BLEScan *scan = BLEDevice::getScan(); // start scanning
scan->setAdvertisedDeviceCallbacks(new IBeaconAdvertised(), true);
scan->setActiveScan(true);
scan->start(SCAN_TIME);
}
\ No newline at end of file
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment