Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of GA-Berkay_Alex by
Revision 4:120ff05a7c27, committed 2018-02-28
- Comitter:
- bberabi
- Date:
- Wed Feb 28 17:06:22 2018 +0000
- Parent:
- 3:8bee1711d186
- Commit message:
- GA Final code with comments
Changed in this revision
--- a/PC/PC.cpp Wed Feb 28 16:10:21 2018 +0000
+++ b/PC/PC.cpp Wed Feb 28 17:06:22 2018 +0000
@@ -22,27 +22,23 @@
printf("\x1B[%d;%dH", Zeile + 1, Spalte + 1);
}
+//This fufnction enable reading strings from matlab.
void PC::readcommand(void (*executer)(char*))
{
- //printf("Reads");
- //while(1){
- char input = getc();
- //printf("%c", input); // get the character from serial bus
- //printf("\x1B[1K");
- //printf("-");
+
+ char input = getc(); //get character from the serial bus
- if(input == '\r') {
- // if return was pressed, the command must be executed
+ if(input == '\r') { // \r is our end of command character when this shows up, command will be executed !
+
this->command[command_char_count] = '\0';
executer(&command[0]);
this->command_char_count = 0; // reset command
this->command[command_char_count] = '\0';
// break;
- } else if (command_char_count < COMMAND_MAX_LENGHT) {
+ } else if (command_char_count < COMMAND_MAX_LENGHT) { //wait for other characters
// printf("Debug Point 4");
this->command[command_char_count] = input;
- //printf(command);
this->command_char_count++;
}
--- a/main_minimal.cpp Wed Feb 28 16:10:21 2018 +0000
+++ b/main_minimal.cpp Wed Feb 28 17:06:22 2018 +0000
@@ -43,7 +43,7 @@
BusIn adressInput(PA_9,PA_8,PB_10,PB_4,PB_5,PB_3,PA_10); // first seven 7 bit for ID settings, most left bit = most significant bit
PC pc(USBTX, USBRX, 921600); // USB UART Terminal
-DigitalIn anchorInput(PC_7); // usage of last bit as deciding bit for: anchor or beacon
+DigitalIn anchorInput(PC_7); // usage of last bit as deciding bit for: anchor or beacon (most right bit on chip !)
Watchdog wdt = Watchdog();
BeaconNode beaconNode(decaWave);
AnchorNode anchorNode(decaWave);
@@ -71,10 +71,12 @@
//modeInput.mode(PullDown);
wait_ms(50);
+ //you can google bit masking for details
baseStationNode.setAddress(adressInput & adressInput.mask());
anchorNode.setAddress(adressInput & adressInput.mask());
beaconNode.setAddress(adressInput & adressInput.mask());
+ //if adress == 15
if((adressInput & adressInput.mask()) == BASE_STATION_ADDR){
node = &baseStationNode;
pc.printf("This node is the Base Station, Adress: %d \r\n \r\n \r\n", node->getAddress());
@@ -101,7 +103,7 @@
char command_str[30];
while(1) {
-
+ //all chips stay in this while loop while listening, when they get a frame they process it and then come back here again !
// Choose between what to execte based on whether this device is a:
// BEACON
// BASESTATION
@@ -127,12 +129,12 @@
wait_ms(8);
}
wdt.kick();
+ //after processing, tag is resetted
}
else if (node->isBaseStation()){
// EXECUTE THIS IF A BASE STATION
pc.readcommand(executeOrder);
- //wdt.kick();
}
else { // All Anchor Action is in the Interrupt functions!
// EXECUTE THIS IF AN ANCHOR
@@ -148,27 +150,29 @@
void executeOrder(char* command){
- int repetitions = command[3]*100 + command[4]*10 + command[5] - 5328;
+ int repetitions = command[3]*100 + command[4]*10 + command[5] - 5328; //the number 5328 come from ascii
//uint8_t dest1 = command[7] - 48;
- uint8_t dest2 = command[8] - 48;
+ uint8_t dest2 = command[8] - 48; // -48 comes from ascii
uint8_t dest3 = command[9] - 48;
uint8_t dest1=0;
+
- if(command[7] == 0 && command[8] == 0)
+ if(command[7] == 0 && command[8] == 0) //anchor id in command has is 1 digit number for example 008
{
dest1 = command[9] - 48;
}
- else if (command[7] == 0 && command[8] != 0)
+ else if (command[7] == 0 && command[8] != 0) //anchor id is 2 digit number for example 017
{
dest1 = command[8] * 10 + command[9] - 528;
}
- else if (command[7] != 0 && command[8] != 0)
+ else if (command[7] != 0 && command[8] != 0) //anchor id is 3 digit number: 123
{
dest1 = command[7] * 100 + command[8] * 10 + command[9] - 5328;
}
+ //again all offsets comes from ascii
if (strncmp(command, "reset", 5) == 0){ // This command is implemented in order to be able to reset BaseStation from Matlab.
wdt.kick(); // Set up WatchDog
@@ -179,11 +183,11 @@
baseStationNode.sendOrder(0,dest1,RANGE_INT,repetitions, Node::BASE_ORDER);
// pc.print("Mode: Range interval \r\n");
}
- else if (strncmp(command, "all", 3) == 0){
+ else if (strncmp(command, "all", 3) == 0){ //range all
baseStationNode.sendOrder(0, NOT_USED, RANGE_ALL, repetitions, Node::BASE_ORDER);
// pc.printf("Mode: Range all \r\n");
}
- else if (strncmp(command, "one", 3) == 0){
+ else if (strncmp(command, "one", 3) == 0){ //range one
@@ -198,7 +202,7 @@
}
}
- else if (strncmp(command, "bea", 3) == 0){
+ else if (strncmp(command, "bea", 3) == 0){ //makes an antenna tag
if(dest1 < 15)
baseStationNode.sendOrder(dest1, NOT_USED, BECOME_BEACON, NOT_USED, Node::SWITCH_TYPE);
else
@@ -206,14 +210,22 @@
}
- else if (strncmp(command, "anc", 3) == 0){
- if(dest1 < 15)
+ else if (strncmp(command, "anc", 3) == 0){ //makes an antenna anchor
+ if(dest1 < 15) //that should be if dest1 != 0 since we have 128 anchors right now
baseStationNode.sendOrder(dest1, NOT_USED, BECOME_ANCHOR, NOT_USED, Node::SWITCH_TYPE);
else
baseStationNode.sendOrder(0, NOT_USED, BECOME_ANCHOR, NOT_USED, Node::SWITCH_TYPE);
}
- else if (strncmp(command, "tri", 3) == 0){
+ else if (strncmp(command, "tri", 3) == 0){ //makes a trilateration but does not work anymore since in our project we only use
+ // one destination(dest1). the command and the code should be changed so that 3 destination can be given where all of them can be a 3 digit number ! in our code
+ // tri001-123 would not work since we take dest1 = 123 as coded above. where actually tri001-123 a triangulation between ancors 1,2,3 sybolizes
+
+ //ideally one should extend the command and the code like this:
+ //action(3 chars) repetitions(3chars) - dest1(3 chars) - dest2(3 chars) - dest3(3 chars) so that every action could work indepently, we ignored tri since we did ni=ot need it in our project
+ //for example one002-121-000-000 == range with anchor 121 2 time
+ //tri002-121-004-056 == triangulation between anchors 121 4 and 56
+
// Switch them in correct modes (should already be the case)
baseStationNode.sendOrder(dest1, NOT_USED, BECOME_BEACON, NOT_USED, Node::SWITCH_TYPE);
baseStationNode.sendOrder(dest2, NOT_USED, BECOME_ANCHOR, NOT_USED, Node::SWITCH_TYPE);
--- a/nodes/nodes.cpp Wed Feb 28 16:10:21 2018 +0000
+++ b/nodes/nodes.cpp Wed Feb 28 17:06:22 2018 +0000
@@ -29,22 +29,26 @@
//------- BeaconNode Class -------------------
+
+//This is the class for the Tag !
+
BeaconNode::BeaconNode(DecaWave& DW) : Node(DW) {
- Anchor = false;
+ Anchor = false; // since it is a tag
for (int i = 0; i < 3; i++)
acknowledgement[i] = true;
- LocalTimer.start();
+ LocalTimer.start(); //starts the timer of the tag.
mode=0;
}
#pragma Otime // Compiler optimize Runtime at the cost of image size
// Two Way Ranging Actions when Frame was received
+//a Frame is basically a message.
void BeaconNode::callbackRX(uint64_t RxTime) {
//pc.printf("Got a frame, adress: %d source: %d \r\n", receivedFrame.destination, receivedFrame.source);
- if (receivedFrame.destination == address){
+ if (receivedFrame.destination == address){ //if id of the package is the same as the id of the anchor to which the tag was communicating
switch (receivedFrame.type) {
- case SWITCH_TYPE:
+ case SWITCH_TYPE: //base station can change the type of an antenna, making an anchor tag or making a tag anchor
sendBaseAck();
if((receivedFrame.signedTime >> 24) == BECOME_BEACON){
pc.printf("\r\n \r\n ---This Node is already a beacon ---\r\n \r\n");
@@ -55,13 +59,13 @@
}
break;
- case BASE_ORDER:
- repetitions = receivedFrame.signedTime&0xffff;
+ case BASE_ORDER: // tag received an order from base station
+ repetitions = receivedFrame.signedTime&0xffff;
mode = receivedFrame.signedTime >> 24;
destination = (receivedFrame.signedTime&0xff0000) >> 16;
- sendBaseAck();
+ sendBaseAck(); //send an acknowledgement to base that message is received
break;
- case ANCHOR_RESPONSE:
+ case ANCHOR_RESPONSE: //tag was measuring distance to an anchor, and respond from anchor came
{
sendAnswer(receivedFrame.source, BEACON_RESPONSE);
senderTimestamps[receivedFrame.source][1] = RxTime; //Save the second timestamp on the sending node/beacon (T_rr)
@@ -135,7 +139,12 @@
*/
void BeaconNode::requestRanging(uint8_t destination) {
if(noRec[destination] <= MAX_TRIES){
- pc.printf(" max try %d\n\r",MAX_TRIES);
+
+ //norec array containg for each id(index) how many times it was tried to contact that anchor.
+ //for example if tag has tried to contact anchor 5 3 times, noRec[5] = 3 !
+ //MAX_TRIES can be changed at nodex.h
+
+ // pc.printf(" max try %d\n\r",MAX_TRIES);
float time_before = LocalTimer.read();
while(!acknowledgement[2] && LocalTimer.read() < time_before + 0.0025f); // Wait until previous StreamFrame is sent
@@ -143,18 +152,18 @@
acknowledgement[0] = false;
acknowledgement[1] = false;
acknowledgement[2] = false;
- time_before = LocalTimer.read();
+ time_before = LocalTimer.read(); //start time t0
sendPingFrame(destination);
while(!acknowledgement[1] && (LocalTimer.read() < time_before + 0.0025f + 0.003f*acknowledgement[0])); // One Ranging normaly takes less than 1.5 miliseconds
- if(acknowledgement[1]){
+ if(acknowledgement[1]){ //measurement is done
distances[destination] = calibratedDistance(destination);
noRec[destination] = 0;
// Stream Data to Basestation
sendStreamFrame(destination);
- } else {
+ } else { //maesurement was not succesfull
//acknowledgement[1]=1;
distances[destination] = -10;
noRec[destination] = 0;
@@ -169,22 +178,27 @@
#pragma Otime // Compiler optimize Runtime at the cost of image size
inline float BeaconNode::calibratedDistance(uint8_t destination) {
+ //the error of two way ranging also depends on how long the distance is. We have tried to calibrate these errors.
+ //the numbers are found according to our measurements and test.
+ //PLEASE NOTE THAT THESE CALIBRATIONS MIGHT BE DONE WISELY IN ORDER TO INCREASE ACCURANCY !
+
float rawDistance = (tofs[destination] * 300 * TIMEUNITS_TO_US / 4);
//float correctDistance = rawDistance + dwt_getrangebias(7, rawDistance, DWT_PRF_64M);
//if(rawDistance <= 8.458)
// rawDistance -= 0.0541*rawDistance; // Correction Term 22-03-2017
//else
- //if(rawDistance >= 22.7)
- // rawDistance += -0.0004*rawDistance - 0.3971;
- //else if (rawDistance >= 14.3)
- // rawDistance += -0.0015*rawDistance - 0.372;
- //else if (rawDistance >= 8)
- // rawDistance += -0.0029*rawDistance - 0.352;
- //else if (rawDistance >= 3.93)
- // rawDistance += 0.001*rawDistance - 0.370;
- //else
- // rawDistance += -0.0235*rawDistance - 0.273;
+
+ if(rawDistance >= 22.7)
+ rawDistance += -0.0004*rawDistance - 0.3971;
+ else if (rawDistance >= 14.3)
+ rawDistance += -0.0015*rawDistance - 0.372;
+ else if (rawDistance >= 8)
+ rawDistance += -0.0029*rawDistance - 0.352;
+ else if (rawDistance >= 3.93)
+ rawDistance += 0.001*rawDistance - 0.370;
+ else
+ rawDistance += -0.0235*rawDistance - 0.273;
//else if (rawDistance >= 3)
// rawDistance += 0.0004*rawDistance - 0.5556
@@ -217,6 +231,7 @@
#pragma Otime // Compiler optimize Runtime at the cost of image size
void BeaconNode::requestRangingAll() {
+ //ADRESSES_COUNT can be changed in nodes.h !
for (int i = 0; i < ADRESSES_COUNT; i++) { // Request ranging to all anchors
if(i != address){
requestRanging(i);
@@ -226,6 +241,8 @@
}
}
void BeaconNode::requestRangingInt(uint8_t from,uint8_t to) {
+ //measures distances to anhors with id in interval [from,to]
+ //------------- Unfourtunately, it does not work properly, this case needs to be debugged !!! ---------
for (int i=from; i <= to; i++){
if (i!= address) {
requestRanging(i);
@@ -319,7 +336,7 @@
return destination;
}
-void BeaconNode::clearRec(){
+void BeaconNode::clearRec(){ //the fufnction clears the noRec array !
for(int j = 0; j < ADRESSES_COUNT; j++)
noRec[j] = 0;
}
@@ -327,7 +344,7 @@
//------- AnchorNode Class -------------------
AnchorNode::AnchorNode(DecaWave& DW) : Node(DW) {
- Anchor = true;
+ Anchor = true; //Since it is an anchor
}
#pragma Otime // Compiler optimize Runtime at the cost of image size
@@ -337,7 +354,7 @@
// if(!isBaseStation()){
if (receivedFrame.destination == address){
switch (receivedFrame.type) {
- case SWITCH_TYPE:
+ case SWITCH_TYPE: //as explained in beaconnode class
sendBaseAck();
if((receivedFrame.signedTime >> 24) == BECOME_BEACON){
node = &beaconNode;
@@ -347,12 +364,12 @@
pc.printf("\r\n \r\n ---This Node is already an anchor ---\r\n \r\n");
}
break;
- case PING:
+ case PING:
sendAnswer(receivedFrame.source, ANCHOR_RESPONSE);
receiverTimestamps[receivedFrame.source][0] = RxTime; //Save the first timestamp on the receiving node/anchor (T_rp)
//dw.turnonrx();
break;
- case BEACON_RESPONSE:
+ case BEACON_RESPONSE:
{
receiverTimestamps[receivedFrame.source][2] = RxTime; //Save the third timestamp on the receiving node/anchor (T_rf)
correctReceiverTimestamps(receivedFrame.source); //Correct the timestamps for the case of a counter overflow
@@ -364,7 +381,7 @@
break;
}
default :
- dw.turnonrx();
+ dw.turnonrx(); //turn on listening mode
break;
}
}
@@ -392,12 +409,12 @@
#pragma Otime // Compiler optimize Runtime at the cost of image size
-void AnchorNode::sendBaseAck() {
+void AnchorNode::sendBaseAck() { //send base ack that the order is received
rangingFrame.source = address;
rangingFrame.destination = BASE_STATION_ADDR;
rangingFrame.type = BASE_ORDER_ACK;
//dw.sendFrame((uint8_t*)&rangingFrame, sizeof(rangingFrame));
- dw.sendFrame((uint8_t*)&rangingFrame, sizeof(rangingFrame), 0, 0);
+ dw.sendFrame((uint8_t*)&rangingFrame, sizeof(rangingFrame), 0, 0); //function for sending messages(frames)
}
@@ -450,6 +467,7 @@
//------- BaseStationNode Class -------------------
+
BaseStationNode::BaseStationNode(DecaWave& DW) : Node(DW) {
Anchor = false;
LocalTimer.start();
@@ -469,14 +487,14 @@
//pc.printf("Got a frame, adress: %d source: %d \r\n", receivedStreamFrame.destination, receivedStreamFrame.source);
if (receivedStreamFrame.destination == address){
switch(receivedStreamFrame.type){
- case STREAM_TO_BASE:
+ case STREAM_TO_BASE: //send the received string from tag to the matlab with pc.printf
//pc.printf("#%d to #%d %f(%f) \r\n", receivedStreamFrame.source, receivedStreamFrame.anchor_adress, receivedStreamFrame.distance, receivedStreamFrame.signalStrength);
pc.printf("#%03d/#%03d/%+011.6f/%+011.6f/%+011.6f/ \r\n", receivedStreamFrame.source, receivedStreamFrame.anchor_adress, receivedStreamFrame.distance, receivedStreamFrame.signalStrength, receivedStreamFrame.FPLevel/*dw.getFPLevel()*/);
break;
case BASE_ORDER_ACK:
- ack = true;
+ ack = true; // so that base station knows order was received
break;
default:
@@ -505,7 +523,7 @@
void BaseStationNode::sendOrder(uint8_t beacon_destination, uint8_t anchor_destination, uint8_t action, uint16_t repetitions, uint8_t type) {
ExtendedRangingFrame orderFrame;
ack = false;
-
+ //the function is used to send orders one has to create and order frame
orderFrame.source = address;
orderFrame.destination = beacon_destination;
orderFrame.type = type;
--- a/nodes/nodes.h Wed Feb 28 16:10:21 2018 +0000 +++ b/nodes/nodes.h Wed Feb 28 17:06:22 2018 +0000 @@ -14,11 +14,11 @@ #define TIMEUNITS_TO_US (1/(128*499.2)) // conversion between the decawave timeunits (ca 15.65ps) to microseconds. #define US_TO_TIMEUNITS (128*499.2) // conversion between microseconds to the decawave timeunits (ca 15.65ps). #define MMRANGING_2POWER40 1099511627776 // decimal value of 2^40 to correct timeroverflow between timestamps -#define ADRESSES_COUNT 128 // Defines the Adress Space that is covered when Ranging for all +#define ADRESSES_COUNT 128 // Defines the Adress Space that is covered when Ranging for all, it is always number of possible anchors + 1 //static int ADRESSES_COUNT=1; // Adress Space: 0 - (ADRESSES_COUNT - 1) #define MAX_TRIES 0 // Number of times a Anchor is pinged until determined it is not in range -#define BASE_STATION_ADDR 15 // Defines the Adress of the Base Station (reserved Adress) +#define BASE_STATION_ADDR 15 // Defines the Adress of the Base Station (reserved Adress) // Constants for Base_Orders #define RANGE_ALL 2
