al w / ARQ-radio
Revision:
0:8e06c9b8b7f6
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