Skip to content

Add function to invert IQ signal register #179

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

Merged
merged 14 commits into from
Aug 19, 2018
9 changes: 9 additions & 0 deletions API.md
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,15 @@ LoRa.enableCrc();
LoRa.disableCrc();
```

### Invert IQ Signals

Invert the LoRa I and Q signals, by default a invertIQ is not used.

```arduino
LoRa.invertIQ(invert);
```
* `invert` - `false` normal mode, `true` IQ signals are inverted.

## Other functions

### Random
Expand Down
113 changes: 113 additions & 0 deletions examples/LoRaSimpleGateway/LoRaSimpleGateway.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
/*
LoRa Simple Gateway/Node Exemple

This code uses InvertIQ function to create a simple Gateway/Node logic.

Gateway - Sends messages with InvertIQ(true)
- Receives messeges with InvertIQ(false)

Node - Sends messages with InvertIQ(false)
- Receives messeges with InvertIQ(true)

With this arrangement a Gateway never receive messagem from another Gateway
and a Node never receive message from another Node.
Only Gateway to Node and vice versa.

This code receives messagens and sends a message every second.

InvertIQ function basically invert the LoRa I and Q signals.

See the Semtech datasheet, http://www.semtech.com/images/datasheet/sx1276.pdf
for more on InvertIQ register 0x33.

created 05 August 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

void setup() {
Serial.begin(115200); // initialize serial
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's have the default baud at 9600 like the other examples, as it's the default baud rate of the Arduino IDE.

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 Gateway");
Serial.println("Only receive messages from nodes");
Serial.println("Tx: invertIQ = true");
Serial.println("Rx: invertIQ = false");
Serial.println();

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

void loop() {
if (runEvery(5000)) { // repeat every 5000 millis

String message = "HeLoRa World! ";
message += "I'm a Gateway! ";
message += millis();

LoRa_sendMessage(message); // send a message

Serial.println("Send Message!");
}
}

void LoRa_rxMode(){
LoRa.invertIQ(false); // normal mode
LoRa.receive(); // set receive mode
}

void LoRa_txMode(){
LoRa.idle(); // set standby mode
LoRa.invertIQ(true); // active invert I and Q signals
}

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
}

void onReceive(int packetSize) {
String message = "";

while (LoRa.available()) {
message += (char)LoRa.read();
}

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

}

boolean runEvery(unsigned long interval)
{
static unsigned long previousMillis = 0;
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval)
{
previousMillis = currentMillis;
return true;
}
return false;
}

113 changes: 113 additions & 0 deletions examples/LoRaSimpleNode/LoRaSimpleNode.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
/*
LoRa Simple Gateway/Node Exemple

This code uses InvertIQ function to create a simple Gateway/Node logic.

Gateway - Sends messages with InvertIQ(true)
- Receives messeges with InvertIQ(false)

Node - Sends messages with InvertIQ(false)
- Receives messeges with InvertIQ(true)

With this arrangement a Gateway never receive messagem from another Gateway
and a Node never receive message from another Node.
Only Gateway to Node and vice versa.

This code receives messagens and sends a message every second.

InvertIQ function basically invert the LoRa I and Q signals.

See the Semtech datasheet, http://www.semtech.com/images/datasheet/sx1276.pdf
for more on InvertIQ register 0x33.

created 05 August 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

void setup() {
Serial.begin(115200); // initialize serial
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar comment as above.

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 Node");
Serial.println("Only receive messages from gateways");
Serial.println("Tx: invertIQ = false");
Serial.println("Rx: invertIQ = true");
Serial.println();

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

void loop() {
if (runEvery(1000)) { // repeat every 1000 millis

String message = "HeLoRa World! ";
message += "I'm a Node! ";
message += millis();

LoRa_sendMessage(message); // send a message

Serial.println("Send Message!");
}
}

void LoRa_rxMode(){
LoRa.invertIQ(true); // active invert I and Q signals
LoRa.receive(); // set receive mode
}

void LoRa_txMode(){
LoRa.idle(); // set standby mode
LoRa.invertIQ(false); // normal mode
}

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
}

void onReceive(int packetSize) {
String message = "";

while (LoRa.available()) {
message += (char)LoRa.read();
}

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

}

boolean runEvery(unsigned long interval)
{
static unsigned long previousMillis = 0;
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval)
{
previousMillis = currentMillis;
return true;
}
return false;
}

2 changes: 2 additions & 0 deletions keywords.txt
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ setPins KEYWORD2
setSPIFrequency KEYWORD2
dumpRegisters KEYWORD2

invertIQ KEYWORD2

#######################################
# Constants (LITERAL1)
#######################################
Expand Down
16 changes: 16 additions & 0 deletions src/LoRa.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,10 @@
#define REG_FREQ_ERROR_LSB 0x2a
#define REG_RSSI_WIDEBAND 0x2c
#define REG_DETECTION_OPTIMIZE 0x31
#define REG_INVERTIQ 0x33
#define REG_DETECTION_THRESHOLD 0x37
#define REG_SYNC_WORD 0x39
#define REG_INVERTIQ2 0x3b
#define REG_DIO_MAPPING_1 0x40
#define REG_VERSION 0x42

Expand Down Expand Up @@ -615,4 +617,18 @@ void LoRaClass::onDio0Rise()
LoRa.handleDio0Rise();
}

void LoRaClass::invertIQ(boolean invert)
{
// https://github.com/intel-iot-devkit/upm/blob/master/src/sx1276/sx1276.cxx
// The datasheet does not mention anything other than an
// InvertIQ bit (0x40) in RegInvertIQ register (0x33). Here,
// we seem to have two bits in RegInvertIQ (existing one for
// RX), and a 'new' one for TXOff (0x01). In addition,
// INVERTIQ2 (0x3b) does not exist in the datasheet, it is
// marked as reserved. We will assume that the datasheet is
// out of date.
writeRegister(REG_INVERTIQ, invert == false ? 0x27 : 0x66);
writeRegister(REG_INVERTIQ2, invert == false ? 0x1d : 0x19);
}

LoRaClass LoRa;
3 changes: 2 additions & 1 deletion src/LoRa.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,8 @@ class LoRaClass : public Stream {
void setSyncWord(int sw);
void enableCrc();
void disableCrc();

void invertIQ(boolean invert);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think about making this:

  • enableInvertIQ() and disableInvertIQ() to make it like the CRC API's above?

another option is invertIQ() and noInvertIQ().

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeap, make sense InvertIQ be like CRC API's function.


// deprecated
void crc() { enableCrc(); }
void noCrc() { disableCrc(); }
Expand Down