Simple transmitter application for SX127x radio.

Dependencies:   MbedJSONValue SX127x sx12xx_hal

main.cpp

Committer:
corymast
Date:
2019-10-16
Revision:
9:b6e3ffbfeabd
Parent:
8:738ab96d41da

File content as of revision 9:b6e3ffbfeabd:

#include "radio.h"
#include "mbed.h"
#include "MbedJSONValue/MbedJSONValue.h"

// Semtech radio definitions for SX127x, SX126x and SX128x

#if defined(SX127x_H)
    #define BW_KHZ              500
    #define SPREADING_FACTOR    11
    #define CF_HZ               912000000
    #define TX_DBM              20
#elif defined(SX126x_H)
    #define BW_KHZ              500
    #define SPREADING_FACTOR    10
    #define CF_HZ               915000000
    #define TX_DBM              (Radio::chipType == CHIP_TYPE_SX1262 ? 20 : 14) 
#elif defined(SX128x_H)
    #define BW_KHZ              200
    #define SPREADING_FACTOR    7
    #define CF_HZ               2487000000
    #define TX_DBM              6
#endif

// The buffer size should match the tx_buf length in sx12xx.h
#define BUF_SIZE    256

// The interval between automatic transmissions in seconds.
#define AUTO_TX_INTERVAL 2.0

/******************** Setup radio transmitter ****************************/

// Analog Sensor setup
AnalogIn sensor_light(A1);
AnalogIn sensor_temp(A3);
double light_val_analog;
double temperature_analog;

// Configure the User button as an interrupt
InterruptIn button(USER_BUTTON, PullUp);

// Initialize global variables
uint8_t seq = 0;  //  Set initial transmit sequence to 0
volatile bool txDone;
MbedJSONValue message;
Timer timer_button;
Ticker ticker_tx;

// Forward declaration
float convert_analog_light_resistance(double analog_val);
float convert_analog_temperature(double analog_val);
void txDoneCB(void);
void rxDoneCB(uint8_t size, float rssi, float snr);
void txTimeoutCB(void);

// Define radio events for transmitter
const RadioEvents_t rev = {
    /* Dio0_top_half */     NULL,
    /* TxDone_topHalf */    NULL,
    /* TxDone_botHalf */    txDoneCB,
    /* TxTimeout  */        txTimeoutCB,
    /* RxDone  */           rxDoneCB,
    /* RxTimeout  */        NULL,
    /* RxError  */          NULL,
    /* FhssChangeChannel  */NULL,
    /* CadDone  */          NULL
};

/**
* Transmit Done Callback Handler
*/
void txDoneCB()
{
    txDone = true;
    printf("Tx Done.\r\n");
}

/**
* Receive Done Callback Handler
*/
void rxDoneCB(uint8_t size, float rssi, float snr)
{
    printf("Rx Done.\r\n");
}

/**
* Transmit Timeout Callback Handler
*/
void txTimeoutCB()
{
    printf("Tx Timeout.\r\n");
}

/**
* Function for building and sending a message.
*/
void send_json()
{
    string s;
    seq++;
    
    /* Fill the message */
    message["btn_count"] = seq; // Total number of button presses since boot.
    message["btn_timer"] = timer_button.read(); // Time since last button press.
    // Scale ADC value to 0-100%
    message["light_val"] = light_val_analog * 100; // Analog reading from light sensor
    message["light_resistance"] = convert_analog_light_resistance(light_val_analog); // Light Sensor Resistance (Ohms)
    message["temperature"] = convert_analog_temperature(temperature_analog); // Temperature (F)
    message["my_str"] = "Hello World!"; // Sample String
    message["my_boolean"] = false; // Sample Boolean
    
    //serialize it into a JSON string
    s = message.serialize();
    printf("json: %s\r\n", s.c_str());
    
    // Copy the serialized message to the radio's transmit buffer
    memcpy(Radio::radio.tx_buf, s.c_str(), s.length());
    // Clear the txDone flag
    txDone = false;
    // Begin transmission of payload
    Radio::Send(s.length(), 0, 0, 0);
}

/**
* Interrupt Handler for the User button.
*/
void button_send_json()
{
    // Send the message
    send_json();
    
    // Restart the button timer
    timer_button.reset();
}

/**
* Function for initializing the SX127x radio.
*/
void radio_init()
{
    // Start radio transmitter after POR or reset
    Radio::Init(&rev);

    //Set radio properties for transmitter
    Radio::Standby();
    Radio::LoRaModemConfig(BW_KHZ, SPREADING_FACTOR, 1);
    Radio::SetChannel(CF_HZ);

    // Set transmitter output power
    Radio::set_tx_dbm(TX_DBM);

    // Setup transmit packet payload  -> preambleLen, fixLen, crcOn, invIQ
    Radio::LoRaPacketConfig(8, false, true, false);
}

/**
* Function for converting analog sensor reading to resistance in Ohms.
*/
float convert_analog_light_resistance(double analog_val)
{          
    float Rsensor=(float)(1023-analog_val)*10/analog_val;
    return Rsensor;
}

/**
* Function for converting analog sensor reading to temperature in degrees F.
*/
float convert_analog_temperature(double analog_val)
{
    double a = analog_val*1023;
    double resistance=(float)(1023-a)*10000/a;
    double temperature=1/(log(resistance/10000)/3975+1/298.15)-276.05;
    double temperature_f = (9.0*temperature)/5.0 + 32.0;
    return temperature_f;
}

/**
* Function for initializing the application.
*/
void application_init(bool enable_auto_tx)
{
    // Configure falling-edge of button to send JSON message
    button.fall(&button_send_json);
    
    if(enable_auto_tx)
    {
        // Configure automatic transmissions on the interval AUTO_TX_INTERVAL
        ticker_tx.attach(&send_json, AUTO_TX_INTERVAL);
    }
    
    // Start a timer to track time between button presses
    timer_button.start();
}

int main()
{        
    printf("\r\nreset-tx \n");
    
    radio_init();
    
    application_init(true);

    for (;;)
    {
        // Transmit message on button press, service radio until tx complete.
        while (!txDone)
        {
            Radio::service();
            light_val_analog = sensor_light.read();
            temperature_analog = sensor_temp.read();
        }
    }
}