8 years ago.

SX1276PingPong demo on modtronix inAir9

Hello I am trying to build a LoRa communication module for an IOT project. The hardware I use is listed below

NZ32-SC151 with STM32L151RC: http://modtronix.com/nz32-sc151

SX1276 inAir9: http://modtronix.com/inair9.html

Hardware were connect to iMod2 ports as shown like this: /media/uploads/rba90/nz32-st1l-r1_inair9_appart_together_c8.jpg

I am using

Import librarymbed_nz32sc151

mbed library for NZ32-SC151

and

Import librarySX1276Lib_modtronix

Enabled all bandwidths, added Modtronix inAir9 module

However, when using demo code similar to https://developer.mbed.org/teams/Semtech/code/SX1276PingPong/, some problems were noticed:

  • With Rx timeout set to 3500000us, Tx timeout set to 2000000us, the program returns "OnTxTimeout" and "OnRxTimeout" in order. There is no RF signal transmitted and received.

Anyone have ideas about this problem?

Thanks

The code is shown below:

Example Code

#include "mbed.h"
#include "sx1276Regs-LoRa.h"
#include "sx1276-inAir.h"

#define DEBUG							1

#define RF_FREQUENCY 					868700000 			// 868KHz
#define TX_OUTPUT_POWER 				14 					// 14 dBm for inAir9
#define LORA_BANDWIDTH					7					// 0: 7.8 kHz,  1: 10.4 kHz, 2: 15.6kHz, 3: 20.8kHz,
															// 4: 31.25kHz, 5: 41.7 kHz, 6: 62.5 kHz,
                                							// 7: 125 kHz,  8: 250 kHz,  9: 500 kHz
#define LORA_SPREADING_FACTOR           12					// SF7..SF12
#define LORA_CODINGRATE                 1       			// 1=4/5, 2=4/6, 3=4/7, 4=4/8
#define LORA_PREAMBLE_LENGTH            8       			// Same for Tx and Rx
#define LORA_SYMBOL_TIMEOUT             5      				// Symbols
#define LORA_FIX_LENGTH_PAYLOAD_ON      false
#define LORA_FHSS_ENABLED               false
#define LORA_NB_SYMB_HOP                4
#define LORA_IQ_INVERSION_ON            false
#define LORA_CRC_ENABLED                true

#define TX_TIMEOUT_VALUE				2000000
#define RX_TIMEOUT_VALUE                3500000     // in us
#define BUFFER_SIZE                     32          // Define the payload size here


void OnTxDone(void);
void OnTxTimeout(void);
void OnRxDone(uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr);
void OnRxTimeout(void);
void OnRxError(void);

Serial      pc(USBTX, USBRX);   //Use default TX and RX. Available via USB Com port when using PGM-NUCLEO programmer
SX1276inAir radio(OnTxDone, OnTxTimeout, OnRxDone, OnRxTimeout, OnRxError, NULL, NULL);
DigitalOut led(LED1);

uint8_t Buffer[BUFFER_SIZE];
uint16_t BufferSize = BUFFER_SIZE;
int16_t LoRaRssi;
int8_t LoRaSNR;
volatile RadioState State = LOWPOWER;

const uint8_t PingMsg[] = "PING";
const uint8_t PongMsg[] = "PONG";

void OnTxDone(void)
{
	radio.Sleep();
	State = TX_DONE;

#if DEBUG == 1
	pc.printf("OnTxDone\r\n");
#endif
}

void OnTxTimeout(void)
{
	radio.Sleep();
	State = TX_TIMEOUT;

#if DEBUG == 1
	pc.printf("OnTxTimeout\r\n");
#endif
}

void OnRxDone(uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr)
{
	radio.Sleep();
	BufferSize = size;
	memcpy(Buffer, payload, BufferSize);
	LoRaRssi = rssi;
	LoRaSNR = snr;
	State = RX_DONE;

#if DEBUG == 1
	pc.printf("OnRxDone\r\n");
#endif
}

void OnRxTimeout(void)
{
	radio.Sleep();
	Buffer[BufferSize] = 0;
	State = RX_TIMEOUT;

#if DEBUG == 1
	pc.printf("OnRxTimeout\r\n");
#endif
}

void OnRxError(void)
{
	radio.Sleep();
	State = RX_ERROR;

#if DEBUG == 1
	pc.printf("OnRxError\r\n");
#endif
}


int main() {
	wait_ms(500); // start delay

	// configure uart port
	pc.baud(19200);
	pc.format(8, SerialBase::None, 1);

	// configure radio
	radio.SetBoardType(BOARD_INAIR9); // the correct hardware for our own board

	led = 0;
	while (radio.Read(REG_VERSION) == 0x00)
	{
		pc.printf("Trying to connect to radio device\r\n");
		wait_ms(200);
	}
	led = 1;

	pc.printf("Radio is initialized\r\n");

	// set radio frequency
	radio.SetChannel(RF_FREQUENCY);

	// setup the modern
	radio.SetTxConfig(
			MODEM_LORA,
			TX_OUTPUT_POWER,
			0,
			LORA_BANDWIDTH,
			LORA_SPREADING_FACTOR,
			LORA_CODINGRATE,
			LORA_PREAMBLE_LENGTH,
			LORA_FIX_LENGTH_PAYLOAD_ON,
			LORA_CRC_ENABLED,
			LORA_FHSS_ENABLED,
			LORA_NB_SYMB_HOP,
			LORA_IQ_INVERSION_ON,
			TX_TIMEOUT_VALUE
	);
	radio.SetRxConfig(
			MODEM_LORA,
			LORA_BANDWIDTH,
			LORA_SPREADING_FACTOR,
			LORA_CODINGRATE,
			0,
			LORA_PREAMBLE_LENGTH,
			LORA_SYMBOL_TIMEOUT,
			LORA_FIX_LENGTH_PAYLOAD_ON,
			0,
			LORA_CRC_ENABLED,
			LORA_FHSS_ENABLED,
			LORA_NB_SYMB_HOP,
			LORA_IQ_INVERSION_ON,
			true
	);


	uint8_t i;
	bool isMaster = true;

	radio.Rx(RX_TIMEOUT_VALUE);

    while (1)
    {
    	// Check for connection to radio module
    	while (radio.Read(REG_VERSION) == 0x00)
		{
    		led = !led;
			pc.printf("Reconnecting...\r\n");
			wait_ms(200);
		}
    	led = 1;

    	switch(State)
    	{
    	case RX_DONE:
    		if (isMaster)
    		{
    			if (BufferSize > 0)
    			{
    				if (strncmp((const char *)Buffer, (const char *)PongMsg, 4) == 0)
    				{
    					pc.printf("...Pong\r\n");
    					// send next ping frame
    					strcpy((char *)Buffer, (char *)PingMsg);
    					// fill the buffer with numbers for the payload
    					for( i = 4; i < BufferSize; i++ )
						{
							Buffer[i] = i - 4;
						}
						wait_ms( 10 );
						radio.Send( Buffer, BufferSize );
    				}
    				else if (strncmp( ( const char* )Buffer, ( const char* )PingMsg, 4 ) == 0 )
    				{
    					// A master already exists then become a slave
    					pc.printf("...Ping\r\n");
    					isMaster = false;
    					// send the next pong frame
    					strcpy( ( char* )Buffer, ( char* )PongMsg );
						// We fill the buffer with numbers for the payload
						for( i = 4; i < BufferSize; i++ )
						{
							Buffer[i] = i - 4;
						}
						wait_ms( 10 );
						radio.Send( Buffer, BufferSize );
    				}
    				else
    				{
    					isMaster = true;
    					radio.Rx(RX_TIMEOUT_VALUE);
    				}
    			}
    		}
    		else
    		{
    			if (BufferSize > 0)
    			{
    				if( strncmp( ( const char* )Buffer, ( const char* )PingMsg, 4 ) == 0 )
					{
						pc.printf( "...Ping\r\n");
						// Send the reply to the PING string
						strcpy( ( char* )Buffer, ( char* )PongMsg );
						// We fill the buffer with numbers for the payload
						for( i = 4; i < BufferSize; i++ )
						{
							Buffer[i] = i - 4;
						}
						wait_ms( 10 );
						radio.Send( Buffer, BufferSize );
					}
					else // valid reception but not a PING as expected
					{    // Set device as master and start again
						isMaster = true;
						radio.Rx( RX_TIMEOUT_VALUE );
					}
    			}
    		}
    		State = LOWPOWER;
    		break;

    	case TX_DONE:
    		if (isMaster)
    		{
    			pc.printf("Ping...\r\n");
    		}
    		else
    		{
    			pc.printf("Pong...\r\n");
    		}
    		radio.Rx(RX_TIMEOUT_VALUE);
    		State = LOWPOWER;
    		break;

    	case RX_TIMEOUT:
    		if( isMaster == true )
			{
				// Send the next PING frame
				strcpy( ( char* )Buffer, ( char* )PingMsg );
				for( i = 4; i < BufferSize; i++ )
				{
					Buffer[i] = i - 4;
				}
				wait_ms( 10 );
				radio.Send( Buffer, BufferSize );
			}
			else
			{
				radio.Rx( RX_TIMEOUT_VALUE );
			}
    		State = LOWPOWER;
    		break;

    	case TX_TIMEOUT:
    		radio.Rx( RX_TIMEOUT_VALUE );
    		State = LOWPOWER;
    		break;

    	case RX_ERROR:
    		// We have received a Packet with a CRC error, send reply as if packet was correct
			if( isMaster == true )
			{
				// Send the next PING frame
				strcpy( ( char* )Buffer, ( char* )PingMsg );
				for( i = 4; i < BufferSize; i++ )
				{
					Buffer[i] = i - 4;
				}
				wait_ms( 10 );
				radio.Send( Buffer, BufferSize );
			}
			else
			{
				// Send the next PONG frame
				strcpy( ( char* )Buffer, ( char* )PongMsg );
				for( i = 4; i < BufferSize; i++ )
				{
					Buffer[i] = i - 4;
				}
				wait_ms( 10 );
				radio.Send( Buffer, BufferSize );
			}
    		State = LOWPOWER;
    		break;

    	case LOWPOWER:
    		break;

    	default:
    		State = LOWPOWER;
    		break;
    	}
    }

}

Hi there, did you ever resolve this issue?

posted by Ruben FitzSimons 12 Feb 2017

Hello Ruben We failed to solve the problem. It seems that three of our NZ32-SC151 boards were totally broken and unusable. Either way we didn't receive any help from Modtronix. In stead we hard wired the inAir9 module to NUCLEO-L152RE board. The demo worked as a charm and did not generate any error message.

posted by Ran Bao 13 Feb 2017
Be the first to answer this question.