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.
arq.cpp
- Committer:
- quagga
- Date:
- 2021-05-25
- Revision:
- 0:8e06c9b8b7f6
File content as of revision 0:8e06c9b8b7f6:
#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();
}