2016-04-07 21:52:02 +02:00
|
|
|
#include "pxt.h"
|
2016-04-03 02:34:06 +02:00
|
|
|
|
2016-04-07 21:52:02 +02:00
|
|
|
using namespace pxt;
|
2016-04-03 02:34:06 +02:00
|
|
|
|
2018-10-02 18:32:08 +02:00
|
|
|
//% color=#E3008C weight=96 icon="\uf012"
|
2016-04-03 02:34:06 +02:00
|
|
|
namespace radio {
|
|
|
|
|
|
|
|
bool radioEnabled = false;
|
2016-10-11 22:48:25 +02:00
|
|
|
|
2016-04-03 02:34:06 +02:00
|
|
|
int radioEnable() {
|
|
|
|
int r = uBit.radio.enable();
|
2016-04-16 07:41:30 +02:00
|
|
|
if (r != MICROBIT_OK) {
|
|
|
|
uBit.panic(43);
|
|
|
|
return r;
|
|
|
|
}
|
2016-04-03 02:34:06 +02:00
|
|
|
if (!radioEnabled) {
|
2016-04-07 21:52:02 +02:00
|
|
|
uBit.radio.setGroup(pxt::programHash());
|
2018-09-24 19:16:03 +02:00
|
|
|
uBit.radio.setTransmitPower(6); // start with high power by default
|
2016-04-03 02:34:06 +02:00
|
|
|
radioEnabled = true;
|
|
|
|
}
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
2018-10-08 18:46:23 +02:00
|
|
|
/**
|
|
|
|
* Sends an event over radio to neigboring devices
|
|
|
|
*/
|
2019-04-05 19:45:06 +02:00
|
|
|
//% blockId=radioRaiseEvent block="radio raise event|from source %src=control_event_source_id|with value %value=control_event_value_id"
|
2018-10-08 18:46:23 +02:00
|
|
|
//% blockExternalInputs=1
|
|
|
|
//% advanced=true
|
|
|
|
//% weight=1
|
|
|
|
//% help=radio/raise-event
|
|
|
|
void raiseEvent(int src, int value) {
|
2016-04-03 02:34:06 +02:00
|
|
|
if (radioEnable() != MICROBIT_OK) return;
|
2019-10-22 17:39:44 +02:00
|
|
|
|
2018-10-08 18:46:23 +02:00
|
|
|
uBit.radio.event.eventReceived(MicroBitEvent(src, value, CREATE_ONLY));
|
2016-04-03 02:34:06 +02:00
|
|
|
}
|
|
|
|
|
2016-05-12 21:35:40 +02:00
|
|
|
/**
|
2019-10-22 17:39:44 +02:00
|
|
|
* Internal use only. Takes the next packet from the radio queue and returns its contents + RSSI in a Buffer
|
2016-10-11 22:48:25 +02:00
|
|
|
*/
|
2019-10-22 17:39:44 +02:00
|
|
|
//%
|
2019-04-12 22:10:47 +02:00
|
|
|
Buffer readRawPacket() {
|
|
|
|
if (radioEnable() != MICROBIT_OK) return mkBuffer(NULL, 0);
|
2019-10-22 17:39:44 +02:00
|
|
|
|
|
|
|
PacketBuffer p = uBit.radio.datagram.recv();
|
|
|
|
if (p == PacketBuffer::EmptyPacket)
|
2019-10-05 15:24:15 +02:00
|
|
|
return mkBuffer(NULL, 0);
|
2019-10-22 17:39:44 +02:00
|
|
|
|
|
|
|
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));
|
2016-05-12 21:35:40 +02:00
|
|
|
}
|
2016-10-11 22:48:25 +02:00
|
|
|
|
2018-01-30 19:11:12 +01:00
|
|
|
/**
|
2019-10-22 17:39:44 +02:00
|
|
|
* Internal use only. Sends a raw packet through the radio (assumes RSSI appened to packet)
|
2018-01-30 19:11:12 +01:00
|
|
|
*/
|
2019-10-05 15:24:15 +02:00
|
|
|
//% async
|
2019-04-12 22:10:47 +02:00
|
|
|
void sendRawPacket(Buffer msg) {
|
2018-01-30 19:11:12 +01:00
|
|
|
if (radioEnable() != MICROBIT_OK || NULL == msg) return;
|
2019-10-22 17:39:44 +02:00
|
|
|
|
|
|
|
// 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);
|
2016-04-03 02:34:06 +02:00
|
|
|
}
|
2016-08-09 01:54:43 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Registers code to run when a packet is received over radio.
|
|
|
|
*/
|
|
|
|
//% help=radio/on-data-received
|
|
|
|
//% weight=50
|
|
|
|
//% blockId=radio_datagram_received_event block="radio on data received" blockGap=8
|
2016-10-25 01:30:21 +02:00
|
|
|
//% deprecated=true
|
2016-08-09 01:54:43 +02:00
|
|
|
void onDataReceived(Action body) {
|
|
|
|
if (radioEnable() != MICROBIT_OK) return;
|
2016-10-11 22:48:25 +02:00
|
|
|
|
2019-10-22 17:39:44 +02:00
|
|
|
registerWithDal(MICROBIT_ID_RADIO, MICROBIT_RADIO_EVT_DATAGRAM, body);
|
|
|
|
uBit.radio.datagram.recv(); // wake up read code
|
2016-04-03 02:34:06 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Sets the group id for radio communications. A micro:bit can only listen to one group ID at any time.
|
2017-03-04 08:39:42 +01:00
|
|
|
* @param id the group id between ``0`` and ``255``, eg: 1
|
2016-04-03 02:34:06 +02:00
|
|
|
*/
|
|
|
|
//% help=radio/set-group
|
2019-06-07 23:27:55 +02:00
|
|
|
//% weight=100
|
2016-08-02 01:02:06 +02:00
|
|
|
//% blockId=radio_set_group block="radio set group %ID"
|
2017-03-04 08:39:42 +01:00
|
|
|
//% id.min=0 id.max=255
|
2016-04-03 02:34:06 +02:00
|
|
|
void setGroup(int id) {
|
|
|
|
if (radioEnable() != MICROBIT_OK) return;
|
2019-10-22 17:39:44 +02:00
|
|
|
|
2016-04-03 02:34:06 +02:00
|
|
|
uBit.radio.setGroup(id);
|
|
|
|
}
|
2016-10-11 22:48:25 +02:00
|
|
|
|
2016-04-03 02:34:06 +02:00
|
|
|
/**
|
|
|
|
* Change the output power level of the transmitter to the given value.
|
2016-06-19 14:15:13 +02:00
|
|
|
* @param power a value in the range 0..7, where 0 is the lowest power and 7 is the highest. eg: 7
|
2016-04-03 02:34:06 +02:00
|
|
|
*/
|
|
|
|
//% help=radio/set-transmit-power
|
2016-08-02 01:02:06 +02:00
|
|
|
//% weight=9 blockGap=8
|
|
|
|
//% blockId=radio_set_transmit_power block="radio set transmit power %power"
|
2017-03-04 08:39:42 +01:00
|
|
|
//% power.min=0 power.max=7
|
2016-10-11 22:48:25 +02:00
|
|
|
//% advanced=true
|
2016-04-03 02:34:06 +02:00
|
|
|
void setTransmitPower(int power) {
|
|
|
|
if (radioEnable() != MICROBIT_OK) return;
|
2019-10-22 17:39:44 +02:00
|
|
|
|
2016-04-03 02:34:06 +02:00
|
|
|
uBit.radio.setTransmitPower(power);
|
|
|
|
}
|
|
|
|
}
|