TinyGPS data parsing & viewing it at the RF433 RX node

Hello,
I am trying to seperate the GPS data & view it in another uno board. the wireless medium is 433MHZ RF modulles. I am using 2 separate uno boards one for GPS+TX & the other with RX module. Tried afew example codes in RF 433MHz & they are successful but I am having issues with the gps data.

The algo I am following is...
separate the lat, lon & date_time value
print it on serial monitor to see if its working
wrap it to a String
send it via RF module

I am using the tinyGPS library & test_with_GPS_device example
I tried to modify the sketch a bit. In a GPS logger example the lat,long&date_time is added to a string

String RF_date_time = "invalid";
String RF_lat = "invalid";
String RF_lon = "invalid";
String dataString ="";
.....
..........
  dataString = RF_date_time + "," + RF_lat + "," + RF_lon;

I tried to put the data in an array to send it via RF433 module

char Sensor1CharMsg[50];// The string that we are going to send trought RF
...............
......................
sprintf(Sensor1CharMsg, "%02d/%02d/%02d %02d:%02d:%02d, %f, %f", RF_date_time, RF_lat, RF_lon);

Date, time, Lat, Lon they are decimal & float values but they are indeed strings. what to do for printing these integer contained strings? Should I use %s instead of %d & %f ?
then tried to see the output via

Serial.println(Sensor1CharMsg);

There is no output in serial monitor. then I tried using the string lenght

Serial.println(Sensor1CharMsg, Sizeof(Sensor1CharMsg));

It couldn't be be compiled. RED screen with error.
Then I tried to print the values separately

  Serial.println(RF_date_time);
  Serial.println(RF_lat);
  Serial.println(RF_lon);

Still no output.
In the code they are defined as string. How to serial Print a string?
Cant differentiate between a string & an array or a "string" & "char". Any analogy?

The messed up code is here... The issue is in the void loop() section. lat, laon & date_time is already seperated in the gpsdump () & print float () section. All i need is to first view the "datastring" in the serial monitor & then send it to via 433MHz module. Any help shall be highly appraised.

#include <SoftwareSerial.h>
#include <TinyGPS.h>
#include <stdlib.h>
#include <VirtualWire.h>
/* This sample code demonstrates the normal use of a TinyGPS object.
   It requires the use of SoftwareSerial, and assumes that you have a
   4800-baud serial GPS device hooked up on pins 3(rx) and 4(tx).
*/

TinyGPS gps;
SoftwareSerial nss(3, 4);
static char dtostrfbuffer[20];
char Sensor1CharMsg[50];// The string that we are going to send trought rf

//Define String
String RF_date_time = "invalid";
String RF_lat = "invalid";
String RF_lon = "invalid";
String dataString ="";

static void gpsdump(TinyGPS &gps);
static bool feedgps();
static void print_float(float val, float invalid, int len, int prec, int RF_val);
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()
{
  //Serial interfaces
  Serial.begin(115200);
  nss.begin(9600);
  vw_setup(4000); // Bits per sec
  vw_set_tx_pin(12);// Set the Tx pin. Default is 12
  
}

void loop()
{
  bool newdata = false;
  unsigned long start = millis();
  
  // Every second we print an update
  while (millis() - start < 1000)
  {
    if (feedgps())
      newdata = true;
  }
  
  gpsdump(gps);
  
  dataString = RF_date_time + "," + RF_lat + "," + RF_lon;
  sprintf(Sensor1CharMsg, "%02d/%02d/%02d %02d:%02d:%02d, %f, %f", RF_date_time, RF_lat, RF_lon);
//  Serial.println(Sensor1CharMsg);
  Serial.println(RF_date_time);
  Serial.println(RF_lat);
  Serial.println(RF_lon);
  
}

static void gpsdump(TinyGPS &gps)
{
  float flat, flon;
  unsigned long age, date, time, chars = 0;
  unsigned short sentences = 0, failed = 0;
  static const float LONDON_LAT = 51.508131, LONDON_LON = -0.128002;
  
  print_int(gps.satellites(), TinyGPS::GPS_INVALID_SATELLITES, 5);
  print_int(gps.hdop(), TinyGPS::GPS_INVALID_HDOP, 5);
  gps.f_get_position(&flat, &flon, &age); 
  print_float(flat, TinyGPS::GPS_INVALID_F_ANGLE, 9, 5, 1); //LATITUDE
  print_float(flon, TinyGPS::GPS_INVALID_F_ANGLE, 10, 5, 2); //LONGITUDE
  print_int(age, TinyGPS::GPS_INVALID_AGE, 5);

  print_date(gps); //DATE AND TIME

  print_float(gps.f_altitude(), TinyGPS::GPS_INVALID_F_ALTITUDE, 8, 2, 0);
  print_float(gps.f_course(), TinyGPS::GPS_INVALID_F_ANGLE, 7, 2, 0);
  print_float(gps.f_speed_kmph(), TinyGPS::GPS_INVALID_F_SPEED, 6, 2, 0);
  print_str(gps.f_course() == TinyGPS::GPS_INVALID_F_ANGLE ? "*** " : TinyGPS::cardinal(gps.f_course()), 6);
  print_int(flat == TinyGPS::GPS_INVALID_F_ANGLE ? 0UL : (unsigned long)TinyGPS::distance_between(flat, flon, LONDON_LAT, LONDON_LON) / 1000, 0xFFFFFFFF, 9);
  print_float(flat == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : TinyGPS::course_to(flat, flon, 51.508131, -0.128002), TinyGPS::GPS_INVALID_F_ANGLE, 7, 2, 0);
  print_str(flat == TinyGPS::GPS_INVALID_F_ANGLE ? "*** " : TinyGPS::cardinal(TinyGPS::course_to(flat, flon, LONDON_LAT, LONDON_LON)), 6);

  gps.stats(&chars, &sentences, &failed);
  print_int(chars, 0xFFFFFFFF, 6);
  print_int(sentences, 0xFFFFFFFF, 10);
  print_int(failed, 0xFFFFFFFF, 9);
  Serial.println();
}

static void print_int(unsigned long val, unsigned long invalid, int len)
{
  char sz[32];
  if (val == invalid)
    strcpy(sz, "*******");
  else
    sprintf(sz, "%ld", val);
  sz[len] = 0;
  for (int i=strlen(sz); i<len; ++i)
    sz[i] = ' ';
  if (len > 0) 
    sz[len-1] = ' ';
  Serial.print(sz);
  feedgps();
}

static void print_float(float val, float invalid, int len, int prec, int RF_val)
{
  char sz[32];
  if (val == invalid)
  {
    strcpy(sz, "*******");
    sz[len] = 0;
        if (len > 0) 
          sz[len-1] = ' ';
    for (int i=7; i<len; ++i)
        sz[i] = ' ';
    Serial.print(sz);
    if(RF_val == 1) RF_lat = sz;
    else if(RF_val == 2) RF_lon = sz;
  }
  else
  {
    Serial.print(val, prec);
    if (RF_val == 1) RF_lat = dtostrf(val,10,5,dtostrfbuffer);
    else if (RF_val == 2) RF_lon = dtostrf(val,10,5,dtostrfbuffer);
    int vi = abs((int)val);
    int flen = prec + (val < 0.0 ? 2 : 1);
    flen += vi >= 1000 ? 4 : vi >= 100 ? 3 : vi >= 10 ? 2 : 1;
    for (int i=flen; i<len; ++i)
      Serial.print(" ");
  }
  feedgps();
}

static void print_date(TinyGPS &gps)
{
  int year;
  byte month, day, hour, minute, second, hundredths;
  unsigned long age;
  gps.crack_datetime(&year, &month, &day, &hour, &minute, &second, &hundredths, &age);
  if (age == TinyGPS::GPS_INVALID_AGE)
  {
    Serial.print("*******    *******    ");
    RF_date_time = "invalid";
  }
  else
  {
    char sz[32];
    sprintf(sz, "%02d/%02d/%02d %02d:%02d:%02d   ",
        month, day, year, hour, minute, second);
    Serial.print(sz);
    RF_date_time = sz;
  }
  print_int(age, TinyGPS::GPS_INVALID_AGE, 5);
  feedgps();
}

static void print_str(const char *str, int len)
{
  int slen = strlen(str);
  for (int i=0; i<len; ++i)
    Serial.print(i<slen ? str[i] : ' ');
  feedgps();
}

static bool feedgps()
{
  while (nss.available())
  {
    if (gps.encode(nss.read()))
      return true;
  }
  return false;
}

This sample code has parsed the lat, lon & date_time data & writes it to an SD card.

#include <SPI.h>
#include <TinyGPS.h>
#include <SD.h>
#include <stdlib.h>
#include <SoftwareSerial.h>
/* This sample code demonstrates the normal use of a TinyGPS object.
   It uses an Arduino Mega with a GPS attached to nss at 4800 buad.
*/
SoftwareSerial nss(4, 3);
TinyGPS gps;
static char dtostrfbuffer[20];
int CS = 53;
int LED = 13;

//Define String
String SD_date_time = "invalid";
String SD_lat = "invalid";
String SD_lon = "invalid";
String dataString ="";
char teststring [50];
static void gpsdump(TinyGPS &gps);
static bool feedgps();
static void print_float(float val, float invalid, int len, int prec, int SD_val);
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()
{
  pinMode(CS, OUTPUT);  //Chip Select Pin for the SD Card
  pinMode(LED, OUTPUT);  //LED Indicator
  
  //Serial interfaces
  Serial.begin(115200);
  nss.begin(9600);
  
  //Connect to the SD Card
 /* if(!SD.begin(CS))
  {
    Serial.println("Card Failure");
    return;
  }*/
    
  Serial.print("Testing TinyGPS library v. "); Serial.println(TinyGPS::library_version());
  Serial.println("by Mikal Hart");
  Serial.println();
  Serial.print("Sizeof(gpsobject) = "); Serial.println(sizeof(TinyGPS));
  Serial.println();
  Serial.println("Sats HDOP Latitude Longitude Fix  Date       Time       Date Alt     Course Speed Card  Distance Course Card  Chars Sentences Checksum");
  Serial.println("          (deg)    (deg)     Age                        Age  (m)     --- from GPS ----  ---- to London  ----  RX    RX        Fail");
  Serial.println("--------------------------------------------------------------------------------------------------------------------------------------");
}

void loop()
{
  bool newdata = false;
  unsigned long start = millis();
  
  // Every second we print an update
  while (millis() - start < 1000)
  {
    if (feedgps())
      newdata = true;
  }
  
  gpsdump(gps);
  
  //Write the newest information to the SD Card
  dataString = SD_date_time + "," + SD_lat + "," + SD_lon;
  if(SD_date_time != "invalid")
    digitalWrite(LED, HIGH);
  else
    digitalWrite(LED, LOW);
 /*   
  //Open the Data CSV File
  File dataFile = SD.open("LOG.csv", FILE_WRITE);
  if (dataFile)
  {
    dataFile.println(dataString);
    Serial.println(dataString);
    dataFile.close();
  }
  else
  {
    Serial.println("\nCouldn't open the log file!");
  }*/
}

static void gpsdump(TinyGPS &gps)
{
  float flat, flon;
  unsigned long age, date, time, chars = 0;
  unsigned short sentences = 0, failed = 0;
  static const float LONDON_LAT = 51.508131, LONDON_LON = -0.128002;
  
  print_int(gps.satellites(), TinyGPS::GPS_INVALID_SATELLITES, 5);
  print_int(gps.hdop(), TinyGPS::GPS_INVALID_HDOP, 5);
  gps.f_get_position(&flat, &flon, &age); 
  print_float(flat, TinyGPS::GPS_INVALID_F_ANGLE, 9, 5, 1); //LATITUDE
  print_float(flon, TinyGPS::GPS_INVALID_F_ANGLE, 10, 5, 2); //LONGITUDE
  print_int(age, TinyGPS::GPS_INVALID_AGE, 5);

  print_date(gps); //DATE AND TIME

  print_float(gps.f_altitude(), TinyGPS::GPS_INVALID_F_ALTITUDE, 8, 2, 0);
  print_float(gps.f_course(), TinyGPS::GPS_INVALID_F_ANGLE, 7, 2, 0);
  print_float(gps.f_speed_kmph(), TinyGPS::GPS_INVALID_F_SPEED, 6, 2, 0);
  print_str(gps.f_course() == TinyGPS::GPS_INVALID_F_ANGLE ? "*** " : TinyGPS::cardinal(gps.f_course()), 6);
  print_int(flat == TinyGPS::GPS_INVALID_F_ANGLE ? 0UL : (unsigned long)TinyGPS::distance_between(flat, flon, LONDON_LAT, LONDON_LON) / 1000, 0xFFFFFFFF, 9);
  print_float(flat == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : TinyGPS::course_to(flat, flon, 51.508131, -0.128002), TinyGPS::GPS_INVALID_F_ANGLE, 7, 2, 0);
  print_str(flat == TinyGPS::GPS_INVALID_F_ANGLE ? "*** " : TinyGPS::cardinal(TinyGPS::course_to(flat, flon, LONDON_LAT, LONDON_LON)), 6);

  gps.stats(&chars, &sentences, &failed);
  print_int(chars, 0xFFFFFFFF, 6);
  print_int(sentences, 0xFFFFFFFF, 10);
  print_int(failed, 0xFFFFFFFF, 9);
  Serial.println();
}

static void print_int(unsigned long val, unsigned long invalid, int len)
{
  char sz[32];
  if (val == invalid)
    strcpy(sz, "*******");
  else
    sprintf(sz, "%ld", val);
  sz[len] = 0;
  for (int i=strlen(sz); i<len; ++i)
    sz[i] = ' ';
  if (len > 0) 
    sz[len-1] = ' ';
  Serial.print(sz);
  feedgps();
}

static void print_float(float val, float invalid, int len, int prec, int SD_val)
{
  char sz[32];
  if (val == invalid)
  {
    strcpy(sz, "*******");
    sz[len] = 0;
        if (len > 0) 
          sz[len-1] = ' ';
    for (int i=7; i<len; ++i)
        sz[i] = ' ';
    Serial.print(sz);
    if(SD_val == 1) SD_lat = sz;
    else if(SD_val == 2) SD_lon = sz;
  }
  else
  {
    Serial.print(val, prec);
    if (SD_val == 1) SD_lat = dtostrf(val,10,5,dtostrfbuffer);
    else if (SD_val == 2) SD_lon = dtostrf(val,10,5,dtostrfbuffer);
    int vi = abs((int)val);
    int flen = prec + (val < 0.0 ? 2 : 1);
    flen += vi >= 1000 ? 4 : vi >= 100 ? 3 : vi >= 10 ? 2 : 1;
    for (int i=flen; i<len; ++i)
      Serial.print(" ");
  }
  feedgps();
}

static void print_date(TinyGPS &gps)
{
  int year;
  byte month, day, hour, minute, second, hundredths;
  unsigned long age;
  gps.crack_datetime(&year, &month, &day, &hour, &minute, &second, &hundredths, &age);
  if (age == TinyGPS::GPS_INVALID_AGE)
  {
    Serial.print("*******    *******    ");
    SD_date_time = "invalid";
  }
  else
  {
    char sz[32];
    sprintf(sz, "%02d/%02d/%02d %02d:%02d:%02d   ",
        month, day, year, hour, minute, second);
    Serial.print(sz);
    SD_date_time = sz;
  }
  print_int(age, TinyGPS::GPS_INVALID_AGE, 5);
  feedgps();
}

static void print_str(const char *str, int len)
{
  int slen = strlen(str);
  for (int i=0; i<len; ++i)
    Serial.print(i<slen ? str[i] : ' ');
  feedgps();
}

static bool feedgps()
{
  while (nss.available())
  {
    if (gps.encode(nss.read()))
      return true;
  }
  return false;
}

The comma separated strinng is   dataString = SD_date_time + "," + SD_lat + "," + SD_lon;
all I 'm trying to do is to echo the data in serial monitor.

I take a character array of 50 characters

char teststring [50];

I tried to put just one value in it using sprintf ()

    sprintf(teststring, "%f", SD_lat);

print it in serial monitor.

  Serial.println(teststring);

But the output stuck at the first line in serial monitor.
Any help in putting a string into a char array & print it in serial monitor?

According to arduino the following format prints a string http://arduino.cc/en/Tutorial/StringConstructors

  String stringOne = "Hello String";    
  Serial.println(stringOne);      // prints "Hello String"

This is not working also.

String SD_lon = "invalid";
......
......... // put the separated longitude data in SD_lon
Serial.println(SD_lon);

The code stops after the first output. Any clue? please

Hello,

I have started over the gps data separation & this time using the basic functions of TinyGPS

#include "TinyGPS.h"
#include <SoftwareSerial.h>
TinyGPS gps; // create a TinyGPS object
SoftwareSerial nss(4, 5); // serial port for GPS Tx(4)

void setup()
{
  Serial.begin(115200); // PC<---> arduino 115200 baud
  nss.begin(9600); // GPS---> arduino at 9600 baud
}

void loop()
{
  while (nss.available())
  {
    int c = nss.read(); //Read the GPS serial port
    // Encode() each byte
    // Check for new position if encode() returns "True"
    if (gps.encode(c))
    {
      long lat, lon;  // variables for storing lat & lon data
      gps.get_position(&lat, &lon); // TinyGPS function for aquiring positional information
      Serial.println(lat); // print latitude
      Serial.println(lon); // print longitude
      delay(500);
    }
  }
}

This code is working correctly but the returned lat & lon value are integers. It contains 8 digits. I tried to divide the long value by by 10^6 so that the output will be like 12.345678. But the value returns only the integer part "12". then realised that the "long" is itself an integer.

lat = lat / 1000000;
      lon = lon / 1000000;
      Serial.println(lat); // print latitude
      Serial.println(lon); // print longitude

Then I tried float but the result is 12.00 instead os 12.345678

    if (gps.encode(c))
    {
      long lat, lon;  // variables for storing lat & lon data
      gps.get_position(&lat, &lon); // TinyGPS function for aquiring positional information
      float flat = lat / 1000000;
      float flon = lon / 1000000;
      Serial.println(flat); // print latitude
      Serial.println(flon); // print longitude
      delay(500);
    }

Trying to seperate the data without using any String function. How to shift the decimal points? any functions?

You are not going to get any help until you learn that string and String are not anywhere near the same thing. They are not interchangeable.

When you decide whether you want to use Strings or strings, let us know. But don't expect that using both is going to be easy.

I would recommend not using the String class on the Arduino.

The other problem, is that %f for floats doesn't work in the sprintf() function ( unless someone has fixed it recently and I didn't notice ), so you need to work around that.

The easiest way is to use longs ( 4 byte integers ), multiply the float longitude by 100000 or 1000000 and then send the result as a (long) integer.

So 90.246 degrees west becomes -90246000 which fits in a long integer. And if you want it to work quicker, there is nothing stopping you from sending it as 4 binary bytes instead of about 9 char bytes.

PaulS:
You are not going to get any help until you learn that string and String are not anywhere near the same thing. They are not interchangeable.

When you decide whether you want to use Strings or strings, let us know. But don't expect that using both is going to be easy.

Thanks for motivation & apologies for my ignorance. I shall not repeat the same mistake of calling a String a string. Gone through a few discussions in stackoverflow pages. I read 100% of the discussions & honestly understood only about 10%. Any good website for this topic with plenty of basic tutorials? First time dealing with Strings & arrays. I am trying, trust me.

michinyon:
The other problem, is that %f for floats doesn't work in the sprintf() function ( unless someone has fixed it recently and I didn't notice ), so you need to work around that.

The easiest way is to use longs ( 4 byte integers ), multiply the float longitude by 100000 or 1000000 and then send the result as a (long) integer.

So 90.246 degrees west becomes -90246000 which fits in a long integer. And if you want it to work quicker, there is nothing stopping you from sending it as 4 binary bytes instead of about 9 char bytes.

Thanks for your suggestion. I'll make these changes & update accordingly.
Thanks again for your help.

multiply the float longitude

The values lat & lon returned by the gps.get_position(&lat, &lon); functions are stored in long integers lat and lon which are the values like 12345678.

Now I put the values into a float variable

float flat = lat; // flat becomes a floating value 12345678
 flat = flat/1000000; //then divide the value by 1000000 to get a value like 12.345678
Serial.print(flat); //but the actual returned value is 12.34

I used double to assign flat & the result still shows 12.34
Sorry If I cant get your explanation correctly.
Thanking you in anticipation.

try

Serial.print(flat,4);

wildbill:
try

Serial.print(flat,4);

Whoever said this, said it correct... " Big things come in small packages"
One line solution. Thanks a lot. Thanks for the quick tweak. I shall remember this decimal point technique. I changed the floating numbers from 4 t0 6 & the output is exactly what I expected. I have put a small if statement to determine N, S, E & W.

#include "TinyGPS.h"
#include <SoftwareSerial.h>
TinyGPS gps; // create a TinyGPS object
SoftwareSerial nss(4, 5); // serial port for GPS Tx(4)

void setup()
{
  Serial.begin(115200); // PC<---> arduino 115200 baud
  nss.begin(9600); // GPS---> arduino at 9600 baud
}

void loop()
{
  while (nss.available())
  {
    int c = nss.read(); //Read the GPS serial port
    // Encode() each byte
    // Check for new position if encode() returns "True"
    if (gps.encode(c))
    {
      long lat, lon;  // variables for storing lat & lon data
      gps.get_position(&lat, &lon); // TinyGPS function for aquiring positional information
      float flon = lon; // copy the value in a float variable to get fractional value
      float flat = lat; //  ---------------------\\-------------------------------
      flon = flon/1000000;
      flat = flat/1000000;
      Serial.print(flat, 6); // print latitude
      if(flat>0) Serial.println("*N");
      else  Serial.println("*S");
      Serial.print(flon, 6); // print longitude
      if(flon>0) Serial.println("*E");
      else  Serial.println("*W");
      delay(500);
    }
  }
}

Next step will be separating the date & time & then wrapping it to a String & send via RF. I'll update the progress here.
My deepest gratitude. Thanks for the help Wildbill. :slight_smile:

Well if they are already in a long variable, don't change them to a float and then back to long. Just use the long values which TinyGPS will provide you with. It was implemented that way precisely to get around the problems which you have encountered.

Thanks michinyon for your response :slight_smile:
Do you mean sending the raw long data via TX node & doing the data acquisition & formatting at the RX node?

Next step will be separating the date & time & then wrapping it to a String

Do yourself a favor and do NOT use a String. The same can be accomplished using sprintf() and a char array without the wastefulness of the String class.

Thanks for your suggestion Paul. I am using the sprintf() function.
added 2 things to the previous sketch... 1. extracting date & time, 2. adding the RF433 TX module

#include "TinyGPS.h"
#include <SoftwareSerial.h>
#include <VirtualWire.h>

TinyGPS gps; // create a TinyGPS object
SoftwareSerial nss(4, 5); // serial port for GPS Tx(4)
char gpsdata[27];// The String that we are going to send trought rf
void setup()
{
  Serial.begin(9600); // PC<---> arduino 9600 baud
  nss.begin(9600); // GPS---> arduino at 9600 baud
  vw_setup(2000); // Bits per sec
  vw_set_tx_pin(12);// Set the Tx pin. Default is 12
}

void loop()
{
  while (nss.available())
  {
    int c = nss.read(); //Read the GPS serial port
    // Encode() each byte
    // Check for new position if encode() returns "True"
    if (gps.encode(c))
    {
      long lat, lon;  // variables for storing lat & lon data
      gps.get_position(&lat, &lon); // TinyGPS function for aquiring positional information
     /* float flon = lon; // copy the value in a float variable to get fractional value
      float flat = lat; //  ---------------------\\-------------------------------
      flon = flon/1000000;
      flat = flat/1000000;
      Serial.print(flat, 6); // print latitude
      if(flat>0) Serial.println("*N");
      else  Serial.println("*S");
      Serial.print(flon, 6); // print longitude
      if(flon>0) Serial.println("*E");
      else  Serial.println("*W");*/
      Serial.println(lat);
      Serial.println(lon);
      delay(500);
      print_date(gps); // function for extracting date time, taken from TinyGPS test_with_gps_device example
      vw_send((uint8_t *)gpsdata, strlen(gpsdata));
      vw_wait_tx(); // Wait until the whole message is gone
      delay(40);
      sprintf(gpsdata, "%d,%d", lat,lon); // put these values in gpsdata
      Serial.println(gpsdata);
    }
  }
}

static void print_date(TinyGPS &gps) // Function for date-time
{
  int year;
  byte month, day, hour, minute, second, hundredths;
  unsigned long age;
  gps.crack_datetime(&year, &month, &day, &hour, &minute, &second, &hundredths, &age);
  if (age == TinyGPS::GPS_INVALID_AGE)
    Serial.print("********** ******** ");
  else
  {
    char sz[32];
    sprintf(sz, "%02d/%02d/%02d %02d:%02d:%02d ",
        month, day, year, hour, minute, second);
    Serial.println(sz);
  }
//  print_int(age, TinyGPS::GPS_INVALID_AGE, 5);
//  smartdelay(0);
}

The TX & RX modules work fine & I can see the wrong data in RX node via serial monitor.
Then I put a short code to see what is actually happening in the TX node.

Serial.println(lat);
Serial.println(lon);
sprintf(gpsdata, "%d,%d", lat,lon); // put these values in gpsdata      
Serial.println(gpsdata);

As I expected, the error is originated in TX node. The printed value of gpsdata is not similar to lat & lon data.

The output on the highlighted area is expected to be like this... 22504388, 88383837 instead of 25540,343
Is %d wrong in case of long variables?
vw_send((uint8_t *)gpsdata, strlen(gpsdata)); it represents unsigned integers but the lat & lon data are long & can be signed. In that case should the vw_send be altered? But according to the vwire library the standard format is vw_send((uint8_t )gpsdata, strlen(gpsdata));. Cannot understand this uint_8 ang long variable conflict. I have used this tutorial for Rf communication & sprintf() construction.

Thanks for your guidance.

Is %d wrong in case of long variables?

Yes. IIRC, you need %ld

Here's a hint. The %d format specifier is used for what? Not longs.

PaulS:
Here's a hint. The %d format specifier is used for what? Not longs.

According to the tutorial %d is the signed decimal integer specifier & as wildbill suggested, now I learn that %ld stands for signed long decimal integers.

Yes, the "gpsdata" is now printing the desired value after making the specifier alterations. :slight_smile:

Altered a couple of lines in the code to see what happens if I put a signed long into the unsigned integer array

      long dlon = -15854201;
      sprintf(gpsdata, "%ld,%ld", lat,dlon); // put these values in gpsdata
      Serial.println(gpsdata);

The result is 22504063,-15854201 in RX node.
it means both the
vw_send((uint8_t )gpsdata, strlen(gpsdata)); and uint8_t buf[VW_MAX_MESSAGE_LEN]; are containing signed decimal longs. Then what is the significance of uint8_t ?

Suddenly the date becomes 00/00/2000


Any clues?

Altered a couple of lines in the code to see what happens if I put a signed long into the unsigned integer array

That's not what sprintf() does. It put the string representation of the signed long in the character array (or unsigned byte array).

it means both the ... are containing signed decimal longs.

Not at all. It means that they are containing string representations of signed longs.

Suddenly the date becomes 00/00/2000

Looks you have a buffer overflow problem.

Thanks for the clarifications. I need to practice more to assimilate these informations. :slight_smile:
Further modified the TX sketch & added the timezone adjustments & finally printed the time using the sprintf() function in tx node.
The output is...

I am expecting the highlighted output in the RX node but at the RX node I'm getting nothing. Only a blank serial monitor. It only happens if I include the time related information in the Tx array
Tx node

sprintf(gpsdata,"%ld,%ld,%s",lat,lon,sz); // put these values in gpsdata

RX node

sscanf(StringReceived,"%ld,%ld,%s",&lat,&lon,&sz); // Converts a string to an array

But the code works fine when I do print only the long variables in the RX node
TX array

 sprintf(gpsdata,"%ld,%ld",lat,lon); // put these values in gpsdata

RX array

sscanf(StringReceived,"%ld,%ld",&lat,&lon); // Converts a string to an array

The full code is here
GPS_TX

#include "TinyGPS.h"
#include <SoftwareSerial.h>
#include <VirtualWire.h>

TinyGPS gps; // create a TinyGPS object
SoftwareSerial nss(4, 5); // serial port for GPS Tx(4)
char gpsdata[27];// The String that we are going to send trought rf
char sz[10];
void setup()
{
  Serial.begin(9600); // PC<---> arduino 115200 baud
  nss.begin(9600); // GPS---> arduino at 9600 baud
  vw_setup(2000); // Bits per sec
  vw_set_tx_pin(12);// Set the Tx pin. Default is 12
}

void loop()
{
  while (nss.available())
  {
    int c = nss.read(); //Read the GPS serial port
    // Encode() each byte Check for new position if encode() returns "True"
    if (gps.encode(c))
    {
      long lat, lon;  // variables for storing lat & lon data
      gps.get_position(&lat, &lon); // TinyGPS function for aquiring positional information
      float flon = lon; // copy the value in a float variable to get fractional value
      float flat = lat; //  ---------------------\\-------------------------------
      flon = flon/1000000;
      flat = flat/1000000;
      Serial.print(flat, 6); // print latitude
      if(flat>0) Serial.println("*N");
      else  Serial.println("*S");
      Serial.print(flon, 6); // print longitude
      if(flon>0) Serial.println("*E");
      else  Serial.println("*W");
     /* Serial.println(lat);
      Serial.println(lon);*/
      delay(500);
      print_date(gps); // function for extracting date time, taken from TinyGPS test_with_gps_device example
      vw_send((uint8_t *)gpsdata, strlen(gpsdata));
      vw_wait_tx(); // Wait until the whole message is gone
      delay(40);
      sprintf(gpsdata,"%ld,%ld,%s",lat,lon,sz); // put these values in gpsdata
 //     sprintf(gpsdata,"%ld,%ld",lat,lon); // put these values in gpsdata
      Serial.println(gpsdata);
    }
  }
}

static void print_date(TinyGPS &gps) // Function for date-time
{
  int year;
  byte month, day, hour, minute, second, hundredths;
  unsigned long age;
  gps.crack_datetime(&year, &month, &day, &hour, &minute, &second, &hundredths, &age);
  /*if (age == TinyGPS::GPS_INVALID_AGE)
    Serial.print("********** ******** ");
  else
  {*/
  second = second + 00;
  minute = minute + 30;
  if (minute > 59){
    minute = minute - 60;
    hour = hour + 01;
  }
  hour = hour + 05;
  if (hour > 23)  hour = hour - 24;
   // char sz[32];
    //sprintf(sz, "%02d/%02d/%02d %02d:%02d:%02d ", month, day, year, hour, minute, second);
    sprintf(sz, "%02d:%02d:%02d ", hour, minute, second);
    Serial.println(sz);
  //}
//  print_int(age, TinyGPS::GPS_INVALID_AGE, 5);
//  smartdelay(0);
}

GPS_RX

#include <VirtualWire.h>
  
// Sensors
long lat;
long lon;  // variables for storing lat & lon data
char sz[10];  
char StringReceived[27];
  
void setup() {
    Serial.begin(9600);
    vw_setup(2000);     // Bits per sec
    vw_set_rx_pin(11); // Set the RX pin
    vw_rx_start();    // Start the receiver PLL running
}

void loop(){
    uint8_t buf[VW_MAX_MESSAGE_LEN];  // set buffer
    uint8_t buflen = VW_MAX_MESSAGE_LEN; // set buffer length
      
    if (vw_get_message(buf, &buflen)){//Taking the data from the control base
     int i;   // Message with a good checksum received, dump it.
        for (i = 0; i < buflen; i++)
 {           
          // Fill Sensor1CharMsg Char array with corresponding chars from buffer.  
          StringReceived[i] = char(buf[i]);
 }
   // sscanf(StringReceived, "%ld,%ld",&lat,&lon); // Converts a string to an array
    sscanf(StringReceived,"%ld,%ld,%s",&lat,&lon,&sz); // Converts a string to an array
    Serial.println(lat);
    Serial.println(lon);
    Serial.println(sz);
    delay(200);      
    }
 memset( StringReceived, 0, sizeof( StringReceived));// This line is for reset the StringReceived
}

According to the datasheet

Messages of up to VW_MAX_PAYLOAD (27) bytes can be sent

I think I am missing something.