Sending GPS position from one CubeCell to another over LoRa

Hi, guys. Noob (who bit off a little more than he could chew) posting here!

Long story short: I am making a transmitter and locator to play Airsoft. My intention is to have one HTCC-AB02S send its location via LoRa to another HTCC-AB02S to locate it. At this time, I am working on the transmitter, and I have been stuck a couple of weeks now trying to transmit the GPS coordinates.

I have been using the Factory_Test_AB02S as a template. I managed to show the GPS data on screen (Lat & Long - 4 digits on screen, 5 in serial print; I intend to transmit 5 - , GPS Time, HDOP, number of satellites, altitude), and also have it print on scren (serial print), but I cannot get it to transmit. I admit that the whole uint8_t * has done me in. I have tried to understand it, but it is WAY beyond my skill level!

My final intention is to have the receiver calculate the direction of the transmitter, and (with the help of a GY-85 module) point an arrow at the direction of the transmitter and state the distance and the level of accuracy (excellent, good, moderate, fair, poor) based on HDOP. But without the transmitter transmitting its location, nothing moves forward!

I should probably point out that one of the AB02S has the Air530Z module and the other has the Air530 (I ordered both at the same time, so go figure!).

Felipe

PS: I was going to include the code I am using, but the site thinks I am posting links and does not allow me to do it!

Hi, is it possible to transmit ordinary data through LoRa(confirm that Lora communication is OK)?
Please show your code in text.

Hi, is it possible to transmit ordinary data through LoRa(confirm that Lora communication is OK)?
Please show your code in text.

Yes. I used the Factory_Test_AB02S and the transmission worked fine. Here is that code:

#include “LoRaWan_APP.h”
#include “Arduino.h”
#include “HT_SSD1306Wire.h”
#include “GPS_Air530.h”
#include “GPS_Air530Z.h”

Air530Class GPS;

#ifndef LoraWan_RGB
#define LoraWan_RGB 0
#endif

extern SSD1306Wire display;

#define RF_FREQUENCY 868000000

#define TX_OUTPUT_POWER 14

#define LORA_BANDWIDTH 0
#define LORA_SPREADING_FACTOR 7
#define LORA_CODINGRATE 1
#define LORA_PREAMBLE_LENGTH 8
#define LORA_SYMBOL_TIMEOUT 0
#define LORA_FIX_LENGTH_PAYLOAD_ON false
#define LORA_IQ_INVERSION_ON false

#define RX_TIMEOUT_VALUE 1000
#define BUFFER_SIZE 30

char txpacket[BUFFER_SIZE];
char rxpacket[BUFFER_SIZE];

static RadioEvents_t RadioEvents;
void OnTxDone( void );
void OnTxTimeout( void );
void OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr );
void displayInof();
void sleep(void);
void testRGB(void);
void showGpsInfo(void);
int fracPart(double val, int n);
void userKey(void);

typedef enum
{
LOWPOWER,
RX,
TX,
GPSTEST
}States_t;

int16_t txNumber;
States_t state;
bool sleepMode = false;
int16_t Rssi,rxSize;

void setup() {
Serial.begin(115200);
pinMode(Vext, OUTPUT);
digitalWrite(Vext, LOW);
delay(100);
display.init();

testRGB();
txNumber=0;
Rssi=0;

pinMode(P3_3,INPUT);
attachInterrupt(P3_3,userKey,FALLING);
RadioEvents.TxDone = OnTxDone;
RadioEvents.TxTimeout = OnTxTimeout;
RadioEvents.RxDone = OnRxDone;

Radio.Init( &RadioEvents );
Radio.SetChannel( RF_FREQUENCY );
Radio.SetTxConfig( MODEM_LORA, TX_OUTPUT_POWER, 0, LORA_BANDWIDTH,
                               LORA_SPREADING_FACTOR, LORA_CODINGRATE,
                               LORA_PREAMBLE_LENGTH, LORA_FIX_LENGTH_PAYLOAD_ON,
                               true, 0, 0, LORA_IQ_INVERSION_ON, 3000 );

Radio.SetRxConfig( MODEM_LORA, LORA_BANDWIDTH, LORA_SPREADING_FACTOR,
                               LORA_CODINGRATE, 0, LORA_PREAMBLE_LENGTH,
                               LORA_SYMBOL_TIMEOUT, LORA_FIX_LENGTH_PAYLOAD_ON,
                               0, true, 0, 0, LORA_IQ_INVERSION_ON, true );

state=TX;

}

void loop()
{
switch(state)
{
case TX:
delay(1000);
txNumber++;
sprintf(txpacket,"%s",“hello”);
sprintf(txpacket+strlen(txpacket),"%d",txNumber);
sprintf(txpacket+strlen(txpacket),"%s"," rssi : “);
sprintf(txpacket+strlen(txpacket),”%d",Rssi);
turnOnRGB(0x100000,0);

      Serial.printf("\r\nsending packet \"%s\" , length %d\r\n",txpacket, strlen(txpacket));

      Radio.Send( (uint8_t *)txpacket, strlen(txpacket) );
      state=LOWPOWER;
      break;
  case RX:
  	Serial.println("into RX mode");
      Radio.Rx( 0 );
      state=LOWPOWER;
      break;
  case LOWPOWER:
  	if(sleepMode)
  	{
    GPS.end();
  		Radio.Sleep( );
  		display.stop();
  		detachInterrupt(RADIO_DIO_1);
  		turnOffRGB();
  	    pinMode(Vext,ANALOG);
  	    pinMode(ADC,ANALOG);
  	}
  	lowPowerHandler();
    break;
case GPSTEST:
  showGpsInfo();
  break;
default:
  break;

}
Radio.IrqProcess( );
}

void OnTxDone( void )
{
Serial.print(“TX done…”);
displayInof();
turnOnRGB(0,0);
state=RX;
}

void OnTxTimeout( void )
{
Radio.Sleep( );
Serial.print(“TX Timeout…”);
}
void OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr )
{
Rssi=rssi;
rxSize=size;
memcpy(rxpacket, payload, size );
rxpacket[size]=’\0’;
turnOnRGB(0x001000,100);
turnOnRGB(0,0);
Radio.Sleep( );

Serial.printf("\r\nreceived packet \"%s\" with rssi %d , length %d\r\n",rxpacket,Rssi,rxSize);
Serial.println("wait to send next packet");
displayInof();

state=TX;

}

void displayInof()
{
display.clear();
display.drawString(0, 50, “Packet " + String(txNumber,DEC) + " sent done”);
display.drawString(0, 0, “Received Size " + String(rxSize,DEC) + " packages:”);
display.drawString(0, 15, rxpacket);
display.drawString(0, 30, "With rssi " + String(Rssi,DEC));
display.display();
}

void userKey(void)
{
delay(10);
if(digitalRead(P3_3)==0)
{
uint16_t keyDownTime = 0;
while(digitalRead(P3_3)==0)
{
delay(1);
keyDownTime++;
if(keyDownTime>=700)
break;
}
if(keyDownTime<700)
{
state = LOWPOWER;
sleepMode = true;
}
else
{
state = GPSTEST;
detachInterrupt(RADIO_DIO_1);
Radio.Sleep( );
turnOnRGB(0,0);
GPS.begin();
}
}
}

void testRGB(void)
{
display.drawString(0, 20, “RGB Testing”);
display.display();
for(uint32_t i=0;i<=30;i++)
{
turnOnRGB(i<<16,10);
}
for(uint32_t i=0;i<=30;i++)
{
turnOnRGB(i<<8,10);
}
for(uint32_t i=0;i<=30;i++)
{
turnOnRGB(i,10);
}
turnOnRGB(0,0);
}

void showGpsInfo()
{ uint32_t starttime = millis();
while( (millis()-starttime) < 1000 )
{
while (GPS.available() > 0)
{
GPS.encode(GPS.read());
}
}

char str[30];
display.clear();
display.setFont(ArialMT_Plain_10);
int index = sprintf(str,"%02d-%02d-%02d",GPS.date.year(),GPS.date.day(),GPS.date.month());
str[index] = 0;
display.setTextAlignment(TEXT_ALIGN_LEFT);
display.drawString(0, 0, str);

index = sprintf(str,"%02d:%02d:%02d",GPS.time.hour(),GPS.time.minute(),GPS.time.second(),GPS.time.centisecond());
str[index] = 0;
display.drawString(60, 0, str);

if( GPS.location.age() < 1000 )
{
display.drawString(120, 0, “A”);
}
else
{
display.drawString(120, 0, “V”);
}

index = sprintf(str,“alt: %d.%d”,(int)GPS.altitude.meters(),fracPart(GPS.altitude.meters(),2));
str[index] = 0;
display.drawString(0, 16, str);

index = sprintf(str,“hdop: %d.%d”,(int)GPS.hdop.hdop(),fracPart(GPS.hdop.hdop(),2));
str[index] = 0;
display.drawString(0, 32, str);

index = sprintf(str,“lat : %d.%d”,(int)GPS.location.lat(),fracPart(GPS.location.lat(),4));
str[index] = 0;
display.drawString(60, 16, str);

index = sprintf(str,“lon:%d.%d”,(int)GPS.location.lng(),fracPart(GPS.location.lng(),4));
str[index] = 0;
display.drawString(60, 32, str);

index = sprintf(str,“speed: %d.%d km/h”,(int)GPS.speed.kmph(),fracPart(GPS.speed.kmph(),3));
str[index] = 0;
display.drawString(0, 48, str);
display.display();
}
int fracPart(double val, int n)
{
return (int)((val - (int)(val))*pow(10,n));
}

The code for the transmitter I have so far is next. But please note that it does not include the transmission part, as everything I have tried thus far is not compiling.

#include “LoRaWan_APP.h”
#include “Arduino.h”
#include “HT_SSD1306Wire.h”
#include “GPS_Air530.h”
#include “GPS_Air530Z.h”
#include <Wire.h>

Air530Class GPS;

extern SSD1306Wire display;

int fracPart(double val, int n)
{
return (int)((val - (int)(val))*pow(10,n));
}

#ifndef LoraWan_RGB
#define LoraWan_RGB 0
#endif

#define RF_FREQUENCY 915000000
#define TX_OUTPUT_POWER 14
#define LORA_BANDWIDTH 0
#define LORA_SPREADING_FACTOR 7
#define LORA_CODINGRATE 1
#define LORA_PREAMBLE_LENGTH 8
#define LORA_SYMBOL_TIMEOUT 0
#define LORA_FIX_LENGTH_PAYLOAD_ON false
#define LORA_IQ_INVERSION_ON false
#define RX_TIMEOUT_VALUE 1000
#define BUFFER_SIZE 30

char txpacket[BUFFER_SIZE];
char rxpacket[BUFFER_SIZE];
char TxLatitude;
char TxLongitude;
char TxSpeed;
char TxAltitude;
char TxSatelite;
char TxHdop;

static RadioEvents_t RadioEvents;
void OnTxDone( void );
void OnTxTimeout( void );

typedef enum
{
RX,
TX,
}States_t;

States_t state;

void OnTxDone( void )
{
turnOnRGB(0,0);
state=TX;
}

void OnTxTimeout( void )
{
Radio.Sleep( );
state=TX;
}

void setup() {
pinMode(Vext,OUTPUT);
digitalWrite(Vext, LOW);
delay(10);

display.init();
//display.flipScreenVertically();
display.clear();
display.display();

display.setTextAlignment(TEXT_ALIGN_CENTER);
display.setFont(ArialMT_Plain_16);
display.drawString(64, 32-16/2, “GPS initing…”);
display.display();

Serial.begin(115200);
GPS.begin();
GPS.setmode(MODE_GPS_GLONASS);
//GPS.setmode(MODE_GPS_BEIDOU_GLONASS); //only Air530Z supported.

pinMode(P3_3,INPUT);
RadioEvents.TxDone = OnTxDone;
RadioEvents.TxTimeout = OnTxTimeout;

Radio.Init( &RadioEvents );
Radio.SetChannel( RF_FREQUENCY );
Radio.SetTxConfig( MODEM_LORA, TX_OUTPUT_POWER, 0, LORA_BANDWIDTH,
LORA_SPREADING_FACTOR, LORA_CODINGRATE,
LORA_PREAMBLE_LENGTH, LORA_FIX_LENGTH_PAYLOAD_ON,
true, 0, 0, LORA_IQ_INVERSION_ON, 3000 );
state=TX;
}

void loop()
{
uint32_t starttime = millis();
while( (millis()-starttime) < 1000 )
{
while (GPS.available() > 0)
{
GPS.encode(GPS.read());
}
}

char str[30];
display.clear();
display.setFont(ArialMT_Plain_10);
int index = sprintf(str,"%02d-%02d-%02d",GPS.date.year(),GPS.date.day(),GPS.date.month());
str[index] = 0;
display.setTextAlignment(TEXT_ALIGN_LEFT);
display.drawString(0, 0, str);

index = sprintf(str,"%02d:%02d:%02d",GPS.time.hour(),GPS.time.minute(),GPS.time.second(),GPS.time.centisecond());
str[index] = 0;
display.drawString(60, 0, str);

if( GPS.location.age() < 1000 )
{
display.drawString(120, 0, “A”);
}
else
{
display.drawString(120, 0, “V”);
}

index = sprintf(str,“alt: %d.%d”,(int)GPS.altitude.meters(),fracPart(GPS.altitude.meters(),2));
str[index] = 0;
display.drawString(0, 16, str);
TxAltitude = GPS.altitude.meters();
Radio.IrqProcess( );

index = sprintf(str,“hdop: %d.%d”,(int)GPS.hdop.hdop(),fracPart(GPS.hdop.hdop(),2));
str[index] = 0;
display.drawString(0, 32, str);
TxHdop = GPS.hdop.hdop();
Radio.IrqProcess( );

index = sprintf(str,“lat : %d.%d”,(int)GPS.location.lat(),fracPart(GPS.location.lat(),6));
str[index] = 0;
display.drawString(60, 16, str);
Serial.print(“Latitud: “);
if( GPS.location.age() < 1000 )
{
Serial.print((int)GPS.location.lat() );
Serial.print(”.”);
Serial.println(abs(fracPart(GPS.location.lat(),6)));
}
else
{
Serial.println(0);
}

TxLatitude = GPS.location.lat();
Radio.IrqProcess( );

index = sprintf(str,“lon:%d.%d”,(int)GPS.location.lng(),fracPart(GPS.location.lng(),5));
str[index] = 0;
display.drawString(60, 32, str);
Serial.print(“Longitud: “);
if( GPS.location.age() < 1000 )
{
Serial.print((int)GPS.location.lng());
Serial.print(”.”);
Serial.println(abs(fracPart(GPS.location.lng(),5)));
}
else
{
Serial.println(0);
}
TxLongitude = GPS.location.lng();

index = sprintf(str,“speed: %d.%d km/h”,(int)GPS.speed.kmph(),fracPart(GPS.speed.kmph(),1));
str[index] = 0;
display.drawString(0, 48, str);
display.display();
TxSpeed = GPS.speed.kmph();
Radio.IrqProcess( );

index = sprintf(str,“sat: %d”,(int)GPS.satellites.value());
str[index] = 0;
display.drawString(95, 48, str);
display.display();
Serial.print("Satelites: ");
Serial.println((int)GPS.satellites.value());
TxSatelite = GPS.satellites.value();
Radio.IrqProcess( );

delay (1000);
}

By the way, this is the kind of way I wanted to send the data (longitud as an example), but it did not work:

TxLongitude = GPS.location.lng();
Radio.Send( (uint8_t *)TxLongitude, strlen(TxLongitude) );
Radio.IrqProcess( );

So far, I have been unable to make the variable play nice with the uint8_t* for some reason beyond my comprehension…

Radio.Send( (uint8_t *)&TxLongitude, strlen(TxLongitude) );

Radio.Send( (uint8_t *)&TxLongitude, strlen(TxLongitude) );

Tried it, but still getting an error… invalid conversion from ‘char’ to ‘const char*’ [-fpermissive]

Maybe you should use the string type.

Can you expand? Currently I have no idea what that means.

Any help is greatly appreciated!