Go Down

Topic: Hardware serial radios unreliably getting data (Read 141 times) previous topic - next topic

tristan1473

Hello, I am working on an antenna tracking project which uses a ground station to point some directional antennas at a transmitter which is attached to an unmanned aircraft. I have gotten nearly everything working correctly. I then have some function in my main loop which grabs telemetry data from a Holybro radio connected to a Hardware Serial1 on an Arduino Mega 2560. I am using the HRFMessage library to send and receive telemetry data between radios. I am successfully receiving data on the ground station however it is not consistently being received while the transmitter is a few feet away. I will usually get data between 2 and 15 times and then the if statement looking for new data is not entered for up to 20 seconds. This is a huge issue because the antennas need to constantly get updates of where the transmitter is. I suspect it is either a timing issue, however I have tried 100s of delays in the loop varying between 25 ms to 5 seconds. I also suspect that the length of the strings being sent or received is causing the buffer to either fill or get offset where the telemetry string is unreadable. I removed everything stepper and IMU related as the code was too long to post, thanks!

Transmitter

Code: [Select]
#include <SoftwareSerial.h>
#include <HRFMessage.h>
#include <TinyGPS.h>
#include <Wire.h>
#include <Adafruit_INA219.h>
Adafruit_INA219 ina219;

TinyGPS gps;
SoftwareSerial ss(10,14); // RX, TX
HRFMessage server(&Serial2);

static void print_float(float val, float invalid, int len, int prec);
static void print_int(unsigned long val, unsigned long invalid, int len);
static void print_date(TinyGPS &gps);
static void print_str(const char *str, int len);

void setup()
{
 ss.begin(9600);
 ina219.begin();
 Serial.begin(57600); // Monitoring via USB
 Serial2.begin(57600); // defaults to 9600
 delay(500);

}

void loop()
{
  bool newData = false;
  unsigned long chars;
//  unsigned short sentences, failed;
  uint8_t buf[HRF_MAX_MESSAGE_LEN];
  uint8_t len = sizeof(buf);
  
  float flat, flon, Alt, fspeed;
  float shuntvoltage = 0;
  float busvoltage = 0;
  float current_mA = 0;
  float loadvoltage = 0;
  float power_mW = 0;
  
  shuntvoltage = ina219.getShuntVoltage_mV();
  busvoltage = ina219.getBusVoltage_V();
  current_mA = ina219.getCurrent_mA();
  power_mW = ina219.getPower_mW();
  loadvoltage = busvoltage + (shuntvoltage / 1000);
  
  gps.f_get_position(&flat, &flon);
  Alt =  gps.f_altitude()+0;
  fspeed = gps.f_speed_mph();

  for (unsigned long start = millis(); millis() - start < 1000;)
  {
    while (ss.available())
    {
      char c = ss.read();
      if (gps.encode(c)) // Did a new valid sentence come in?
        newData = true;
    }
  }
  
  char string1[5];
  char string4[7];
  char string5[8];
  char string6[12];
  char string7[12];
  char string8[11];
  char string9[9];
  char total[64];
 
  dtostrf(loadvoltage,2,2,string1);
  dtostrf(current_mA,4,2,string4);
  dtostrf(power_mW,5,2,string5);
  dtostrf(flat,4,6,string6);
  dtostrf(flon,4,6,string7);      
  dtostrf(fspeed,3,7,string8);
  dtostrf(Alt,5,3,string9);

//Serial.println();
Serial.print("                     Load  Curr.  Power   Latitude   Longitude Speed(mph) Altitude");

  strcpy(total,string1);
  strcat(total," ");
  strcat(total,string4);
  strcat(total," ");
  strcat(total,string5);
  strcat(total," ");
  strcat(total,string6);
  strcat(total," ");
  strcat(total,string7);
  strcat(total," ");
  strcat(total,string8);
  strcat(total," ");
  strcat(total,string9);

  server.send((uint8_t*)total,60);

  Serial.println();
  Serial.print("Info in total Array:");
  Serial.print(" ");
  Serial.print(total);
  Serial.println();

}



tristan1473

Receiver

Receiver

Code: [Select]
#include <EEPROM.h>
#include <SoftwareSerial.h>
#include <TinyGPS.h>
#include <Wire.h>
#include <SPI.h>
#include <HRFMessage.h>
#include <SpeedyStepper.h>
#include <Adafruit_GFX.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BNO055.h>
#include <utility/imumaths.h>
#include <avr/wdt.h>
#include <math.h>

#define HRF_MAX_MESSAGE_LEN  64

const float steptodeg    = 360.0/1630.0;   // Degrees per step
const byte  numData      = 64;
uint8_t     tx, ty;
uint8_t     buf[HRF_MAX_MESSAGE_LEN];
uint8_t     len          = sizeof(buf);
boolean     newData      = false;
byte        index        = 0;
char        receivedData[numData];
char        tempData[numData];             // place holder for incoming data string
char        tempChar     = 0;
float       targetLat    = 0;
float       targetLon    = 0;
float       flat         = 0;
float       flon         = 0;
float       alt          = 0;
float       fspeed       = 0;
float       baseAlt      = 0;
float       targetAlt    = 0;
float       latDiff      = 0;
float       lonDiff      = 0;
float       AltDiff      = 0;
float       a            = 0;
float       c            = 0;
float       d            = 0;
float       tom          = 0;
float       jerry        = 0;
float       shuntvoltage = 0;
float       busvoltage   = 0;
float       current_mA   = 0;
float       loadvoltage  = 0;
float       power_mW     = 0;
float       x            = 0;
float       y            = 0;
float       z            = 0;



//Define the objects for the included libraries
HRFMessage client(&Serial1);
SoftwareSerial ss(10,14);
TinyGPS gps;

  ss.begin(9600);
  Serial.begin(9600);
  Serial1.begin(57600);
  delay(500);
  Serial2.begin(9600);

  bool newData = false;
  for (unsigned long start = millis(); millis() - start < 1000;)
  {
    if(ss.available())
    {
      char c = ss.read();
      if (gps.encode(c)) // Did a new valid sentence come in?
        newData = true;
    }
  }

  if (newData){
    if(i == 0){
      Serial.println("Successful GPS read");
      Serial2.println("Successful GPS read\n");
      i++;
    }
    gps.f_get_position(&flat, &flon);
    alt = gps.f_altitude();
  }


/*****************************************************************************************************************/
void loop(void) {
  uint8_t buf[HRF_MAX_MESSAGE_LEN];
  uint8_t len = sizeof(buf);
  if(client.recv((uint8_t*)&buf, &len)){
    strcpy(tempData,buf);
    Serial.println(tempData);
    parseData();
    StepperPointCommand();
  }
  Serial.println("Fin loop");
}
/*****************************************************************************************************************/

void parseData(){      // split the data into its parts

    char * strtokIndx; // this is used by strtok() as an index

    strtokIndx = strtok(tempData," ");      // get the first part
    loadvoltage = atof(strtokIndx); // copy it to Float
 
    strtokIndx = strtok(NULL, " "); // this continues where the previous call left off
    current_mA = atof(strtokIndx);     // convert this part to an float

    strtokIndx = strtok(NULL, " ");
    power_mW = atof(strtokIndx);     // convert this part to a float

    strtokIndx = strtok(NULL, " ");
    targetLat = atof(strtokIndx);
    
    strtokIndx = strtok(NULL, " ");
    targetLon = atof(strtokIndx);

    strtokIndx = strtok(NULL, " ");
    fspeed = atof(strtokIndx);

    strtokIndx = strtok(NULL, " ");
    targetAlt = atof(strtokIndx);
    
    tempData[0] = (char)0;
    buf[0]      = (char)0;
}
// Pull info from telemetry stream, calculate angles, and move steppers
void StepperPointCommand(){

  readIMU();

  Serial.print("LAT = ");
  Serial.println(flat,6);
  Serial.print("LON = ");
  Serial.println(flon,6);
  Serial.print("Alt = ");
  Serial.println(alt,6);

  showParsedData();
    
  latDiff = targetLat - flat;
  lonDiff = targetLon - flon;
//  AltDiff = float(targetAlt - alt);
  AltDiff = 0.0;
  tom     = cos(flat)*sin(targetLat) - sin(flat)*cos(targetLat)*cos(lonDiff);
  jerry   = sin(lonDiff)*cos(targetLat);
  theta1  = atan2(jerry,tom);
  theta1  = -theta1*(180.0/3.14159265359);
  steps1  = round((theta1-((float)x))/((float)steptodeg));
  
  a = pow(sin(latDiff/2),2) + cos(flat)*cos(targetLat)*pow(sin(lonDiff/2),2);
  c = 2*atan2(sqrt(a),sqrt(1-a));
  d = 6371.0*c;
  theta2 = atan2(AltDiff,d);
  theta2 = -theta2*(180.0/3.14159265359);
  steps2 = -round((theta2-y)/((float)steptodeg));
  
// Prevent pitch going over 60°
  if(y-theta2 <= -60.0){
    steps2 = -round((60.0+y)/steptodeg);
  }
// Prevent antennas from hitting tripod
  if(y-theta2 >= 40.0){
    steps2 = round((40-y)/steptodeg);
  }
  Serial.print("theta1 = ");
  Serial.println(theta1);
  Serial.print("steps1 = ");
  Serial.println(steps1);
  Serial.print("theta2 = ");
  Serial.println(theta2);
  Serial.print("steps2 = ");
  Serial.println(steps2);

// Move motors for angle calculations
  step1.moveRelativeInSteps(steps1);
//  step2.moveRelativeInSteps(steps2);
  
}

// print parsed data in Serial
void showParsedData(){
    Serial.println("Voltage [V]");
     Serial.print(loadvoltage,6);
     Serial.println();
    
    Serial.println("Current [mA]");
     Serial.print(current_mA,6);
     Serial.println();
    
    Serial.println("Power [mW]");
     Serial.print(power_mW,6);
     Serial.println();
    
    Serial.println("Latitude");
     Serial.print(targetLat,6);
     Serial.println();
    
    Serial.println("Longitude");
     Serial.print(targetLon,6);
     Serial.println();
    
    Serial.println("Speed [m/s]");
     Serial.print(fspeed,6);
     Serial.println();
    
    Serial.println("Altitude [m]");
     Serial.print(targetAlt,6);
     Serial.println();
}

Robin2

I am successfully receiving data on the ground station however it is not consistently being received while the transmitter is a few feet away.
Have you tried with a simple program that only contains the code that is essential for the wireless communication?

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

srnet

#3
Apr 24, 2019, 10:09 am Last Edit: Apr 24, 2019, 10:09 am by srnet
I am successfully receiving data on the ground station however it is not consistently being received while the transmitter is a few feet away.
To eliminate the possibility that the receiver is just being overloaded by very strong signals, fit an attenuator or terminator to the transmitters antenna.
$50SAT is now Silent (but probably still running)
http://www.50dollarsat.info/
http://www.loratracker.uk/

Go Up