Building and Programming the Transmitter

Front of Transmitter on the Flight Mount

Parts List for the Transmitter

I sometimes find that the recommended parts are occasionally out of stock at the companies mentioned below. If this is the case they are often in stock at Digikey or Mouser or other electronics supply companies that stock Sparkfun or Adafruit products. Take a look if you are having trouble finding parts.

Quantity 1
Microprocessor and Transmitter / Receiver that supports the I2C (Qwiic) Interface
SparkFun Pro RF – LoRa, 915MHz (SAMD21)
Sparkfun Part: WRL-15836

Quantity 1
GPS Satellite Receiver that uses the I2C (Qwiic) Interface
SparkFun GPS Breakout – XA1110 (Qwiic)
Sparkfun Part: GPS-14414

Quantity 1
Atmospheric Pressure and Temperature Sensors
Adafruit DPS310 Precision Barometric Pressure / Altitude Sensor – STEMMA QT / Qwiic
Adafruit Product ID: 4494

Quantity 1
915MHz Dipole Antenna
BETAFPV 915MHZ DIPOLE T ANTENNA – 80MM – 2PCS
Pyrodrone PRODUCT SKU: 65C-10107

Quantity 1
Battery
Lithium Ion Polymer Battery – 3.7v 500mAh
Adafruit Product ID: 1578

Quantity 2
Cable to Connect Electronic Components Together
STEMMA QT / Qwiic JST SH 4-pin Cable – 100mm Long
Adafruit Product ID: 4210

It is suggested that you wire the 3 boards together on the bench.

Load code using the Arduino IDE (Code Below)

Test

Package for flight

** Photo of transmitter

Code (to cut and paste):

// This is Radio Server Radio_Server_GPS_SparkFun_SAMD21_Pro_RF_008.ino 2024_02_20
//Radio Server
/*
  Both the TX and RX ProRF boards will need a wire antenna. We recommend a 3" piece of wire.
  This example is a modified version of the example provided by the Radio Head
  Library which can be found here: www.github.com/PaulStoffregen/RadioHeadd
*/

// PLEASE UNCOMMENT THE 6 LINES BELOW
//#include <RadioHead.h>
//#include <SPI.h>
//#include <Adafruit_DPS310.h>
//#include <RH_RF95.h> //Radio Head Library: 
//#include <SparkFun_I2C_GPS_Arduino_Library.h> //Use Library Manager
//#include <TinyGPS++.h>   //Use Library Manager or from: https://github.com/mikalhart/TinyGPSPlus


// We need to provide the RFM95 module's chip select and interrupt pins to the 
// rf95 instance below.On the SparkFun ProRF those pins are 12 and 6 respectively.
RH_RF95 rf95(12, 6);

//Create an instance of the Adafruit DPS310 Pressure/Temperature Sensor
Adafruit_DPS310 dps;

//Create an instance of the Sparkfun GPS Breakout - XA1110
I2CGPS myI2CGPS; //Hook object to the library

//Declare gps object
TinyGPSPlus gps; 

int LED = 13; //Status LED on pin 13
int i = 0;
char GPS_Lat_buf[25];
char GPS_Lon_buf[25];
char GPS_Alt_buf[25];
char GPS_Sat_buf[25];
char GPS_Date_buf[25];
char GPS_Time_buf[25];
char DPS_Pressure_buf[25];
char DPS_Temperature_buf[25];
uint8_t toSend[25];
String configString;

// Turn SerialUSB on or off
// true enables the use of SerialuSB.  false disables the use of SerialUSB
//   for battery operation you want to disable SerialUSB since the computer is not connected
//   to the computer and the USB connector
bool EnableSerialUSB = false;

// true enables the use of the LED.  false disables the use of th LED
//   for battery operation you want to disable the LED to save power
bool EnableLED = false;

// Collect temperature / pressure data from the DPS310 sensor
sensors_event_t temp_event, pressure_event;

// The broadcast frequency is set to 921.2, but the SADM21 ProRf operates
// anywhere in the range of 902-928MHz in the Americas.
// Europe operates in the frequencies 863-870, center frequency at 
// 868MHz.This works but it is unknown how well the radio configures to this frequency:
//float frequency = 864.1;

//float frequency = 921.2; //Broadcast frequency
float frequency = 919.1; //Broadcast frequency


void setup()
{

    pinMode(LED, OUTPUT);
    digitalWrite(LED, LOW);

  if (EnableSerialUSB == true){
    SerialUSB.begin(9600);
    // It may be difficult to read serial messages on startup. The following
    // line will wait for serial to be ready before continuing. Comment out if not needed.
    while(!SerialUSB);
    SerialUSB.println("RFM Server!");
  }
  //Initialize and configure the Radio. 
  if (rf95.init() == false){
      if (EnableSerialUSB == true){SerialUSB.println("Radio Init Failed - Freezing");}
    while (1);
  }
  else{
  // An LED indicator to let us know radio initialization has completed.
    if (EnableSerialUSB == true){SerialUSB.println("Receiver up!");}  

    if (EnableLED == true){
      digitalWrite(LED, HIGH);
      delay(500);
      digitalWrite(LED, LOW);
      delay(500);
    }

  }
 
 // Set frequency
  rf95.setFrequency(frequency); 

 // The default transmitter power is 13dBm, using PA_BOOST.
 // If you are using RFM95/96/97/98 modules which uses the PA_BOOST transmitter pin, then 
 // you can set transmitter powers from 5 to 23 dBm:
 // rf95.setTxPower(14, false);
 rf95.setTxPower(20, false); //false - uses the PA_BOOST Pin

 rf95.setSignalBandwidth(125000);
 rf95.setSpreadingFactor(12);
 rf95.setCodingRate4(8);
 rf95.setPayloadCRC(true);

// Initialize and configure the DPS310 temperature / Pressure sensor
  if (EnableSerialUSB == true){SerialUSB.println("DPS310");}
  if (! dps.begin_I2C(0x77)) {             // Pass in I2C address here
    if (EnableSerialUSB == true){SerialUSB.println("Failed to find DPS");}
    while (1) yield();
  }
  if (EnableSerialUSB == true){SerialUSB.println("DPS OK!");}
  dps.configurePressure(DPS310_64HZ, DPS310_64SAMPLES);
  dps.configureTemperature(DPS310_64HZ, DPS310_64SAMPLES);

  //Start the Sparkfun GPS Breakout - XA1110
  if (myI2CGPS.begin() == false)
  {
    if (EnableSerialUSB == true){SerialUSB.println("Module failed to respond. Please check wiring.");};
    while (1); //Freeze!
  }
  if (EnableSerialUSB == true){SerialUSB.println("GPS module found!");};

  // Set the update rate of the GPS to once every 2 seconds
  //Packet 220: Set time between fixes (update rate)
  //Milliseconds between output. 100 to 10,000 is allowed.
  //Example 1 Hz: ",1000"
  //Example 2 Hz: ",500"
  //Example 10 Hz: ",100"
  //NOTE: You must increase the baud rate to 57600bps or higher to reach 10Hz
  configString = myI2CGPS.createMTKpacket(220, ",2000");  //Set pdate rate to 2 seconds
  myI2CGPS.sendMTKpacket(configString);  

}

void loop()
{

  //To get TinyGPS++ to work, you have to repeatedly funnel the characters to it
  //  from the GPS module using the encode() method using the code below
  while (myI2CGPS.available()) //available() returns the number of new bytes available from the GPS module
  {
    gps.encode(myI2CGPS.read()); //Feed the GPS parser
  }

  //After the object has been “fed” you can query it to 
  //  see if any data fields have been updated
  if (gps.time.isUpdated()) //Check to see if new GPS info is available
  {

    char gps_hour[5];
    char gps_minute[5];
    char gps_second[5];

    // Send the GPS Date from the Sparkfun GPS Breakout - XA1110
    sprintf(GPS_Date_buf, "GPS_Dat: %u/%u/%u", gps.date.year(), gps.date.month(), gps.date.day());
    for(i=0; i < sizeof(GPS_Date_buf); i++)
        { 
          toSend[i] = GPS_Date_buf[i];
        }
    rf95.send(toSend, sizeof(toSend));
    rf95.waitPacketSent();
    if (EnableSerialUSB == true){SerialUSB.println(GPS_Date_buf);}

    // Send the GPS Time from the Sparkfun GPS Breakout - XA1110
    if (gps.time.hour() < 10) {sprintf(gps_hour, "0%u", gps.time.hour());} else {sprintf(gps_hour, "%u", gps.time.hour());}
    if (gps.time.minute() < 10) {sprintf(gps_minute, "0%u", gps.time.minute());} else {sprintf(gps_minute, "%u", gps.time.minute());}
    if (gps.time.second() < 10) {sprintf(gps_minute, "0%u", gps.time.second());} else {sprintf(gps_second, "%u", gps.time.second());}
    sprintf(GPS_Time_buf, "GPS_Tim: %s:%s:%s", gps_hour, gps_minute, gps_second);
    for(i=0; i < sizeof(GPS_Time_buf); i++)
        { 
          toSend[i] = GPS_Time_buf[i];
        }
    rf95.send(toSend, sizeof(toSend));
    rf95.waitPacketSent();
    if (EnableSerialUSB == true){SerialUSB.println(GPS_Time_buf);}

    // Send GPS Latitude data from the Sparkfun GPS Breakout - XA1110
    sprintf(GPS_Lat_buf, "GPS_Lat: %.6f", gps.location.lat());
    for(i=0; i < sizeof(GPS_Lat_buf); i++)
        { 
          toSend[i] = GPS_Lat_buf[i];
        }
    rf95.send(toSend, sizeof(toSend));
    rf95.waitPacketSent();
    if (EnableSerialUSB == true){SerialUSB.println(GPS_Lat_buf);}

    // Send GPS Longitude data from the Sparkfun GPS Breakout - XA1110
    sprintf(GPS_Lon_buf, "GPS_Lon: %.6f", gps.location.lng());
    for(i=0; i < sizeof(GPS_Lat_buf); i++)
        { 
          toSend[i] = GPS_Lon_buf[i];
        }
    rf95.send(toSend, sizeof(toSend));
    rf95.waitPacketSent();
    if (EnableSerialUSB == true){SerialUSB.println(GPS_Lon_buf);}

    // Send GPS Altutude (in feet) data from the Sparkfun GPS Breakout - XA1110
    sprintf(GPS_Alt_buf, "GPS_Alt: %.0f", gps.altitude.feet());
    for(i=0; i < sizeof(GPS_Alt_buf); i++)
        { 
          toSend[i] = GPS_Alt_buf[i];
        }
    rf95.send(toSend, sizeof(toSend));
    rf95.waitPacketSent();
    if (EnableSerialUSB == true){SerialUSB.println(GPS_Alt_buf);}

    // Send GPS Nmber of Satellities data from the Sparkfun GPS Breakout - XA1110
    sprintf(GPS_Sat_buf, "GPS_Sat: %u", gps.satellites.value());
    for(i=0; i < sizeof(GPS_Sat_buf); i++)
        { 
          toSend[i] = GPS_Sat_buf[i];
        }
    rf95.send(toSend, sizeof(toSend));
    rf95.waitPacketSent();
    if (EnableSerialUSB == true){SerialUSB.println(GPS_Sat_buf);}

  }

  // Get Pressure and Temperature Data from DPS311
  while (!dps.temperatureAvailable() || !dps.pressureAvailable()) {
    return; // wait until there's something to read
  }

  dps.getEvents(&temp_event, &pressure_event);

    // Send DPS pressure data from the Adafruit_DPS310
    sprintf(DPS_Pressure_buf, "DPS_Prs: %.2f", pressure_event.pressure);
    for(i=0; i < sizeof(DPS_Pressure_buf); i++)
        { 
          toSend[i] = DPS_Pressure_buf[i];
        }
    rf95.send(toSend, sizeof(toSend));
    rf95.waitPacketSent();
    if (EnableSerialUSB == true){SerialUSB.println(DPS_Pressure_buf);}


    // Send DPS temperature data from the Adafruit_DPS310
    sprintf(DPS_Temperature_buf, "DPS_Tmp: %.2f", temp_event.temperature);
    for(i=0; i < sizeof(DPS_Temperature_buf); i++)
        { 
          toSend[i] = DPS_Temperature_buf[i];
        }
    rf95.send(toSend, sizeof(toSend));
    rf95.waitPacketSent();
    if (EnableSerialUSB == true){SerialUSB.println(DPS_Temperature_buf);}


} // End of Loop
Scroll to Top