diff --git a/libs/radio/_locales/radio-jsdoc-strings.json b/libs/radio/_locales/radio-jsdoc-strings.json index f33671f6..316f6e51 100644 --- a/libs/radio/_locales/radio-jsdoc-strings.json +++ b/libs/radio/_locales/radio-jsdoc-strings.json @@ -19,7 +19,7 @@ "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.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.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.", @@ -27,12 +27,12 @@ "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.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.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.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.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\"", diff --git a/libs/radio/radio.cpp b/libs/radio/radio.cpp index 6135769d..bda09f17 100644 --- a/libs/radio/radio.cpp +++ b/libs/radio/radio.cpp @@ -31,30 +31,40 @@ namespace radio { //% help=radio/raise-event void raiseEvent(int src, int value) { if (radioEnable() != MICROBIT_OK) return; + 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() { if (radioEnable() != MICROBIT_OK) return mkBuffer(NULL, 0); - uint8_t buf[32]; - int size = uBit.radio.datagram.recv(buf, sizeof(buf)); - if (size <= 0) + + PacketBuffer p = uBit.radio.datagram.recv(); + if (p == PacketBuffer::EmptyPacket) 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 void sendRawPacket(Buffer msg) { 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 void onDataReceived(Action body) { if (radioEnable() != MICROBIT_OK) return; - registerWithDal(MICROBIT_ID_RADIO, MICROBIT_RADIO_EVT_DATAGRAM, body); - readRawPacket(); - } - /** - * 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 - int receivedSignalStrength() { - if (radioEnable() != MICROBIT_OK) return 0; - return uBit.radio.getRSSI(); + registerWithDal(MICROBIT_ID_RADIO, MICROBIT_RADIO_EVT_DATAGRAM, body); + uBit.radio.datagram.recv(); // wake up read code } /** @@ -94,6 +91,7 @@ namespace radio { //% id.min=0 id.max=255 void setGroup(int id) { if (radioEnable() != MICROBIT_OK) return; + uBit.radio.setGroup(id); } @@ -108,6 +106,7 @@ namespace radio { //% advanced=true void setTransmitPower(int power) { if (radioEnable() != MICROBIT_OK) return; + uBit.radio.setTransmitPower(power); } } diff --git a/libs/radio/radio.ts b/libs/radio/radio.ts index 5b2e98b1..2f564e8c 100644 --- a/libs/radio/radio.ts +++ b/libs/radio/radio.ts @@ -55,37 +55,37 @@ namespace radio { function init() { if (initialized) return; initialized = true; + onDataReceived(handleDataReceived); + } - onDataReceived(() => { - let buffer: Buffer = readRawPacket(); - while (buffer && buffer.length) { - lastPacket = RadioPacket.getPacket(buffer); - lastPacket.signal = receivedSignalStrength(); - switch (lastPacket.packetType) { - case PACKET_TYPE_NUMBER: - case PACKET_TYPE_DOUBLE: - if (onReceivedNumberHandler) - onReceivedNumberHandler(lastPacket.numberPayload); - break; - case PACKET_TYPE_VALUE: - case PACKET_TYPE_DOUBLE_VALUE: - if (onReceivedValueHandler) - onReceivedValueHandler(lastPacket.stringPayload, lastPacket.numberPayload); - break; - case PACKET_TYPE_BUFFER: - if(onReceivedBufferHandler) - onReceivedBufferHandler(lastPacket.bufferPayload); - break; - case PACKET_TYPE_STRING: - if (onReceivedStringHandler) - onReceivedStringHandler(lastPacket.stringPayload); - break; - } + function handleDataReceived() { + let buffer: Buffer = readRawPacket(); + while (buffer && buffer.length) { + lastPacket = RadioPacket.getPacket(buffer); + switch (lastPacket.packetType) { + case PACKET_TYPE_NUMBER: + case PACKET_TYPE_DOUBLE: + if (onReceivedNumberHandler) + onReceivedNumberHandler(lastPacket.numberPayload); + break; + case PACKET_TYPE_VALUE: + case PACKET_TYPE_DOUBLE_VALUE: + if (onReceivedValueHandler) + onReceivedValueHandler(lastPacket.stringPayload, lastPacket.numberPayload); + break; + case PACKET_TYPE_BUFFER: + if (onReceivedBufferHandler) + onReceivedBufferHandler(lastPacket.bufferPayload); + break; + case PACKET_TYPE_STRING: + if (onReceivedStringHandler) + onReceivedStringHandler(lastPacket.stringPayload); + break; + } // read next packet if any buffer = readRawPacket(); - } - }) + } } /** @@ -162,6 +162,7 @@ namespace radio { export class RadioPacket { public static getPacket(data: Buffer) { + // last 4 bytes is RSSi return new RadioPacket(data); } @@ -172,10 +173,12 @@ namespace radio { } 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() { return this.data[0]; @@ -358,6 +361,18 @@ namespace radio { 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) { serial.writeString("{"); serial.writeString("\"t\":"); diff --git a/libs/radio/shims.d.ts b/libs/radio/shims.d.ts index fbbca79b..cb6e340c 100644 --- a/libs/radio/shims.d.ts +++ b/libs/radio/shims.d.ts @@ -16,15 +16,14 @@ declare namespace radio { 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; /** - * 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 function sendRawPacket(msg: Buffer): void; @@ -37,17 +36,6 @@ declare namespace radio { //% deprecated=true shim=radio::onDataReceived 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. * @param id the group id between ``0`` and ``255``, eg: 1