Skip to content
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

Added radio to radio and tested it. Can switch back and forth by calling init or initP2P #51

Open
wants to merge 13 commits into
base: master
Choose a base branch
from
134 changes: 134 additions & 0 deletions examples/SodaqExplorer-p2p/SodaqExplorer-p2p.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
/*
* Basic sketch for connecting
* a Sodaq Explorer to another Sodaq Explorer
*
* Author: Dennis Ruigrok
*/

#include <rn2xx3.h>

// Explorer Serial port definitions.
#define debugSerial SerialUSB
#define loraSerial Serial2


// create an instance of the Library.
rn2xx3 myLora(loraSerial);


void setup()
{
// built_in led
pinMode(LED_BUILTIN, OUTPUT);
led_on();

// make sure usb serial connection is available,
// or after 10s go on anyway for 'headless' use of the
// node.
while ((!debugSerial) && (millis() < 10000));

// beginning serial connections.
debugSerial.begin(57600);
loraSerial.begin(57600);

//
debugSerial.println(F("--------------------------------"));
debugSerial.println(F("Basic sketch for communicating "));
debugSerial.println(F("with another Sodaq Explorer"));
debugSerial.println(F("--------------------------------"));
led_off();

initialize_radio();

}

void initialize_radio()
{

myLora.autobaud();

debugSerial.println("DevEUI? ");debugSerial.print(F("> "));
debugSerial.println(myLora.hweui());
debugSerial.println("Version?");debugSerial.print(F("> "));
debugSerial.println(myLora.sysver());
debugSerial.println(F("--------------------------------"));

debugSerial.println(F("Setting up for listening for another explorer"));
bool join_result = false;


// point to point
join_result = myLora.initP2P();


debugSerial.println("\u2713 Successfully Activated radio 2 radio");


}




void loop()
{
debugSerial.print("TXing");
myLora.txCnf("Can you hear me???"); //one byte, blocking function

switch(myLora.txCnf("!")) //one byte, blocking function
{
case TX_FAIL:
{
debugSerial.println("TX unsuccessful or not acknowledged");
break;
}
case TX_SUCCESS:
{
debugSerial.println("TX successful and acknowledged");
break;
}
case TX_WITH_RX:
{
String received = myLora.getRx();
received = myLora.base16decode(received);
debugSerial.print("Received downlink immediately: " + received);
break;
}
default:
{
debugSerial.println("Unknown response from TX function");
}
}

led_off();

for(int i = 0; i < 15000/500; i++) // 15 second listen then send ^
switch(myLora.listenP2P()) {
case TX_WITH_RX:
{
String received = myLora.getRx();
received = myLora.base16decode(received);
debugSerial.print("Received downlink: " + received);
break;
}
case RADIO_LISTEN_WITHOUT_RX:
{
debugSerial.println("Listened timeout but no downlink");
break;
}


}


}


void led_on()
{
digitalWrite(LED_BUILTIN, 1);
}

void led_off()
{
digitalWrite(LED_BUILTIN, 0);
}
147 changes: 142 additions & 5 deletions src/rn2xx3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,9 @@ String rn2xx3::deveui()

bool rn2xx3::init()
{
if(_radio2radio)sendRawCommand(F("mac resume"));
_radio2radio = false;

if(_appskey=="0") //appskey variable is set by both OTAA and ABP
{
return false;
Expand Down Expand Up @@ -323,6 +326,85 @@ bool rn2xx3::initABP(String devAddr, String AppSKey, String NwkSKey)
}
}

bool rn2xx3::initP2P() {
sendRawCommand(F("sys reset"));
_radio2radio = true;

String receivedData;

//clear serial buffer
while(_serial.available())
_serial.read();

configureModuleType();

sendRawCommand(F("mac pause"));

sendRawCommand(F("radio set mod lora"));

switch (_moduleType) {
case RN2903:
sendRawCommand(F("radio set freq 869100000"));
break;
case RN2483:
sendRawCommand(F("radio set freq 868000000"));

break;
default:
// we shouldn't go forward with the init
return false;
}

sendRawCommand(F("radio set pwr 14"));

sendRawCommand(F("radio set sf sf7"));

sendRawCommand(F("radio set afcbw 41.7"));

sendRawCommand(F("radio set rxbw 125"));

sendRawCommand(F("radio set prlen 8"));

sendRawCommand(F("radio set crc on"));

sendRawCommand(F("radio set iqi off"));

sendRawCommand(F("radio set cr 4/5"));

sendRawCommand(F("radio set sync 12"));

sendRawCommand(F("radio set bw 125"));

sendRawCommand(F("radio set wdt 500"));

return true;
}

TX_RETURN_TYPE rn2xx3::listenP2P() {
String receivedData;
bool mustStop = false;

receivedData = sendRawCommand(F("radio rx 0")); // don't put this in receiveddata we want to ignore the first ok
while(!mustStop) {
receivedData = _serial.readStringUntil('\n');

if(receivedData.startsWith("radio_err")) {
return RADIO_LISTEN_WITHOUT_RX; // timeout
} else if(receivedData.startsWith("busy")) {
// just wait
} else if(receivedData.startsWith("radio_rx")) {
//example: radio_rx 54657374696E6720313233
_rxMessenge = receivedData.substring(receivedData.indexOf(' ', 9)+1);
initP2P(); // to remove last messenge because it keeps repeating
return TX_WITH_RX;
}

}



}

TX_RETURN_TYPE rn2xx3::tx(String data)
{
return txUncnf(data); //we are unsure which mode we're in. Better not to wait for acks.
Expand Down Expand Up @@ -371,10 +453,18 @@ TX_RETURN_TYPE rn2xx3::txCommand(String command, String data, bool shouldEncode)
return TX_FAIL;
}

_serial.print(command);
if(_radio2radio) {
command.replace("mac", "radio");
command.replace("uncnf 1 ", "");
command.replace("cnf 1 ", "");
}



_serial.print(command);
if(shouldEncode)
{
sendEncoded(data);
sendEncoded(data);
}
else
{
Expand All @@ -384,7 +474,9 @@ TX_RETURN_TYPE rn2xx3::txCommand(String command, String data, bool shouldEncode)

String receivedData = _serial.readStringUntil('\n');
//TODO: Debug print on receivedData




if(receivedData.startsWith("ok"))
{
_serial.setTimeout(30000);
Expand Down Expand Up @@ -422,14 +514,23 @@ TX_RETURN_TYPE rn2xx3::txCommand(String command, String data, bool shouldEncode)

else if(receivedData.startsWith("radio_tx_ok"))
{

//SUCCESS!!
send_success = true;
return TX_SUCCESS;
}

else if(receivedData.startsWith("radio_rx")) {
//example: radio_rx 54657374696E6720313233
_rxMessenge = receivedData.substring(receivedData.indexOf(' ', 9)+1);
send_success = true;
return TX_WITH_RX;
}

else if(receivedData.startsWith("radio_err"))
{
//This should never happen. If it does, something major is wrong.
// or someone added radio 2 radio support and did it wrong ;-)

init();
}

Expand All @@ -439,6 +540,12 @@ TX_RETURN_TYPE rn2xx3::txCommand(String command, String data, bool shouldEncode)
//init();
}
}
else if(receivedData.startsWith("radio_rx")) {
//example: radio_rx 54657374696E6720313233
_rxMessenge = receivedData.substring(receivedData.indexOf(' ', 9)+1);
send_success = true;
return TX_WITH_RX;
}

else if(receivedData.startsWith("invalid_param"))
{
Expand Down Expand Up @@ -546,7 +653,8 @@ String rn2xx3::base16encode(String input)
}

String rn2xx3::getRx() {
return _rxMessenge;

return _rxMessenge;
}

int rn2xx3::getSNR()
Expand All @@ -564,6 +672,7 @@ String rn2xx3::base16decode(String input)
input.toCharArray(charsIn, input.length()+1);

unsigned i = 0;

for(i = 0; i<input.length()/2+1; i++)
{
if(charsIn[i*2] == '\0') break;
Expand All @@ -583,6 +692,34 @@ String rn2xx3::base16decode(String input)
return charsOut;
}

uint8_t * rn2xx3::base16decodeBytes(String input)
{
if(input.length() > 0) {
uint8_t* bytesOut = (uint8_t*) malloc(input.length() * sizeof(uint8_t));

char charsIn[input.length()+1];

input.trim();
input.toCharArray(charsIn, input.length()+1);

unsigned i = 0;
for(i = 0; i<input.length()/2+1; i++)
{
if(charsIn[i*2] == '\0') break;
if(charsIn[i*2+1] == '\0') break;

char toDo[2];
toDo[0] = charsIn[i*2];
toDo[1] = charsIn[i*2+1];
int out = strtoul(toDo, 0, 16);

bytesOut[i] = (uint8_t) out;
}
return bytesOut;
}
return 0;
}

void rn2xx3::setDR(int dr)
{
if(dr>=0 && dr<=5)
Expand Down
Loading