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.
Diff: arq.cpp
- 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