Skip to content

Callback onTxDone and Better Random #188

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 19 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions API.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,24 @@ LoRa.endPacket(async);

Returns `1` on success, `0` on failure.

### Tx Done

**WARNING**: Not supported on the Arduino MKR WAN 1300 board!

### Register callback

Register a callback function for when a packet transmission finish.

```arduino
LoRa.onTxDone(onTxDone);

void onTxDone() {
// ...
}
```

* `onTxDone` - function to call when a packet transmission finish.

## Receiving data

### Parsing packet
Expand Down
8 changes: 6 additions & 2 deletions examples/LoRaSimpleGateway/LoRaSimpleGateway.ino
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ void setup() {
Serial.println();

LoRa.onReceive(onReceive);
LoRa.onTxDone(onTxDone);
LoRa_rxMode();
}

Expand Down Expand Up @@ -83,8 +84,7 @@ void LoRa_sendMessage(String message) {
LoRa_txMode(); // set tx mode
LoRa.beginPacket(); // start packet
LoRa.print(message); // add payload
LoRa.endPacket(); // finish packet and send it
LoRa_rxMode(); // set rx mode
LoRa.endPacket(true); // finish packet and send it
}

void onReceive(int packetSize) {
Expand All @@ -96,7 +96,11 @@ void onReceive(int packetSize) {

Serial.print("Gateway Receive: ");
Serial.println(message);
}

void onTxDone() {
Serial.println("TxDone");
LoRa_rxMode();
}

boolean runEvery(unsigned long interval)
Expand Down
8 changes: 6 additions & 2 deletions examples/LoRaSimpleNode/LoRaSimpleNode.ino
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ void setup() {
Serial.println();

LoRa.onReceive(onReceive);
LoRa.onTxDone(onTxDone);
LoRa_rxMode();
}

Expand Down Expand Up @@ -83,8 +84,7 @@ void LoRa_sendMessage(String message) {
LoRa_txMode(); // set tx mode
LoRa.beginPacket(); // start packet
LoRa.print(message); // add payload
LoRa.endPacket(); // finish packet and send it
LoRa_rxMode(); // set rx mode
LoRa.endPacket(true); // finish packet and send it
}

void onReceive(int packetSize) {
Expand All @@ -96,7 +96,11 @@ void onReceive(int packetSize) {

Serial.print("Node Receive: ");
Serial.println(message);
}

void onTxDone() {
Serial.println("TxDone");
LoRa_rxMode();
}

boolean runEvery(unsigned long interval)
Expand Down
65 changes: 65 additions & 0 deletions examples/LoRaSimpleRandomSeed/LoRaSimpleRandomSeed.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
LoRa Simple Random Seed

This code generate a randomSeed using the LoRa Module.

created 03 October 2018
by Luiz H. Cassettari
*/

#include <SPI.h> // include libraries
#include <LoRa.h>

const long frequency = 915E6; // LoRa Frequency

const int csPin = 10; // LoRa radio chip select
const int resetPin = 9; // LoRa radio reset
const int irqPin = 2; // change for your board; must be a hardware interrupt pin

uint32_t seed = 0;

void setup() {
Serial.begin(9600); // initialize serial
while (!Serial);

LoRa.setPins(csPin, resetPin, irqPin);

if (!LoRa.begin(frequency)) {
Serial.println("LoRa init failed. Check your connections.");
while (true); // if failed, do nothing
}

Serial.println("LoRa init succeeded.");
Serial.println();
Serial.println("LoRa Simple Random");
Serial.println("'LoRa.random()' only works when the module is on receive mode");
Serial.println("This code generate a randomSeed using the LoRa Module");
Serial.println();

LoRa.receive();

// Generate a random seed with 32 bits
seed = (uint32_t) LoRa.random() << 24 |
(uint32_t) LoRa.random() << 16 |
(uint32_t) LoRa.random() << 8 |
(uint32_t) LoRa.random();

LoRa.sleep();

randomSeed(seed);
Serial.print("Random Seed : ");
Serial.println(seed);
Serial.println();
}

void loop() {
for (int i = 0; i < 16; i++) {
byte b = random();
if (b < 0x10)
Serial.print('0');
Serial.print(b, HEX);
Serial.print(" ");
}
Serial.println();
delay(1000);
}
1 change: 1 addition & 0 deletions keywords.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ peek KEYWORD2
flush KEYWORD2

onReceive KEYWORD2
onTxDone KEYWORD2
receive KEYWORD2
idle KEYWORD2
sleep KEYWORD2
Expand Down
69 changes: 52 additions & 17 deletions src/LoRa.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,8 @@ LoRaClass::LoRaClass() :
_frequency(0),
_packetIndex(0),
_implicitHeaderMode(0),
_onReceive(NULL)
_onReceive(NULL),
_onTxDone(NULL)
{
// overide Stream timeout value
setTimeout(0);
Expand Down Expand Up @@ -171,13 +172,14 @@ int LoRaClass::beginPacket(int implicitHeader)

int LoRaClass::endPacket(bool async)
{

if ((async) && (_onTxDone))
writeRegister(REG_DIO_MAPPING_1, 0x40); // DIO0 => TXDONE

// put in TX mode
writeRegister(REG_OP_MODE, MODE_LONG_RANGE_MODE | MODE_TX);

if (async) {
// grace time is required for the radio
delayMicroseconds(150);
} else {
if (!async) {
// wait for TX done
while ((readRegister(REG_IRQ_FLAGS) & IRQ_TX_DONE_MASK) == 0) {
yield();
Expand Down Expand Up @@ -347,8 +349,24 @@ void LoRaClass::onReceive(void(*callback)(int))

if (callback) {
pinMode(_dio0, INPUT);
#ifdef SPI_HAS_NOTUSINGINTERRUPT
SPI.usingInterrupt(digitalPinToInterrupt(_dio0));
#endif
attachInterrupt(digitalPinToInterrupt(_dio0), LoRaClass::onDio0Rise, RISING);
} else {
detachInterrupt(digitalPinToInterrupt(_dio0));
#ifdef SPI_HAS_NOTUSINGINTERRUPT
SPI.notUsingInterrupt(digitalPinToInterrupt(_dio0));
#endif
}
}

void LoRaClass::onTxDone(void(*callback)())
{
_onTxDone = callback;

writeRegister(REG_DIO_MAPPING_1, 0x00);
if (callback) {
pinMode(_dio0, INPUT);
#ifdef SPI_HAS_NOTUSINGINTERRUPT
SPI.usingInterrupt(digitalPinToInterrupt(_dio0));
#endif
Expand All @@ -363,6 +381,9 @@ void LoRaClass::onReceive(void(*callback)(int))

void LoRaClass::receive(int size)
{

writeRegister(REG_DIO_MAPPING_1, 0x00); // DIO0 => RXDONE

if (size > 0) {
implicitHeaderMode();

Expand Down Expand Up @@ -582,7 +603,12 @@ void LoRaClass::setOCP(uint8_t mA)

byte LoRaClass::random()
{
return readRegister(REG_RSSI_WIDEBAND);
static byte result = 0;
for(int i = 0; i < 8; i++) {
result = (result << 1) | (result >> 7); // Spread randomness around / rotate left
result ^= readRegister(REG_RSSI_WIDEBAND); // XOR preserves randomness
}
return result;
}

void LoRaClass::setPins(int ss, int reset, int dio0)
Expand Down Expand Up @@ -634,21 +660,30 @@ void LoRaClass::handleDio0Rise()
writeRegister(REG_IRQ_FLAGS, irqFlags);

if ((irqFlags & IRQ_PAYLOAD_CRC_ERROR_MASK) == 0) {
// received a packet
_packetIndex = 0;

// read packet length
int packetLength = _implicitHeaderMode ? readRegister(REG_PAYLOAD_LENGTH) : readRegister(REG_RX_NB_BYTES);
if ((irqFlags & IRQ_RX_DONE_MASK) != 0) {
// received a packet
_packetIndex = 0;

// set FIFO address to current RX address
writeRegister(REG_FIFO_ADDR_PTR, readRegister(REG_FIFO_RX_CURRENT_ADDR));
// read packet length
int packetLength = _implicitHeaderMode ? readRegister(REG_PAYLOAD_LENGTH) : readRegister(REG_RX_NB_BYTES);

// set FIFO address to current RX address
writeRegister(REG_FIFO_ADDR_PTR, readRegister(REG_FIFO_RX_CURRENT_ADDR));

if (_onReceive) {
_onReceive(packetLength);
}

if (_onReceive) {
_onReceive(packetLength);
// reset FIFO address
writeRegister(REG_FIFO_ADDR_PTR, 0);
}

// reset FIFO address
writeRegister(REG_FIFO_ADDR_PTR, 0);
else if ((irqFlags & IRQ_TX_DONE_MASK) != 0) {
if (_onTxDone) {
_onTxDone();
}
}
}
}

Expand Down
2 changes: 2 additions & 0 deletions src/LoRa.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ class LoRaClass : public Stream {

#ifndef ARDUINO_SAMD_MKRWAN1300
void onReceive(void(*callback)(int));
void onTxDone(void(*callback)());

void receive(int size = 0);
#endif
Expand Down Expand Up @@ -111,6 +112,7 @@ class LoRaClass : public Stream {
int _packetIndex;
int _implicitHeaderMode;
void (*_onReceive)(int);
void (*_onTxDone)();
};

extern LoRaClass LoRa;
Expand Down