micro:bit RSSI fix (#2480)

* read rssi from packet

* updated shims

* fix build

* fix help

* move deprecated function to ts

* some formatting

* restore rssi block

* restory notations

* actually copy bytes

* removing logging code

* simpler wake up code

* comment

* fix build

* bump pxt

* go back to safety

* bump microbit

* restor package.json

* revert jquery v

* use macro

* check length
This commit is contained in:
Peli de Halleux 2019-10-22 08:39:44 -07:00 committed by GitHub
parent 2f0d812fc8
commit f9e9daae18
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 73 additions and 71 deletions

View File

@ -19,7 +19,7 @@
"radio.onReceivedValue": "Registers code to run when the radio receives a key value pair.", "radio.onReceivedValue": "Registers code to run when the radio receives a key value pair.",
"radio.onReceivedValueDeprecated": "Registers code to run when the radio receives a key value pair. Deprecated, use\nonReceivedValue instead.", "radio.onReceivedValueDeprecated": "Registers code to run when the radio receives a key value pair. Deprecated, use\nonReceivedValue instead.",
"radio.raiseEvent": "Sends an event over radio to neigboring devices", "radio.raiseEvent": "Sends an event over radio to neigboring devices",
"radio.readRawPacket": "Takes the next packet from the radio queue and returns its contents in a Buffer", "radio.readRawPacket": "Internal use only. Takes the next packet from the radio queue and returns its contents + RSSI in a Buffer",
"radio.receiveNumber": "Reads the next packet from the radio queue and returns the packet's number\npayload or 0 if the packet did not contain a number.", "radio.receiveNumber": "Reads the next packet from the radio queue and returns the packet's number\npayload or 0 if the packet did not contain a number.",
"radio.receiveString": "Reads the next packet from the radio queue and returns the packet's string\npayload or the empty string if the packet did not contain a string.", "radio.receiveString": "Reads the next packet from the radio queue and returns the packet's string\npayload or the empty string if the packet did not contain a string.",
"radio.receivedBuffer": "Returns the buffer payload from the last packet taken from the radio queue\n(via ``receiveNumber``, ``receiveString``, etc) or the empty string if that\npacket did not contain a string.", "radio.receivedBuffer": "Returns the buffer payload from the last packet taken from the radio queue\n(via ``receiveNumber``, ``receiveString``, etc) or the empty string if that\npacket did not contain a string.",
@ -27,12 +27,12 @@
"radio.receivedPacket": "Returns properties of the last radio packet received.", "radio.receivedPacket": "Returns properties of the last radio packet received.",
"radio.receivedPacket|param|type": "the type of property to retrieve from the last packet", "radio.receivedPacket|param|type": "the type of property to retrieve from the last packet",
"radio.receivedSerial": "Returns the serial number of the sender micro:bit from the last packet taken\nfrom the radio queue (via ``receiveNumber``, ``receiveString``, etc) or 0 if\nthat packet did not send a serial number.", "radio.receivedSerial": "Returns the serial number of the sender micro:bit from the last packet taken\nfrom the radio queue (via ``receiveNumber``, ``receiveString``, etc) or 0 if\nthat packet did not send a serial number.",
"radio.receivedSignalStrength": "Gets the received signal strength indicator (RSSI) from the last packet taken\nfrom the radio queue (via ``receiveNumber``, ``receiveString``, etc). Not supported in simulator.\nnamespace=radio", "radio.receivedSignalStrength": "Gets the received signal strength indicator (RSSI) from the last packet taken\nfrom the radio queue (via ``receiveNumber``, ``receiveString``, etc). Not supported in simulator.",
"radio.receivedString": "Returns the string payload from the last packet taken from the radio queue\n(via ``receiveNumber``, ``receiveString``, etc) or the empty string if that\npacket did not contain a string.", "radio.receivedString": "Returns the string payload from the last packet taken from the radio queue\n(via ``receiveNumber``, ``receiveString``, etc) or the empty string if that\npacket did not contain a string.",
"radio.receivedTime": "Returns the system time of the sender micro:bit at the moment when it sent the\nlast packet taken from the radio queue (via ``receiveNumber``,\n``receiveString``, etc).", "radio.receivedTime": "Returns the system time of the sender micro:bit at the moment when it sent the\nlast packet taken from the radio queue (via ``receiveNumber``,\n``receiveString``, etc).",
"radio.sendBuffer": "Broadcasts a buffer (up to 19 bytes long) along with the device serial number\nand running time to any connected micro:bit in the group.", "radio.sendBuffer": "Broadcasts a buffer (up to 19 bytes long) along with the device serial number\nand running time to any connected micro:bit in the group.",
"radio.sendNumber": "Broadcasts a number over radio to any connected micro:bit in the group.", "radio.sendNumber": "Broadcasts a number over radio to any connected micro:bit in the group.",
"radio.sendRawPacket": "Sends a raw packet through the radio", "radio.sendRawPacket": "Internal use only. Sends a raw packet through the radio (assumes RSSI appened to packet)",
"radio.sendString": "Broadcasts a string along with the device serial number\nand running time to any connected micro:bit in the group.", "radio.sendString": "Broadcasts a string along with the device serial number\nand running time to any connected micro:bit in the group.",
"radio.sendValue": "Broadcasts a name / value pair along with the device serial number\nand running time to any connected micro:bit in the group. The name can\ninclude no more than 8 characters.", "radio.sendValue": "Broadcasts a name / value pair along with the device serial number\nand running time to any connected micro:bit in the group. The name can\ninclude no more than 8 characters.",
"radio.sendValue|param|name": "the field name (max 8 characters), eg: \"name\"", "radio.sendValue|param|name": "the field name (max 8 characters), eg: \"name\"",

View File

@ -31,30 +31,40 @@ namespace radio {
//% help=radio/raise-event //% help=radio/raise-event
void raiseEvent(int src, int value) { void raiseEvent(int src, int value) {
if (radioEnable() != MICROBIT_OK) return; if (radioEnable() != MICROBIT_OK) return;
uBit.radio.event.eventReceived(MicroBitEvent(src, value, CREATE_ONLY)); uBit.radio.event.eventReceived(MicroBitEvent(src, value, CREATE_ONLY));
} }
/** /**
* Takes the next packet from the radio queue and returns its contents in a Buffer * Internal use only. Takes the next packet from the radio queue and returns its contents + RSSI in a Buffer
*/ */
//% help=radio/received-packet //%
Buffer readRawPacket() { Buffer readRawPacket() {
if (radioEnable() != MICROBIT_OK) return mkBuffer(NULL, 0); if (radioEnable() != MICROBIT_OK) return mkBuffer(NULL, 0);
uint8_t buf[32];
int size = uBit.radio.datagram.recv(buf, sizeof(buf)); PacketBuffer p = uBit.radio.datagram.recv();
if (size <= 0) if (p == PacketBuffer::EmptyPacket)
return mkBuffer(NULL, 0); return mkBuffer(NULL, 0);
return mkBuffer(buf, size);
int rssi = p.getRSSI();
uint8_t buf[MICROBIT_RADIO_MAX_PACKET_SIZE + sizeof(int)]; // packet length + rssi
memset(buf, 0, sizeof(buf));
memcpy(buf, p.getBytes(), p.length()); // data
memcpy(buf + MICROBIT_RADIO_MAX_PACKET_SIZE, &rssi, sizeof(int)); // RSSi - assumes Int32LE layout
return mkBuffer(buf, sizeof(buf));
} }
/** /**
* Sends a raw packet through the radio * Internal use only. Sends a raw packet through the radio (assumes RSSI appened to packet)
*/ */
//% advanced=true
//% async //% async
void sendRawPacket(Buffer msg) { void sendRawPacket(Buffer msg) {
if (radioEnable() != MICROBIT_OK || NULL == msg) return; if (radioEnable() != MICROBIT_OK || NULL == msg) return;
uBit.radio.datagram.send(msg->data, msg->length);
// don't send RSSI data; and make sure no buffer underflow
int len = msg->length - sizeof(int);
if (len > 0)
uBit.radio.datagram.send(msg->data, len);
} }
/** /**
@ -66,22 +76,9 @@ namespace radio {
//% deprecated=true //% deprecated=true
void onDataReceived(Action body) { void onDataReceived(Action body) {
if (radioEnable() != MICROBIT_OK) return; if (radioEnable() != MICROBIT_OK) return;
registerWithDal(MICROBIT_ID_RADIO, MICROBIT_RADIO_EVT_DATAGRAM, body);
readRawPacket();
}
/** registerWithDal(MICROBIT_ID_RADIO, MICROBIT_RADIO_EVT_DATAGRAM, body);
* Gets the received signal strength indicator (RSSI) from the last packet taken uBit.radio.datagram.recv(); // wake up read code
* from the radio queue (via ``receiveNumber``, ``receiveString``, etc). Not supported in simulator.
* namespace=radio
*/
//% help=radio/received-signal-strength
//% weight=40
//% blockId=radio_datagram_rssi block="radio received signal strength"
//% deprecated=true
int receivedSignalStrength() {
if (radioEnable() != MICROBIT_OK) return 0;
return uBit.radio.getRSSI();
} }
/** /**
@ -94,6 +91,7 @@ namespace radio {
//% id.min=0 id.max=255 //% id.min=0 id.max=255
void setGroup(int id) { void setGroup(int id) {
if (radioEnable() != MICROBIT_OK) return; if (radioEnable() != MICROBIT_OK) return;
uBit.radio.setGroup(id); uBit.radio.setGroup(id);
} }
@ -108,6 +106,7 @@ namespace radio {
//% advanced=true //% advanced=true
void setTransmitPower(int power) { void setTransmitPower(int power) {
if (radioEnable() != MICROBIT_OK) return; if (radioEnable() != MICROBIT_OK) return;
uBit.radio.setTransmitPower(power); uBit.radio.setTransmitPower(power);
} }
} }

View File

@ -55,37 +55,37 @@ namespace radio {
function init() { function init() {
if (initialized) return; if (initialized) return;
initialized = true; initialized = true;
onDataReceived(handleDataReceived);
}
onDataReceived(() => { function handleDataReceived() {
let buffer: Buffer = readRawPacket(); let buffer: Buffer = readRawPacket();
while (buffer && buffer.length) { while (buffer && buffer.length) {
lastPacket = RadioPacket.getPacket(buffer); lastPacket = RadioPacket.getPacket(buffer);
lastPacket.signal = receivedSignalStrength(); switch (lastPacket.packetType) {
switch (lastPacket.packetType) { case PACKET_TYPE_NUMBER:
case PACKET_TYPE_NUMBER: case PACKET_TYPE_DOUBLE:
case PACKET_TYPE_DOUBLE: if (onReceivedNumberHandler)
if (onReceivedNumberHandler) onReceivedNumberHandler(lastPacket.numberPayload);
onReceivedNumberHandler(lastPacket.numberPayload); break;
break; case PACKET_TYPE_VALUE:
case PACKET_TYPE_VALUE: case PACKET_TYPE_DOUBLE_VALUE:
case PACKET_TYPE_DOUBLE_VALUE: if (onReceivedValueHandler)
if (onReceivedValueHandler) onReceivedValueHandler(lastPacket.stringPayload, lastPacket.numberPayload);
onReceivedValueHandler(lastPacket.stringPayload, lastPacket.numberPayload); break;
break; case PACKET_TYPE_BUFFER:
case PACKET_TYPE_BUFFER: if (onReceivedBufferHandler)
if(onReceivedBufferHandler) onReceivedBufferHandler(lastPacket.bufferPayload);
onReceivedBufferHandler(lastPacket.bufferPayload); break;
break; case PACKET_TYPE_STRING:
case PACKET_TYPE_STRING: if (onReceivedStringHandler)
if (onReceivedStringHandler) onReceivedStringHandler(lastPacket.stringPayload);
onReceivedStringHandler(lastPacket.stringPayload); break;
break; }
}
// read next packet if any // read next packet if any
buffer = readRawPacket(); buffer = readRawPacket();
} }
})
} }
/** /**
@ -162,6 +162,7 @@ namespace radio {
export class RadioPacket { export class RadioPacket {
public static getPacket(data: Buffer) { public static getPacket(data: Buffer) {
// last 4 bytes is RSSi
return new RadioPacket(data); return new RadioPacket(data);
} }
@ -172,10 +173,12 @@ namespace radio {
} }
private constructor(public readonly data?: Buffer) { private constructor(public readonly data?: Buffer) {
if (!data) this.data = control.createBuffer(32); if (!data) this.data = control.createBuffer(DAL.MICROBIT_RADIO_MAX_PACKET_SIZE + 4);
} }
public signal: number; get signal() {
return this.data.getNumber(NumberFormat.Int32LE, this.data.length - 4);
}
get packetType() { get packetType() {
return this.data[0]; return this.data[0];
@ -358,6 +361,18 @@ namespace radio {
transmittingSerial = transmit; transmittingSerial = transmit;
} }
/**
* Gets the received signal strength indicator (RSSI) from the last packet taken
* from the radio queue (via ``receiveNumber``, ``receiveString``, etc). Not supported in simulator.
*/
//% help=radio/received-signal-strength
//% weight=40
//% blockId=radio_datagram_rssi block="radio received signal strength"
//% deprecated=true blockHidden=true
export function receivedSignalStrength(): number {
return lastPacket ? lastPacket.signal : 0;
}
export function writeToSerial(packet: RadioPacket) { export function writeToSerial(packet: RadioPacket) {
serial.writeString("{"); serial.writeString("{");
serial.writeString("\"t\":"); serial.writeString("\"t\":");

18
libs/radio/shims.d.ts vendored
View File

@ -16,15 +16,14 @@ declare namespace radio {
function raiseEvent(src: int32, value: int32): void; function raiseEvent(src: int32, value: int32): void;
/** /**
* Takes the next packet from the radio queue and returns its contents in a Buffer * Internal use only. Takes the next packet from the radio queue and returns its contents + RSSI in a Buffer
*/ */
//% help=radio/received-packet shim=radio::readRawPacket //% shim=radio::readRawPacket
function readRawPacket(): Buffer; function readRawPacket(): Buffer;
/** /**
* Sends a raw packet through the radio * Internal use only. Sends a raw packet through the radio (assumes RSSI appened to packet)
*/ */
//% advanced=true
//% async shim=radio::sendRawPacket //% async shim=radio::sendRawPacket
function sendRawPacket(msg: Buffer): void; function sendRawPacket(msg: Buffer): void;
@ -37,17 +36,6 @@ declare namespace radio {
//% deprecated=true shim=radio::onDataReceived //% deprecated=true shim=radio::onDataReceived
function onDataReceived(body: () => void): void; function onDataReceived(body: () => void): void;
/**
* Gets the received signal strength indicator (RSSI) from the last packet taken
* from the radio queue (via ``receiveNumber``, ``receiveString``, etc). Not supported in simulator.
* namespace=radio
*/
//% help=radio/received-signal-strength
//% weight=40
//% blockId=radio_datagram_rssi block="radio received signal strength"
//% deprecated=true shim=radio::receivedSignalStrength
function receivedSignalStrength(): int32;
/** /**
* Sets the group id for radio communications. A micro:bit can only listen to one group ID at any time. * Sets the group id for radio communications. A micro:bit can only listen to one group ID at any time.
* @param id the group id between ``0`` and ``255``, eg: 1 * @param id the group id between ``0`` and ``255``, eg: 1