LoRa two-way communication

@srnet hey, thank you for your help, I've used the examples duplex code and have successfully been able to have a button pressed and 'abort the flight' thank you :slight_smile:

I'll post the finish code just incase someone wants to use this as help for themselves in their future projects

Here's the 'rocket' sender

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

Adafruit_BMP280 bmp;
const int blue = 3;//set blue to pin 3
const int red = 1;//set red to pin 5
const int green = 2;//set green to pin 6 

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

String outgoing;              // outgoing message
String Abort = "ABORT!";
byte msgCount = 0;    // count of outgoing messages
//Original
byte localAddress = 0xBB;     // address of this device
byte destination = 0xFF;      // destination to send to
//byte localAddress = 0xFF;     // address of this device
//byte destination = 0xBB;

long lastSendTime = 0;        // last send time
int interval = 2000;          // interval between sends
double temp;
double pressure;

String tempData;
String pressureData;
String Data;


void setup() {
  Serial.begin(9600); // initialize serial
  delay(2000);
  //while (!Serial);
  Serial.println("LoRa Duplex Rocket");

  // override the default CS, reset, and IRQ pins (optional)
  LoRa.setPins(csPin, resetPin, irqPin);// set CS, reset, IRQ pin
  //LoRa.setPins(22, 8, 9);
  if (!LoRa.begin(433E6)) {             // initialize ratio at 915 MHz
    Serial.println("LoRa init failed. Check your connections.");
    while (true);                       // if failed, do nothing
  }
  LoRa.setTxPower(50);
  bmp.begin(0x76);
  bmp.setSampling(Adafruit_BMP280::MODE_NORMAL,     /* Operating Mode. */
                  Adafruit_BMP280::SAMPLING_X2,     /* Temp. oversampling */
                  Adafruit_BMP280::SAMPLING_X16,    /* Pressure oversampling */
                  Adafruit_BMP280::FILTER_X16,      /* Filtering. */
                  Adafruit_BMP280::STANDBY_MS_500);

  pinMode(red, OUTPUT);//set red as an output
  pinMode(green, OUTPUT);//set green as an output
  pinMode(blue, OUTPUT);//set blue as an output

  digitalWrite(red,LOW);
  digitalWrite(green,LOW);
  digitalWrite(blue,LOW);


  Serial.println("LoRa init succeeded.");
}

void loop() {
  if (millis() - lastSendTime > interval) {
    //Message = bmp read
    temp = bmp.readTemperature();
    pressure = bmp.readPressure();
    tempData = String(temp, 2) + " *C ";
    pressureData = String(pressure, 2) + " Pa"; 
    Data = tempData + pressureData;
    sendMessage(Data);
    Serial.println("Sending " + Data);
    lastSendTime = millis();            // timestamp the message
    interval = random(2000) + 1000;    // 2-3 seconds
  }

  // parse for a packet, and call onReceive with the result:
  onReceive(LoRa.parsePacket());
}

void sendMessage(String outgoing) {
  LoRa.beginPacket();                   // start packet
  LoRa.write(destination);              // add destination address
  LoRa.write(localAddress);             // add sender address
  LoRa.write(msgCount);                 // add message ID
  LoRa.write(outgoing.length());        // add payload length
  LoRa.print(outgoing);                 // add payload
  LoRa.endPacket();                     // finish packet and send it
  msgCount++;                           // increment message ID
}

void onReceive(int packetSize) {
  if (packetSize == 0) return;          // if there's no packet, return

  // read packet header bytes:
  int recipient = LoRa.read();          // recipient address
  byte sender = LoRa.read();            // sender address
  byte incomingMsgId = LoRa.read();     // incoming msg ID
  byte incomingLength = LoRa.read();    // incoming msg length

  String incoming = "";

  while (LoRa.available()) {
    incoming += (char)LoRa.read();
  }
  if (incoming == Abort){
    digitalWrite(red,HIGH);
    while(1);
  }

  if (incomingLength != incoming.length()) {   // check length for error
    Serial.println("error: message length does not match length");
    return;                             // skip rest of function
  }

  // if the recipient isn't this device or broadcast,
  if (recipient != localAddress && recipient != 0xFF) {
    Serial.println("This message is not for me.");
    return;                             // skip rest of function
  }

  // if message is for this device, or broadcast, print details:
  Serial.println("Received from: 0x" + String(sender, HEX));
  Serial.println("Sent to: 0x" + String(recipient, HEX));
  Serial.println("Message ID: " + String(incomingMsgId));
  Serial.println("Message length: " + String(incomingLength));
  Serial.println("Message: " + incoming);
  Serial.println("RSSI: " + String(LoRa.packetRssi()));
  Serial.println("Snr: " + String(LoRa.packetSnr()));
  Serial.println();
}

Here's the station code, which is used to press the button to abort the flight

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



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

const int buttonPin = 5;

String outgoing;              // outgoing message
int buttonState = 0;     

bool Abort = false;

byte msgCount = 0;            // count of outgoing messages
byte localAddress = 0xBB;     // address of this device
byte destination = 0xFF;      // destination to send to
long lastSendTime = 0;        // last send time
int interval = 2000;          // interval between sends

void setup() {
  Serial.begin(9600);                   // initialize serial
  delay(2000);
  //while (!Serial);
  pinMode(buttonPin, INPUT);
  Serial.println("LoRa Duplex");

  // override the default CS, reset, and IRQ pins (optional)
  LoRa.setPins(csPin, resetPin, irqPin);// set CS, reset, IRQ pin

  if (!LoRa.begin(433E6)) {             // initialize ratio at 915 MHz
    Serial.println("LoRa init failed. Check your connections.");
    while (true);                       // if failed, do nothing
  }

  Serial.println("LoRa init succeeded.");
}

void loop() {
  buttonState = digitalRead(buttonPin);


  
    if (Abort == false){
      if (millis() - lastSendTime > interval) {
        if (buttonState == HIGH) {
         Abort = true;
      String message = "ABORT!";   // send a message
      sendMessage(message);
      Serial.println(message);
      lastSendTime = millis();            // timestamp the message
      interval = random(2000) + 1000;    // 2-3 seconds
    
        }
      
      }
      Serial.println("Searching");
    }
  else{ 
    String message = "ABORT!";   // send a message
    sendMessage(message);
    Serial.println("Sending " + message);
    lastSendTime = millis();            // timestamp the message
    interval = random(2000) + 1000;    // 2-3 seconds
    
  }

  // parse for a packet, and call onReceive with the result:
  onReceive(LoRa.parsePacket());
  }


void sendMessage(String outgoing) {
  LoRa.beginPacket();                   // start packet
  LoRa.write(destination);              // add destination address
  LoRa.write(localAddress);             // add sender address
  LoRa.write(msgCount);                 // add message ID
  LoRa.write(outgoing.length());        // add payload length
  LoRa.print(outgoing);                 // add payload
  LoRa.endPacket();                     // finish packet and send it
  msgCount++;                           // increment message ID
}

void onReceive(int packetSize) {
  if (packetSize == 0) return;          // if there's no packet, return

  // read packet header bytes:
  int recipient = LoRa.read();          // recipient address
  byte sender = LoRa.read();            // sender address
  byte incomingMsgId = LoRa.read();     // incoming msg ID
  byte incomingLength = LoRa.read();    // incoming msg length

  String incoming = "";
//Recieving the data
  while (LoRa.available()) {
    incoming += (char)LoRa.read();
  }

  if (incomingLength != incoming.length()) {   // check length for error
    Serial.println("error: message length does not match length");
    return;                             // skip rest of function
  }

  // if the recipient isn't this device or broadcast,
  if (recipient != localAddress && recipient != 0xFF) {
    Serial.println("This message is not for me.");
    return;                             // skip rest of function
  }

  // if message is for this device, or broadcast, print details:
  Serial.println("Received from: 0x" + String(sender, HEX));
  Serial.println("Sent to: 0x" + String(recipient, HEX));
  Serial.println("Message ID: " + String(incomingMsgId));
  Serial.println("Message length: " + String(incomingLength));
  Serial.println("Message: " + incoming);
  Serial.println("RSSI: " + String(LoRa.packetRssi()));
  Serial.println("Snr: " + String(LoRa.packetSnr()));
  Serial.println();
}

thank you again for helping -Harvey :slight_smile: