al w / ARQ-radio

Files at this revision

API Documentation at this revision

Comitter:
quagga
Date:
Tue May 25 17:45:26 2021 +0000
Commit message:
arq radio class; todo- crc check on message

Changed in this revision

arq.cpp Show annotated file Show diff for this revision Revisions of this file
arq.h Show annotated file Show diff for this revision Revisions of this file
diff -r 000000000000 -r 8e06c9b8b7f6 arq.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/arq.cpp	Tue May 25 17:45:26 2021 +0000
@@ -0,0 +1,176 @@
+#include"arq.h"
+
+Arq::Arq(MicroBit* bit)
+{
+    uBit=bit;
+    //uBit->serial.send("Arq::Arq(MicroBit *)\n");
+    power=0;
+    timeout=5000;
+    maxtries=10;
+    mintries=1;
+    tries=0;
+    rssi=255;
+    min_rssi=70;
+    uBit->radio.setTransmitPower(power);
+}
+
+void Arq::off()
+{
+    //uBit->serial.send("void Arq::off()\n");
+    uBit->messageBus.ignore(MICROBIT_ID_RADIO, MICROBIT_RADIO_EVT_DATAGRAM, this, &Arq::listen);
+    uBit->radio.disable();
+}
+
+void Arq::listen(MicroBitEvent e)
+{
+    //uBit->serial.send("Arq::receive(MicroBitEvent)\n");
+    //message received
+    rssi=uBit->radio.getRSSI();
+    PacketBuffer s=uBit->radio.datagram.recv();
+    if (s[0]==0) //power_test
+    {
+        #ifdef ARQ_DEBUG
+        int pow=(int)s[1];
+        uBit->serial.printf("received POWER_TEST at %d\n",pow);
+        #endif
+        received_power=s[1];
+        MicroBitEvent(ARQ_ID,ARQ_POW_RECVD_EVT);
+    }
+    else //message
+    {
+        //set packet to received packet buffer minus 1st byte
+        packet = PacketBuffer(s.length()-1);
+        for (int i=1;i<s.length();i++){packet[i-1]=s[i];}
+        #ifdef ARQ_DEBUG
+        //uBit->serial.send(packet); //send packet to serial
+        #endif
+        MicroBitEvent(ARQ_ID,ARQ_MSG_RECVD_EVT);
+    }
+    s=PacketBuffer(1); //send ACK
+    s[0]=(char) rssi;
+    s[0] |= 1UL << 7; // set bit 8 for ACK
+    uBit->radio.datagram.send(s);
+    #ifdef ARQ_DEBUG
+    uBit->serial.printf("Sending ACK with %d rssi\n",rssi);
+    #endif
+}
+
+void Arq::receive()
+{
+    uBit->messageBus.listen(MICROBIT_ID_RADIO, MICROBIT_RADIO_EVT_DATAGRAM, this, &Arq::listen);
+    uBit->radio.setTransmitPower(7); //max power for ACK
+    uBit->radio.enable();
+}
+
+void Arq::send(PacketBuffer packet)
+{
+    //uBit->serial.send("void Arq::send()\n");
+    uBit->radio.enable();
+
+    int t,dt;
+    int count=0;
+    bool ack=false;
+    
+    while (count<maxtries)
+    {
+        //clear dataReady queue
+        while (uBit->radio.dataReady()>0){uBit->radio.recv();}
+        uBit->radio.datagram.send(packet);
+        dt=0;
+        t=system_timer_current_time_us();
+        while (dt<timeout)
+        {
+            dt=system_timer_current_time_us()-t;
+            if (uBit->radio.dataReady()>0){ack=true;break;}
+        }
+        if (ack){break;}
+        count++;
+    }
+    tries=count;
+    if (ack)
+    {
+        //PacketBuffer s=uBit->radio.datagram.recv();
+        FrameBuffer *s=uBit->radio.recv();
+        //get rssi reported from receiver
+        rssi=(int)((s->payload[0])^128);
+        delete s;
+        #ifdef ARQ_DEBUG
+        uBit->serial.printf("%d rssi reported from ACK ",rssi);
+        uBit->serial.printf("after - %d tries\n",tries);
+        uBit->serial.printf("after - %d microseconds\n",dt);
+        #endif
+        if (packet[0]==0){MicroBitEvent(ARQ_ID,ARQ_POW_ACK_RECVD);}
+        else {MicroBitEvent(ARQ_ID,ARQ_MSG_ACK_RECVD);}
+    }
+
+    else
+    {
+        #ifdef ARQ_DEBUG
+        uBit->serial.printf("Send Failed!\n"); 
+        #endif
+        if (packet[0]==0){MicroBitEvent(ARQ_ID_POW_SEND_FAIL);}
+        else {MicroBitEvent(ARQ_ID,ARQ_MSG_SEND_FAIL);}
+    }
+    
+    //power check?
+    if (packet[0]!=0) //make sure not power_test to avoid infinite loop
+    {
+        if (tries>(mintries-1)){this->incPower();} //if too many attempts power up
+        else if (rssi<min_rssi){this->decPower();} //if rssi high reduce power
+    }
+    
+    uBit->radio.disable();
+}
+
+
+void Arq::incPower()
+{
+    //uBit->serial.send("Arq::incPower()\n");
+    //send message if ack not received up power
+    uBit->radio.enable();
+    while (power<7)
+    {
+        //send message
+        PacketBuffer s(2);
+        s[0]=0;
+        s[1]=(char)power;
+        this->send(s);
+        if (tries<mintries){break;}
+        power++;
+        uBit->radio.setTransmitPower(power);
+        #ifdef ARQ_DEBUG
+        uBit->serial.printf("Power set to %d\n",power);
+        #endif
+    }
+    uBit->radio.disable();
+}
+
+void Arq::decPower()
+{
+    //uBit->serial.send("Arq::decPower()\n");
+    uBit->radio.enable();
+    while (power>0)
+    {
+        //send message
+        PacketBuffer s(2);
+        s[0]=0;
+        s[1]=(char) power;
+        //try lower power
+        power--;
+        uBit->radio.setTransmitPower(power);
+        this->send(s);
+        if (tries>mintries)//failed at this power,increase power and break
+        {
+            if (power<7)
+            {
+                power++;
+                uBit->radio.setTransmitPower(power);
+                #ifdef ARQ_DEBUG
+                uBit->serial.printf("Power set to %d\n",power);
+                #endif
+            }
+            break;
+        }
+    }
+    uBit->radio.disable();
+}
\ No newline at end of file
diff -r 000000000000 -r 8e06c9b8b7f6 arq.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/arq.h	Tue May 25 17:45:26 2021 +0000
@@ -0,0 +1,54 @@
+#include"MicroBit.h"
+//#define ARQ_DEBUG
+
+#define ARQ_ID              4000
+#define ARQ_MSG_RECVD_EVT   1
+#define ARQ_MSG_SEND_FAIL   2
+#define ARQ_MSG_ACK_RECVD   3
+#define ARQ_POW_RECVD_EVT   4
+#define ARQ_POW_SEND_FAIL   5
+#define ARQ_POW_ACK_RECVD   6
+
+#ifndef ARQ_H
+#define ARQ_H
+
+class Arq
+{
+    public:
+    unsigned char power;    //power of transmitter
+    unsigned char received_power;
+    unsigned int timeout;   //time after send with no ACK before resend in microseconds CURRENTLY IRRELEVANT!! 
+    unsigned int maxtries;  //max number of attempts at sending before give up :( (default 10)
+    unsigned int mintries;  //min number of attempts allowable (default 1)
+    unsigned int tries;     //number of attempts at last go
+    unsigned int rssi;      //rssi from last ACK received i.e. rssi reported by receiver
+    unsigned int min_rssi;  //rssi below which power can be reduced (default 70)
+
+    MicroBit *uBit;
+    PacketBuffer packet;
+    
+    Arq(MicroBit *bit);
+    ~Arq(){};
+    
+    void off();
+    void receive();
+    void listen(MicroBitEvent e);
+    void send(PacketBuffer packet);
+
+    void incPower();
+    void decPower();
+};
+
+#endif
+
+//1st byte ACK,POWER_TEST or MESSAGE if ACK, RSSI of RECEIVED MESSAGE ALSO
+//128   64   32   16   8   4   2   1
+//  1    1    1    0   0   0   0   0  - ACK  -98 RSSI
+//  1    0    1    1   0   0   0   1  - ACK  -49 RSSI
+//  0    0    0    0   0   0   0   0  - POWER_TEST
+//  0    1    1    1   1   1   1   1  - MESSAGE
+
+//if POWER_TEST 2nd byte is power
+//if MESSAGE 2nd byte is start of message packet[1]
+
+ 
\ No newline at end of file