void DW1000RangingClass::loop() { //we check if needed to reset ! checkForReset(); long time = millis(); if(time-timer > _timerDelay) { timer = time; timerTick(); } if(_sentAck) { _sentAck = false; int messageType = detectMessageType(data); if(messageType != POLL_ACK && messageType != POLL && messageType != RANGE) return; //A msg was sent. We launch the ranging protocole when a message was sent if(_type == ANCHOR) { if(messageType == POLL_ACK) { DW1000Device* myDistantDevice = searchDistantDevice(_lastSentToShortAddress); DW1000.getTransmitTimestamp(myDistantDevice->timePollAckSent); } } else if(_type == TAG) { if(messageType == POLL) { DW1000Time timePollSent; DW1000.getTransmitTimestamp(timePollSent); //if the last device we send the POLL is broadcast: if(_lastSentToShortAddress[0] == 0xFF && _lastSentToShortAddress[1] == 0xFF) { //we save the value for all the devices ! for(short i = 0; i < _networkDevicesNumber; i++) { _networkDevices[i].timePollSent = timePollSent; } } else { //we search the device associated with the last send address DW1000Device* myDistantDevice = searchDistantDevice(_lastSentToShortAddress); //we save the value just for one device myDistantDevice->timePollSent = timePollSent; } } else if(messageType == RANGE) { DW1000Time timeRangeSent; DW1000.getTransmitTimestamp(timeRangeSent); //if the last device we send the POLL is broadcast: if(_lastSentToShortAddress[0] == 0xFF && _lastSentToShortAddress[1] == 0xFF) { //we save the value for all the devices ! for(short i = 0; i < _networkDevicesNumber; i++) { _networkDevices[i].timeRangeSent = timeRangeSent; } } else { //we search the device associated with the last send address DW1000Device* myDistantDevice = searchDistantDevice(_lastSentToShortAddress); //we save the value just for one device myDistantDevice->timeRangeSent = timeRangeSent; } } } } //check for new received message if(_receivedAck) { _receivedAck = false; //we read the datas from the modules: // get message and parse DW1000.getData(data, LEN_DATA); int messageType = detectMessageType(data); //we have just received a BLINK message from tag if(messageType == BLINK && _type == ANCHOR) { byte address[8]; byte shortAddress[2]; _globalMac.decodeBlinkFrame(data, address, shortAddress); //we crate a new device with th tag DW1000Device myTag(address, shortAddress); if(addNetworkDevices(&myTag)) { Serial.print("blink; 1 device added ! -> "); Serial.print(" short:"); Serial.println(myTag.getShortAddress(), HEX); //we relpy by the transmit ranging init message transmitRangingInit(&myTag); noteActivity(); } _expectedMsgId = POLL; } else if(messageType == RANGING_INIT && _type == TAG) { byte address[2]; _globalMac.decodeLongMACFrame(data, address); //we crate a new device with the anchor DW1000Device myAnchor(address, true); if(addNetworkDevices(&myAnchor, true)) { Serial.print("ranging init; 1 device added ! -> "); Serial.print(" short:"); Serial.println(myAnchor.getShortAddress(), HEX); } noteActivity(); } else { //we have a short mac layer frame ! byte address[2]; _globalMac.decodeShortMACFrame(data, address); //we get the device which correspond to the message which was sent (need to be filtered by MAC address) DW1000Device* myDistantDevice = searchDistantDevice(address); if(myDistantDevice == NULL) { Serial.println("Not found"); //we don't have the short address of the device in memory /* Serial.print("unknown: "); Serial.print(address[0], HEX); Serial.print(":"); Serial.println(address[1], HEX); */ return; } //then we proceed to range protocole if(_type == ANCHOR) { if(messageType != _expectedMsgId) { // unexpected message, start over again (except if already POLL) _protocolFailed = true; } if(messageType == POLL) { //we receive a POLL which is a broacast message //we need to grab info about it short numberDevices = 0; memcpy(&numberDevices, data+SHORT_MAC_LEN+1, 1); for(short i = 0; i < numberDevices; i++) { //we need to test if this value is for us: //we grab the mac address of each devices: byte shortAddress[2]; memcpy(shortAddress, data+SHORT_MAC_LEN+2+i*4, 2); //we test if the short address is our address if(shortAddress[0] == _currentShortAddress[0] && shortAddress[1] == _currentShortAddress[1]) { //we grab the replytime wich is for us unsigned int replyTime = 0; memcpy(&replyTime, data+SHORT_MAC_LEN+2+i*4+2, 2); //we configure our replyTime; _replyDelayTimeUS = replyTime; // on POLL we (re-)start, so no protocol failure _protocolFailed = false; DW1000.getReceiveTimestamp(myDistantDevice->timePollReceived); //we note activity for our device: myDistantDevice->noteActivity(); //we indicate our next receive message for our ranging protocole _expectedMsgId = RANGE; transmitPollAck(myDistantDevice); noteActivity(); return; } } } else if(messageType == RANGE) { //we receive a RANGE which is a broacast message //we need to grab info about it short numberDevices = 0; memcpy(&numberDevices, data+SHORT_MAC_LEN+1, 1); for(short i = 0; i < numberDevices; i++) { //we need to test if this value is for us: //we grab the mac address of each devices: byte shortAddress[2]; memcpy(shortAddress, data+SHORT_MAC_LEN+2+i*17, 2); //we test if the short address is our address if(shortAddress[0] == _currentShortAddress[0] && shortAddress[1] == _currentShortAddress[1]) { //we grab the replytime wich is for us DW1000.getReceiveTimestamp(myDistantDevice->timeRangeReceived); noteActivity(); _expectedMsgId = POLL; if(!_protocolFailed) { myDistantDevice->timePollSent.setTimestamp(data+SHORT_MAC_LEN+4+17*i); myDistantDevice->timePollAckReceived.setTimestamp(data+SHORT_MAC_LEN+9+17*i); myDistantDevice->timeRangeSent.setTimestamp(data+SHORT_MAC_LEN+14+17*i); // (re-)compute range as two-way ranging is done DW1000Time myTOF; computeRangeAsymmetric(myDistantDevice, &myTOF); // CHOSEN RANGING ALGORITHM float distance = myTOF.getAsMeters(); myDistantDevice->setRXPower(DW1000.getReceivePower()); myDistantDevice->setRange(distance); myDistantDevice->setFPPower(DW1000.getFirstPathPower()); myDistantDevice->setQuality(DW1000.getReceiveQuality()); //we send the range to TAG transmitRangeReport(myDistantDevice); //we have finished our range computation. We send the corresponding handler _lastDistantDevice = myDistantDevice->getIndex(); if(_handleNewRange != 0) { (*_handleNewRange)(); } } else { transmitRangeFailed(myDistantDevice); } return; } } } } else if(_type == TAG) { // get message and parse if(messageType != _expectedMsgId) { // unexpected message, start over again //not needed ? return; _expectedMsgId = POLL_ACK; return; } if(messageType == POLL_ACK) { DW1000.getReceiveTimestamp(myDistantDevice->timePollAckReceived); //we note activity for our device: myDistantDevice->noteActivity(); //in the case the message come from our last device: if(myDistantDevice->getIndex() == _networkDevicesNumber-1) { _expectedMsgId = RANGE_REPORT; //and transmit the next message (range) of the ranging protocole (in broadcast) transmitRange(NULL); } } else if(messageType == RANGE_REPORT) { float curRange; memcpy(&curRange, data+1+SHORT_MAC_LEN, 4); float curRXPower; memcpy(&curRXPower, data+5+SHORT_MAC_LEN, 4); //we have a new range to save ! myDistantDevice->setRange(curRange); myDistantDevice->setRXPower(curRXPower); //We can call our handler ! //we have finished our range computation. We send the corresponding handler _lastDistantDevice = myDistantDevice->getIndex(); if(_handleNewRange != 0) { (*_handleNewRange)(); } } else if(messageType == RANGE_FAILED) { //not needed as we have a timer; return; _expectedMsgId = POLL_ACK; } } } } }
void DW1000RangingClass::loop(){ //we check if needed to reset ! checkForReset(); long time=millis(); if(time-timer>DEFAULT_TIMER_DELAY){ timer=time; timerTick(); } if(_sentAck){ _sentAck = false; int messageType=detectMessageType(data); if(messageType!=POLL_ACK && messageType!= POLL && messageType!=RANGE) return; DW1000Device *myDistantDevice=searchDistantDevice(_lastSentToShortAddress); if(myDistantDevice==0) { //we don't have the short address of the device in memory /* Serial.print("unknown sent: "); Serial.print(_lastSentToShortAddress[0], HEX); Serial.print(":"); Serial.println(_lastSentToShortAddress[1], HEX); */ } //A msg was sent. We launch the ranging protocole when a message was sent if(_type==ANCHOR){ if(messageType == POLL_ACK) { DW1000.getTransmitTimestamp(myDistantDevice->timePollAckSent); } } else if(_type==TAG){ if(messageType == POLL) { DW1000.getTransmitTimestamp(myDistantDevice->timePollSent); //Serial.print("Sent POLL @ "); Serial.println(timePollSent.getAsFloat()); } else if(messageType == RANGE) { DW1000.getTransmitTimestamp(myDistantDevice->timeRangeSent); } } } //check for new received message if(_receivedAck){ _receivedAck=false; //we read the datas from the modules: // get message and parse DW1000.getData(data, LEN_DATA); int messageType=detectMessageType(data); //we have just received a BLINK message from tag if(messageType==BLINK && _type==ANCHOR){ byte address[8]; byte shortAddress[2]; _globalMac.decodeBlinkFrame(data, address, shortAddress); //we crate a new device with th tag DW1000Device myTag(address, shortAddress); if(addNetworkDevices(&myTag)) { Serial.print("blink; 1 device added ! -> "); Serial.print(" short:"); Serial.println(myTag.getShortAddress(), HEX); //we relpy by the transmit ranging init message transmitRangingInit(&myTag); noteActivity(); } _expectedMsgId=POLL; } else if(messageType==RANGING_INIT && _type==TAG){ byte address[2]; _globalMac.decodeLongMACFrame(data, address); //we crate a new device with the anchor DW1000Device myAnchor(address, true); if(addNetworkDevices(&myAnchor, true)) { Serial.print("ranging init; 1 device added ! -> "); Serial.print(" short:"); Serial.println(myAnchor.getShortAddress(), HEX); } //we relpy by the transmit ranging init message //transmitPoll(&myAnchor); noteActivity(); } else { //we have a short mac layer frame ! byte address[2]; _globalMac.decodeShortMACFrame(data, address); //we get the device which correspond to the message which was sent (need to be filtered by MAC address) DW1000Device *myDistantDevice=searchDistantDevice(address); if(myDistantDevice==0) { //we don't have the short address of the device in memory /* Serial.print("unknown: "); Serial.print(address[0], HEX); Serial.print(":"); Serial.println(address[1], HEX); */ return; } //then we proceed to range protocole if(_type==ANCHOR){ if(messageType != _expectedMsgId) { // unexpected message, start over again (except if already POLL) _protocolFailed = true; } if(messageType == POLL) { //Serial.println("receive poll"); // on POLL we (re-)start, so no protocol failure _protocolFailed = false; DW1000.getReceiveTimestamp(myDistantDevice->timePollReceived); //we note activity for our device: myDistantDevice->noteActivity(); //we indicate our next receive message for our ranging protocole _expectedMsgId = RANGE; transmitPollAck(myDistantDevice); noteActivity(); } else if(messageType == RANGE) { DW1000.getReceiveTimestamp(myDistantDevice->timeRangeReceived); noteActivity(); _expectedMsgId = POLL; if(!_protocolFailed) { myDistantDevice->timePollSent.setTimestamp(data+1+SHORT_MAC_LEN); myDistantDevice->timePollAckReceived.setTimestamp(data+6+SHORT_MAC_LEN); myDistantDevice->timeRangeSent.setTimestamp(data+11+SHORT_MAC_LEN); // (re-)compute range as two-way ranging is done DW1000Time myTOF; computeRangeAsymmetric(myDistantDevice, &myTOF); // CHOSEN RANGING ALGORITHM float distance=myTOF.getAsMeters(); myDistantDevice->setRXPower(DW1000.getReceivePower()); myDistantDevice->setRange(distance); myDistantDevice->setFPPower(DW1000.getFirstPathPower()); myDistantDevice->setQuality(DW1000.getReceiveQuality()); //we send the range to TAG transmitRangeReport(myDistantDevice); //we have finished our range computation. We send the corresponding handler if(_handleNewRange != 0) { (*_handleNewRange)(); } } else { transmitRangeFailed(myDistantDevice); } noteActivity(); } } else if(_type==TAG){ // get message and parse if(messageType != _expectedMsgId) { // unexpected message, start over again _expectedMsgId = POLL_ACK; //transmitPoll(myDistantDevice); return; } if(messageType == POLL_ACK) { DW1000.getReceiveTimestamp(myDistantDevice->timePollAckReceived); _expectedMsgId = RANGE_REPORT; //we note activity for our device: myDistantDevice->noteActivity(); //and transmit the next message (range) of the ranging protocole transmitRange(myDistantDevice); } else if(messageType == RANGE_REPORT) { _expectedMsgId = POLL_ACK; float curRange; memcpy(&curRange, data+1+SHORT_MAC_LEN, 4); float curRXPower; memcpy(&curRXPower, data+5+SHORT_MAC_LEN, 4); //we have a new range to save ! myDistantDevice->setRange(curRange); myDistantDevice->setRXPower(curRXPower); //We can call our handler ! if(_handleNewRange != 0){ (*_handleNewRange)(); } } else if(messageType == RANGE_FAILED) { _expectedMsgId = POLL_ACK; } } } } }
void DW1000RangingClass::loop(){ //we check if needed to reset ! checkForReset(); if(_sentAck){ _sentAck = false; //we get the device which correspond to the message which was sent (need to be filtered by MAC address) DW1000Device *myDistantDevice=&_networkDevices[0]; //A msg was sent. We launch the ranging protocole when a message was sent if(_type==ANCHOR){ if(data[0] == POLL_ACK) { DW1000.getTransmitTimestamp((*myDistantDevice).timePollAckSent); noteActivity(); } } else if(_type==TAG){ if(data[0] == POLL) { DW1000.getTransmitTimestamp((*myDistantDevice).timePollSent); //Serial.print("Sent POLL @ "); Serial.println(timePollSent.getAsFloat()); } else if(data[0] == RANGE) { DW1000.getTransmitTimestamp((*myDistantDevice).timeRangeSent); noteActivity(); } } } //check for new received message if(_receivedAck){ _receivedAck=false; //we get the device which correspond to the message which was sent (need to be filtered by MAC address) DW1000Device *myDistantDevice=&_networkDevices[0]; //we read the datas from the modules: // get message and parse DW1000.getData(data, LEN_DATA); //then we proceed to range protocole if(_type==ANCHOR){ if(data[0] != _expectedMsgId) { // unexpected message, start over again (except if already POLL) _protocolFailed = true; } if(data[0] == POLL) { // on POLL we (re-)start, so no protocol failure _protocolFailed = false; DW1000.getReceiveTimestamp((*myDistantDevice).timePollReceived); _expectedMsgId = RANGE; transmitPollAck(); noteActivity(); } else if(data[0] == RANGE) { DW1000.getReceiveTimestamp((*myDistantDevice).timeRangeReceived); _expectedMsgId = POLL; if(!_protocolFailed) { (*myDistantDevice).timePollSent.setTimestamp(data+1); (*myDistantDevice).timePollAckReceived.setTimestamp(data+6); (*myDistantDevice).timeRangeSent.setTimestamp(data+11); // (re-)compute range as two-way ranging is done computeRangeAsymmetric(myDistantDevice); // CHOSEN RANGING ALGORITHM float distance=(*myDistantDevice).timeComputedRange.getAsMeters(); (*myDistantDevice).setRXPower(DW1000.getReceivePower()); float rangeBias=rangeRXCorrection((*myDistantDevice).getRXPower()); (*myDistantDevice).setRange(distance-rangeBias); (*myDistantDevice).setFPPower(DW1000.getFirstPathPower()); (*myDistantDevice).setQuality(DW1000.getReceiveQuality()); //we wend the range to TAG transmitRangeReport(myDistantDevice); //we have finished our range computation. We send the corresponding handler if(_handleNewRange != 0) { (*_handleNewRange)(); } } else { transmitRangeFailed(); } noteActivity(); } } else if(_type==TAG){ // get message and parse if(data[0] != _expectedMsgId) { // unexpected message, start over again //Serial.print("Received wrong message # "); Serial.println(msgId); _expectedMsgId = POLL_ACK; transmitPoll(); return; } if(data[0] == POLL_ACK) { DW1000.getReceiveTimestamp((*myDistantDevice).timePollAckReceived); _expectedMsgId = RANGE_REPORT; transmitRange(myDistantDevice); noteActivity(); } else if(data[0] == RANGE_REPORT) { _expectedMsgId = POLL_ACK; float curRange; memcpy(&curRange, data+1, 4); float curRXPower; memcpy(&curRXPower, data+5, 4); //we have a new range to save ! (*myDistantDevice).setRange(curRange); (*myDistantDevice).setRXPower(curRXPower); //We can call our handler ! if(_handleNewRange != 0){ (*_handleNewRange)(); } //we start again ranging transmitPoll(); noteActivity(); } else if(data[0] == RANGE_FAILED) { _expectedMsgId = POLL_ACK; transmitPoll(); noteActivity(); } } } }