Go Down

Topic: Including Variables in Text with APRS (Read 58 times) previous topic - next topic

Noah517

Jun 16, 2019, 01:50 am Last Edit: Jun 16, 2019, 02:08 am by Noah517
Hello! I am working on developing a weather balloon tracker. I have decided to use APRS because I have my Ham license. To do this, I am starting off by using a pre-made APRS code for the Arduino, and add everything else I need for the project. You can find it here. I am trying to transmit some temperature data live with it. To do this, I am trying to alter the "comment" part of the code inside the locationUpdate() Part of the code by adding a variable inside of it. It keeps giving me an error saying, "initializer fails to determine size of 'comment'." My code is below.

Code: [Select]


// Arduino APRS Tracker (aat) with Arduino Pro Mini 3.3V/8 MHz
// Based on https://github.com/sh123/aprs_tracker
//

#include <SimpleTimer.h>
#include <TinyGPS.h>
#include <LibAPRS.h>
#include <OneWire.h>
#include <DallasTemperature.h>


// Single shot button
#define BUTTON_PIN 10


// LibAPRS
#define OPEN_SQUELCH false
#define ADC_REFERENCE REF_5V


// Setup for DS18B20 temperature sensor
int insideTemp = 0;
int outsideTemp = 0;
#define ONE_WIRE_BUS 2
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
 

// APRS settings
char APRS_CALLSIGN[]="KM4VXF";
const int APRS_SSID=5;
char APRS_SYMBOL='>';


// Timer
#define TIMER_DISABLED -1

TinyGPS gps;
float falt = gps.f_altitude();

SimpleTimer timer;

char aprs_update_timer_id = TIMER_DISABLED;
bool send_aprs_update = false;
//long instead of float for latitude and longitude
long lat = 0;
long lon = 0;

int year=0;
byte month=0, day=0, hour=0, minute=0, second=0, hundredths=0;
unsigned long age=0;

// buffer for conversions
#define CONV_BUF_SIZE 16
static char conv_buf[CONV_BUF_SIZE];

void setup() 
{
  Serial.begin(115200);
  Serial1.begin(9600);
  sensors.begin();
 
  pinMode(BUTTON_PIN, INPUT_PULLUP);
 
  Serial.println(F("Arduino APRS Tracker"));

  //GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA);
  //GPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ);
  //GPS.sendCommand(PGCMD_ANTENNA);

  APRS_init(ADC_REFERENCE, OPEN_SQUELCH);
  APRS_setCallsign(APRS_CALLSIGN,APRS_SSID);
  APRS_setSymbol(APRS_SYMBOL);
 
  aprs_update_timer_id=timer.setInterval(2L*60L*1000L, setAprsUpdateFlag);
}

void loop()
{
  bool newData = false;

  // For one second we parse GPS data
  for (unsigned long start = millis(); millis() - start < 1000;)
  {
    while (Serial1.available())
    {
      char c = Serial1.read();
      // Serial.write(c); // uncomment this line if you want to see the GPS data flowing
      if (gps.encode(c)) // Did a new valid sentence come in?
        newData = true;
    }
  }

  if (newData)
  {

    sensors.requestTemperatures();
   
    gps.crack_datetime(&year, &month, &day, &hour, &minute, &second, NULL, &age);
    gps.get_position(&lat, &lon, &age);

    Serial.print(static_cast<int>(day)); Serial.print("/"); Serial.print(static_cast<int>(month)); Serial.print("/"); Serial.print(year);
    Serial.print(" "); Serial.print(static_cast<int>(hour)); Serial.print(":"); Serial.print(static_cast<int>(minute)); Serial.print(":"); Serial.print(static_cast<int>(second));Serial.print(F(" "));

    Serial.print(F("LAT="));Serial.print(lat);
    Serial.print(F(" LON="));Serial.print(lon);

    Serial.print(F(" "));
    Serial.print(deg_to_nmea(lat, true));
    Serial.print(F("/"));

    Serial.println(deg_to_nmea(lon, false));

  if (digitalRead(BUTTON_PIN)==0)
  {
    while(digitalRead(BUTTON_PIN)==0) {}; //debounce
    Serial.println(F("MANUAL UPDATE"));
    locationUpdate(DallasTemperature::toFahrenheit(sensors.getTempCByIndex(0)), DallasTemperature::toFahrenheit(sensors.getTempCByIndex(1)), falt);
  }
 
  if (send_aprs_update) {
    Serial.println(F("APRS UPDATE"));
    locationUpdate(0, 0, 0);
    send_aprs_update = false;
  }

  }
  timer.run();
}

void aprs_msg_callback(struct AX25Msg *msg) {
}

void locationUpdate(int insideTemp, int outsideTemp, int alt) {
  char comment []= ("Arduino APRS Weather Ballon! Inside Temp:"+insideTemp);

  APRS_setLat((char*)deg_to_nmea(lat, true));
  APRS_setLon((char*)deg_to_nmea(lon, false));
     
  // turn off SoftSerial to stop interrupting tx
  Serial1.end();
 
  // TX
  APRS_sendLoc(comment, strlen(comment));
 
  // read TX LED pin and wait till TX has finished (PB5) digital write 13 LED_BUILTIN
  while(bitRead(PORTB,5));

  // start SoftSerial again
  Serial1.begin(9600);
}

/*
**  Convert degrees in long format to APRS string format
**  DDMM.hhN for latitude and DDDMM.hhW for longitude
**  D is degrees, M is minutes and h is hundredths of minutes.
**  http://www.aprs.net/vm/DOS/PROTOCOL.HTM
*/
char* deg_to_nmea(long deg, boolean is_lat) {
  bool is_negative=0;
  if (deg < 0) is_negative=1;

  // Use the absolute number for calculation and update the buffer at the end
  deg = labs(deg);

  unsigned long b = (deg % 1000000UL) * 60UL;
  unsigned long a = (deg / 1000000UL) * 100UL + b / 1000000UL;
  b = (b % 1000000UL) / 10000UL;

  conv_buf[0] = '0';
  // in case latitude is a 3 digit number (degrees in long format)
  if( a > 9999) { snprintf(conv_buf , 6, "%04u", a);} else snprintf(conv_buf + 1, 5, "%04u", a);

  conv_buf[5] = '.';
  snprintf(conv_buf + 6, 3, "%02u", b);
  conv_buf[9] = '\0';
  if (is_lat) {
    if (is_negative) {conv_buf[8]='S';}
    else conv_buf[8]='N';
    return conv_buf+1;
    // conv_buf +1 because we want to omit the leading zero
    }
  else {
    if (is_negative) {conv_buf[8]='W';}
    else conv_buf[8]='E';
    return conv_buf;
    }
}

void setAprsUpdateFlag() {
  send_aprs_update = true;
}



Any help would be great.

Thank You,
Noah (KM4VXF)

odometer

You could try using sprintf and/or strcat.

Or, you could just try the direct approach:
Code: [Select]

//                          111111111122222222223333333333444444
//                0123456789012345678901234567890123456789012345
char comment []= "Arduino APRS Weather Ballon! Inside Temp: XXX";

// insert the inside temperature into comment string
if (insideTemp >= 0) {
  // handle temperatures of zero degrees and above
  comment[42] =  (insideTemp/100)    + '0'; // hundreds digit
  comment[43] = ((insideTemp/10)%10) + '0'; // tens digit
  comment[44] =  (insideTemp%10)     + '0'; // ones digit
}
else {
  // handle temperatures below zero degrees
  comment[42] = '-'; // minus sign
  comment[43] = ((-insideTemp)/10) + '0'; // tens digit
  comment[44] = ((-insideTemp)%10) + '0'; // ones digit
}


6v6gt

You can't do this:
char comment []= ("Arduino APRS Weather Ballon! Inside Temp:"+insideTemp) ;
The '+' operator is for the String class.

Maybe convert insideTemp to a char array then put out comment and insideTemp separately.

Crossed with @Odometer

Noah517

You could try using sprintf and/or strcat.

Or, you could just try the direct approach:
Code: [Select]

//                          111111111122222222223333333333444444
//                0123456789012345678901234567890123456789012345
char comment []= "Arduino APRS Weather Ballon! Inside Temp: XXX";

// insert the inside temperature into comment string
if (insideTemp >= 0) {
  // handle temperatures of zero degrees and above
  comment[42] =  (insideTemp/100)    + '0'; // hundreds digit
  comment[43] = ((insideTemp/10)%10) + '0'; // tens digit
  comment[44] =  (insideTemp%10)     + '0'; // ones digit
}
else {
  // handle temperatures below zero degrees
  comment[42] = '-'; // minus sign
  comment[43] = ((-insideTemp)/10) + '0'; // tens digit
  comment[44] = ((-insideTemp)%10) + '0'; // ones digit
}


Thank you for the help. It works perfectly now.

Noah

Go Up