SODAQ1 to Loriot

Hey guys! Has anyone had any success connecting the SODAQ1 to Loriot? I have a working Gateway (that I checked with another sensor - accelerometer and temperature) and the following setup on the SODAQ1:

However, the Gateway is not receiving anything and the led on the SODAQ1 never turns green, it goes from blue to off and back to blue. Does this mean that it’s not getting a fix and transmitting it? Or is something else wrong in the setup?

Thanks!

Dear Jose,

We like Loriot :slight_smile:

For the keys you need to use DevAddr, NWKSKey and AppSKey (ABP) OR DevEUI, AppEUI and AppKey (OTAA).
In your output you mix the two set of keys. It looks like you want to use ABP, change the DevEUI for the DevAddr.

Regards,
Jan

Hi Jan,

thank you very much for the reply!

I’ll try that and let you know how it goes.

Best regards!

Jose.

1 Like

Hi Jan!

So, tried your fix and I am still not getting through to Loriot. This is the latest setup:

According to the debuger, the chip is transmitting. Additionally, the GPS isn’t getting a fix. I tried going outside and I have the same problem.

1.- Could the problems be related? Meaning that without a fix, no data is transmitted (even though it says it is)

2.- Does anyone know what the “ADR” setting does in the Lora section?

3.- The chip should transmit even without an external antenna, correct?

Thanks again very much for any help!

Best regards!

Jose.

Hi,

  1. When the keys are the correct lenght, and the payload is correct the message is succesfully send into the air.
    There is no feedback the message has arrived on the server, you can use acknowledgement for this.

  2. ADR Adaptive Data Rate. The network will tell you what DR to set, DR will set the Spreadingsfactor and Bitrate,

  3. There are two antenna connectors, you need to attach the external lora and gps antenne.

Regards,
Jan

Hi Jan,

ok, so; if I’m understanding you correctly, the antennae are necessary for the board to function correctly, yes?

And, if so, do I need any sort of antennae in particular? Would you have any suggestions?

Thanks again!

Best regards!

Jose.

Hi Jose,

Yes both antenna’s are necessary.

In the webshop we have a section with all antenna’s:

Regards,
Jan

Hi Jan,

wondering if I could trouble you a bit more.

Got my antennae yesterday and installed them. I am now getting a GPS fix. However, I’m still not getting through to Loriot.

Was wondering if the SODAQ One Board is capable of transmitting in 915MHz or if it is only for 868, being that 915 is the band I am using with my Gateway.

Thanks and best regards!

Jose.

Hi Jose,

The RN2483 is 868Mhz and the RN2903 is only 915Mhz.
Do you have the correct module?

Regards,
Jan

Hi Jan,

I have the US module and the 915 lora antenna, which I assume transmits in 915, correct?

I was wondering about the pwr setting and the lora port. Could one of those be the issue with the transmissions to Loriot?

Best regards!

Jose.

Hi Jose,

pwr is by default on maximum.
loraport should not matter, you can use this in a later stage to send different messages to different ports.

What gateway do you use for loriot?
Can you send me in a private message a screenshot of the gateway settings in loriot?
Did you make the correct changed to use the correct frequencies on the gateway?

Regards,
Jan

Hey!

Sent you the screenshots you asked for privately this morning.

Could it be possible that the problem lies in the channels being used? Like I said, my Haxiot LoRaWAN Arduino Shield works within a few seconds of being connected. This is the code I upload to said shield, in case it helps:

#include <LoRaWAN.h>
#include <SoftwareSerial.h>
#include <Wire.h> // for IIC communication
#include “TimerOne.h”

//************** Device parameters for registration *****************
////////////////////////////////////////////////////////////
char DEVICE_ADDR[] = “009E12E6”; //4 bytes required
char APP_KEY[] = “271844B4E9241FDAFDFE669527B61436”; //16 bytes required
char NWK_SESSION_KEY[] = “CF4A2813A4E42756EA8D7F53F656C20A”; //network session key
char APP_SESSION_KEY[] = “8B26C324608AC8BA538E6B79A0AE546C”; //network session key
char DEVICE_EUI[] = “0004A30B001A9EC2”;
////////////////////////////////////////////////////////////

//************** ACCELEROMETER THRESHOLDS*******************************
#define xThreshold 0.5
#define yThreshold 0.5
#define zThreshold 0.5

//**************** TEMPERATURE SAMPLE TIME *******************************
#define TEMP_SAMPLE_TIME 100 //sample time for temperature

//******************** Channel Status *******************
//set bit channel on = 1, channel off = 0
//bank 0 = channels 0-7, bank 1 = channels 8-15, bank 2 = channels 16-23, bank 3 = channels 24-31, bank 4 = channels 32-39,
//bank 5 = channels 40-47, bank 6 = channels 48-55, bank 7 = channels 56-63, bank 8 = channels 64-71,
//MSB = highest channel number in bank. Example Bank 2 = b11000000. Channels 23 and 22 are on

byte channelBank[] = {B11111111, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B11111111};

#define accAddress 0x1D //right justified accelerometer address
#define tmpAddress 0x48 //right justified TMP112 address
#define I2C_WRITE Wire.write
#define I2C_READ Wire.read

/******************** ACCELEROMETER Data ************/
// adresss of accelerometer
#define adress_acc 0X1D // MMA8653FC and MMA8652FC

// adress of registers for MMA8653FC
#define ctrl_reg1 0x2A
#define ctrl_reg2 0x2B
#define ctrl_reg3 0x2C
#define ctrl_reg4 0x2D
#define ctrl_reg5 0x2E
#define int_source 0x0C
#define status_ 0x00
#define f_setup 0x09
#define out_x_msb 0x01
#define out_y_msb 0x03
#define out_z_msb 0x05
#define sysmod 0x0B
#define xyz_data_cfg 0x0E
#define ff_mt_cfg 0x15
#define ff_mt_src 0x16
#define ff_mt_ths 0x17
#define ff_mt_count 0x18

//************** set resolution of accelerometer *************************
//#define resolution 0.0038; //resolution for 2g
//#define resolution 0.0078; //resolution for 4g
#define resolution 0.0156; //resolution for 8g

//************** set range of accelerometer *************************
//#define range 0x00 //2G full scale
//#define range 0x01 //4G full scale
#define range 0x02 //8G full scale

//************** configure accelerometer *************************
//#define accConfig 0x00 // Output data rate at 800Hz, no auto wake, no auto scale adjust, no fast read mode
//#define accConfig 0x21 // Output data rate at 200Hz, no auto wake, no auto scale adjust, no fast read mode
#define accConfig 0x41 // Output data rate at 50Hz, no auto wake, no auto scale adjust, no fast read mode
//#define accConfig 0x71 // Output data rate at 1.5Hz, no auto wake, no auto scale adjust, no fast read mode

//****************** sensor variables **************************
float axeXnow ;
float axeYnow ;
float axeZnow ;
float axeXprev;
float axeYprev;
float axeZprev;
float tempC;

int printTemp;
int printXaxis;
int printYaxis;
int printZaxis;
char charVal[4][5];
long tempCounter;

//*******************************************************************************************************
SoftwareSerial loraSerial(4, 5); // RX, TX ** Set to 10, 11 for Mega2560 boards

void setup() {

delay(1000); //startup delay - gives Lora module time to reset if cold start
Serial.begin(57600); //terminal serial port
loraSerial.begin(57600);
Wire.begin(); // join i2c bus
ACC_INIT(); //initialize accelerometer

getConfig(); //get module information
setChannelStatus(); //configure channels to be on or off

configureABP(); //configure Access By Personalization (ABP)
//configureOTAA(); //configure Over The Air Activation (OTAA)

Timer1.initialize(500000); // initialize timer1, and set to 0.5 second period
Timer1.attachInterrupt(systemTimer); //set ISR

I2C_READ_ACC(0x01); //get initial readings
axeXprev = axeXnow;
axeYprev = axeYnow;
axeZprev = axeZnow;

tempCounter = 0;
}

void loop() {

while (loraSerial.available()) {
Serial.write(loraSerial.read());
}

if (tempCounter >= TEMP_SAMPLE_TIME) //send data every x time
{
getTemperature();
I2C_READ_ACC(0x01);
sendAllData();
tempCounter = 0;
}
delay(50);
I2C_READ_ACC(0x01);
#if 0
if ((abs(axeXprev-axeXnow))>xThreshold || (abs(axeYprev-axeYnow))>yThreshold || (abs(axeZprev-axeZnow))>zThreshold) //send data if any axis exceeds threshold
{
getTemperature();
sendAllData();
axeXprev = axeXnow;
axeYprev = axeYnow;
axeZprev = axeZnow;
}
#endif
}

//*********************************************************************************************
//***************************** FUNCTIONS *****************************************************
//*********************************************************************************************

void sendAllData(void)
{
Serial.println();
Serial.println("****************************************");
Serial.print("Temperature (deg C): ");Serial.println(tempC);
Serial.print("X Axis Now: ");Serial.println(axeXnow);
Serial.print("Y Axis Now: ");Serial.println(axeYnow);
Serial.print("Z Axis Now: ");Serial.println(axeZnow);
Serial.print("X Axis Previous: ");Serial.println(axeXprev);
Serial.print("Y Axis Previous: ");Serial.println(axeYprev);
Serial.print("Z Axis Previous: ");Serial.println(axeZprev);
Serial.println();

formatData();
loraSerial.print("mac tx uncnf 10 ");loraSerial.print(“0167”);loraSerial.print(charVal[0]);
loraSerial.print(“0271”);loraSerial.print(charVal[1]);loraSerial.print(charVal[2]);loraSerial.println(charVal[3]);

Serial.print("mac tx uncnf 10 ");Serial.print(“0167”);Serial.print(charVal[0]);
Serial.print(“0471”);Serial.print(charVal[1]);Serial.print(charVal[2]);Serial.println(charVal[3]);

waitCommandResponse();

}

void systemTimer(void)
{
tempCounter++;

}

//************************ format data for lora tx **********************************
//modified for Cayenne Lora
void formatData(void)
{
int len;

printTemp = int(tempC*10);
String stringT = String(printTemp,HEX);
len = stringT.length();
stringT.toCharArray(charVal[0],5);
leadingZero(0,len);

printXaxis = int(axeXnow * 1000);
String stringX = String(printXaxis,HEX);
len = stringX.length();
stringX.toCharArray(charVal[1],5);
leadingZero(1,len);

printYaxis = int(axeYnow * 1000);
String stringY = String(printYaxis,HEX);
len = stringY.length();
stringY.toCharArray(charVal[2],5);
leadingZero(2,len);

printZaxis = int(axeZnow * 1000);
String stringZ = String(printZaxis,HEX);
len = stringZ.length();
stringZ.toCharArray(charVal[3],5);
leadingZero(3,len);

}
//********************* Add leading zeros to hex value ********************************
void leadingZero(byte dataID, byte lenStr)
{
charVal[dataID][4]=’\0’;

if (lenStr==3)
{
charVal[dataID][3]=charVal[dataID][2];
charVal[dataID][2]=charVal[dataID][1];
charVal[dataID][1]=charVal[dataID][0];
charVal[dataID][0]=‘0’;
}
else if (lenStr==2)
{
charVal[dataID][3]=charVal[dataID][1];
charVal[dataID][2]=charVal[dataID][0];
charVal[dataID][1]=‘0’;
charVal[dataID][0]=‘0’;
}
else if (lenStr==1)
{
charVal[dataID][3]=charVal[dataID][0];
charVal[dataID][2]=‘0’;
charVal[dataID][1]=‘0’;
charVal[dataID][0]=‘0’;
}
}
//****************** Write to I2C Slave Registers *********************************************

void I2C_SEND(unsigned char REG_ADDRESS, unsigned char DATA) //SEND data to MMA7660
{

Wire.beginTransmission(adress_acc);
Wire.write(REG_ADDRESS);
Wire.write(DATA);
Wire.endTransmission();
}

//****************************** Read I2C Slave register *******************************************
void I2C_READ_REG(int ctrlreg_address) //READ number data from i2c slave ctrl-reg register and return the result in a vector
{
unsigned char REG_ADDRESS;
int i=0;
Wire.beginTransmission(adress_acc); //=ST + (Device Adress+W(0)) + wait for ACK
Wire.write(ctrlreg_address); // register to read
Wire.endTransmission();
Wire.requestFrom(adress_acc,1); // read a number of byte and store them in write received
}

//****************** Accelerometer Initialization ************************************
void ACC_INIT()
{
I2C_SEND(ctrl_reg1 ,0X00); // standby to be able to configure
delay(10);
I2C_SEND(f_setup ,B01100000); // set FIFO mode - circular mode 32 byte watermark
delay(5);
I2C_SEND(xyz_data_cfg ,range); // set full range
delay(1);
I2C_SEND(ctrl_reg1 ,accConfig); // configure accelerometer
delay(1);
}
//************************** Read Acceleromter Registers ************************************

void I2C_READ_ACC(int ctrlreg_address) //READ number data from i2c slave ctrl-reg register and return the result in a vector
{
byte REG_ADDRESS[7];
int accel[4];
int i=0;
Wire.beginTransmission(adress_acc); //=ST + (Device Adress+W(0)) + wait for ACK
Wire.write(ctrlreg_address); // store the register to read in the buffer of the wire library
Wire.endTransmission(); // actually send the data on the bus -note: returns 0 if transmission OK-
Wire.requestFrom(adress_acc,7); // read a number of byte and store them in wire.read (note: by nature, this is called an “auto-increment register adress”)

for(i=0; i<7; i++) // 7 because on datasheet p.19 if FREAD=0, on auto-increment, the adress is shifted
// according to the datasheet, because it’s shifted, outZlsb are in adress 0x00
// so we start reading from 0x00, forget the 0x01 which is now “status” and make the adapation by ourselves
//this gives:
//0 = status
//1= X_MSB
//2= X_LSB
//3= Y_MSB
//4= Y_LSB
//5= Z_MSB
// 6= Z_LSB
{
REG_ADDRESS[i]=Wire.read(); //each time you read the write.read it gives you the next byte stored. The couter is reset on requestForm
}

// MMA8653FC gives the result in 10bits. 8bits are in _MSB, and 2 are in _LSB
// this part is used to concatenate both, and then put a sign on it (the most significant bit is giving the sign)
// the explanations are on p.14 of the ‘application notes’ given by freescale.
for (i=1;i<7;i=i+2)
{
accel[0] = (REG_ADDRESS[i+1]|((int)REG_ADDRESS[i]<<8))>>6; // X
if (accel[0]>0x01FF) {accel[1]=(((~accel[0])+1)-0xFC00);} // note: with signed int, this code is optional
else {accel[1]=accel[0];} // note: with signed int, this code is optional
switch(i){
case 1: axeXnow=accel[1]*resolution;
break;
case 3: axeYnow=accel[1]*resolution;
break;
case 5: axeZnow=accel[1]*resolution;
break;
}
}

}

//******************** Temperature Sensor (TMP112) Reading *****************************
void getTemperature(void)
{
long tempSum;
int tempReadingIn[2];
Wire.requestFrom(tmpAddress,2);
tempReadingIn[0] = Wire.read();
tempReadingIn[1] = Wire.read();

//it’s a 12bit int, using two’s compliment for negative
tempSum = ((tempReadingIn[0] << 8) | tempReadingIn[1]) >> 4;
tempC = tempSum*0.0625;
}

//********************* configure ABP ************************************************
void configureABP(void)
{
loraSerial.print("mac set deveui ");loraSerial.println(DEVICE_EUI);
Serial.print("mac set deveui ");Serial.println(DEVICE_EUI);
waitCommandResponse();

//loraSerial.print("mac set appeui ");loraSerial.println(APP_EUI);
//Serial.print("mac set appeui ");Serial.println(APP_EUI);
//waitCommandResponse();

loraSerial.print("mac set appkey ");loraSerial.println(APP_KEY);
Serial.print("mac set appkey ");Serial.println(APP_KEY);
waitCommandResponse();
loraSerial.print("mac set devaddr ");loraSerial.println(DEVICE_ADDR);
Serial.print("mac set devaddr ");Serial.println(DEVICE_ADDR);
waitCommandResponse();
loraSerial.print("mac set nwkskey ");loraSerial.println(NWK_SESSION_KEY);
Serial.print("mac set nwkskey ");Serial.println(NWK_SESSION_KEY);
waitCommandResponse();
loraSerial.print("mac set appskey ");loraSerial.println(APP_SESSION_KEY);
Serial.print("mac set appskey ");Serial.println(APP_SESSION_KEY);
waitCommandResponse();
loraSerial.println(“mac save”);
Serial.println(“mac save”);
waitCommandResponse();
loraSerial.println(“mac join abp”);
Serial.println(“mac join abp”);
waitCommandResponse();
}

#if 0 //not supported on free account
//************************ configure OTAA ************************************
void configureOTAA(void)
{
loraSerial.print("mac set deveui ");loraSerial.println(DEVICE_EUI);
Serial.print("mac set deveui ");Serial.println(DEVICE_EUI);
waitCommandResponse();
loraSerial.print("mac set appeui ");loraSerial.println(APP_EUI);
Serial.print("mac set appeui ");Serial.println(APP_EUI);
waitCommandResponse();
loraSerial.print("mac set appkey ");loraSerial.println(APP_KEY);
Serial.print("mac set appkey ");Serial.println(APP_KEY);
waitCommandResponse();
loraSerial.println(“mac save”);
Serial.println(“mac save”);
waitCommandResponse();
loraSerial.println(“mac join otaa”);
Serial.println(“mac join otaa”);
waitCommandResponse();
}
#endif

//********************* configure channels on or off ******************************
void setChannelStatus()
{
byte channelNumber=0;
for (int x=0; x<9; x++)
{
for (int b=0; b<8; b++)
{
if (bitRead(channelBank[x],b))
{
loraSerial.print(“mac set ch status “);loraSerial.print(channelNumber);loraSerial.println(” on”);
Serial.print(“mac set ch status “);Serial.print(channelNumber);Serial.println(” on”);
}
else
{
loraSerial.print(“mac set ch status “);loraSerial.print(channelNumber);loraSerial.println(” off”);
Serial.print(“mac set ch status “);Serial.print(channelNumber);Serial.println(” off”);
}
channelNumber++;
waitCommandResponse();
}
}
loraSerial.println(“mac set adr off”);
Serial.println(“mac set adr off”);
waitCommandResponse();
loraSerial.println(“mac set pwridx 5”);
Serial.println(“Set Tx power”);
waitCommandResponse();
//loraSerial.println(“mac set dr 4”);
//Serial.println(“Set Data Rate 4”);
//waitCommandResponse();
loraSerial.println(“mac save”);
delay(200);
}

//******************** wait for response from module *************************************
void waitCommandResponse(void)
{
unsigned long currentTime,startTime;
startTime = millis();
while (loraSerial.available() == 0)
{
currentTime = millis();
if (currentTime > (startTime + 3000)) //exit wait routine if nor response in 3 seconds
{
Serial.println(“No Response from Lora Module”);
return;
}
}

while (loraSerial.available())
{
Serial.write(loraSerial.read());
}
}

//************************ get configuration information from module *********************
void getConfig(void)
{
loraSerial.println(“sys get ver”); //get module version
Serial.print("Module Version: ");
waitCommandResponse();
Serial.println();

loraSerial.println(“sys get hweui”); //get module version
Serial.print("EUI Node Address: ");
waitCommandResponse();
Serial.println();
}

Best regards!

Jose.

Hi Jose,

Yes, I see you use the first set of fsb channels.

By default we use there the 2nd set FSB channels for the RN2903 module, in the haxiot sketch is refered to as bank 1.
You can change this in Sodaq_RN2483.h

Update
#define DEFAULT_FSB 2
to
#define DEFAULT_FSB 1
to use bank 0

Best regards,
Jan