GPS/Morse code transmitter help needed

Looking for some help - noob to coding.
I am trying to transmit serial (read: gps) data via morse code over an external rf transmitter. The morse works fine, however when I try to read the serial data from the GPS, no go. I have been able to simultaneously read the proper lat/long (in one of my versions of this code) but have never been able to get it to work with the morse transmitter. Any ideas?

Yes I am a hack coder, this is put together from a variety of different code I have come across. :slight_smile: FYI the audio output pumped right into a NFM transmitter works quite well...

#include "TinyGPS.h"

TinyGPS gps;

float flat, flon;
unsigned long fix_age, time, date, speed, course;
unsigned long chars;
unsigned short sentences, failed_checksum;

void getgps(TinyGPS &gps);

// Start of Morse Code Generator //
struct t_mtab { char a, pat; } ;

struct t_mtab morsetab[] = {
        {'.', 106},
      {',', 115},
      {'?', 76},
      {'/', 41},
      {'A', 6},
      {'B', 17},
      {'C', 21},
      {'D', 9},
      {'E', 2},
      {'F', 20},
      {'G', 11},
      {'H', 16},
      {'I', 4},
      {'J', 30},
      {'K', 13},
      {'L', 18},
      {'M', 7},
      {'N', 5},
      {'O', 15},
      {'P', 22},
      {'Q', 27},
      {'R', 10},
      {'S', 8},
      {'T', 3},
      {'U', 12},
      {'V', 24},
      {'W', 14},
      {'X', 25},
      {'Y', 29},
      {'Z', 19},
      {'1', 62},
      {'2', 60},
      {'3', 56},
      {'4', 48},
      {'5', 32},
      {'6', 33},
      {'7', 35},
      {'8', 39},
      {'9', 47},
      {'0', 63}
} ;

#define N_MORSE  (sizeof(morsetab)/sizeof(morsetab[0]))

#define SPEED  (200)
#define DOTLEN  (1200/SPEED)
#define DASHLEN  (3*(1200/SPEED))

int LEDpin = 13 ;
int SPKpin = 9 ;   /* PWM output */

#define VOLUME 64

void
dash()
{
  digitalWrite(LEDpin, HIGH) ;
  analogWrite(SPKpin, VOLUME) ;
  delay(DASHLEN);
  digitalWrite(LEDpin, LOW) ;
  analogWrite(SPKpin, 0) ;
  delay(DOTLEN) ;
}

void
dit()
{
  digitalWrite(LEDpin, HIGH) ;
  analogWrite(SPKpin, VOLUME) ;
  delay(DOTLEN);
  digitalWrite(LEDpin, LOW) ;
  analogWrite(SPKpin, 0) ;
  delay(DOTLEN);
}

void
send(char a)
{
  int i ;
  if (a == ' ') {
    Serial.print(a) ;
    delay(7*DOTLEN) ;
    return ;
  }
  for (i=0; i<N_MORSE; i++) {
    if (morsetab[i].a == a) {
      unsigned char p = morsetab[i].pat ;
     Serial.print(morsetab[i].a) ; //- Killed echo back to serial

      while (p != 1) {
          if (p & 1)
            dash() ;
          else
            dit() ;
          p = p / 2 ;
      }
      delay(2*DOTLEN) ;
      return ;
    }
  }
  /* if we drop off the end, then we send a space */
  Serial.print("?") ;
}

void
sendmsg(char *str)
{
  while (*str)
    send(*str++) ;
  Serial.println(""); //-- Killed LF back to serial
}

void setup() {
  pinMode(LEDpin, OUTPUT) ;
  pinMode(SPKpin, OUTPUT) ;
  Serial.begin(4800) ;
 
}

void loop() {
//   if (Serial.available() > 0){ 
  char c = Serial.read();

    if (gps.encode(c))
    {
      gps.f_get_position(&flat, &flon, &fix_age);
      gps.get_datetime(&date, &time, &fix_age);

/*      sendmsg(flat);   <---- does not work, want to transmit Lat/Long wia morse code using above code. 
        sendmsg(flon);   <---- sendmsg wants char, not float.......
*/      Serial.print("LAT: ");
      Serial.println(flat, 5);  
      Serial.print("LONG: ");
      Serial.println(flon, 5);
    }
  
  sendmsg("THIS IS A TEST OF THE MORSE CODE DECODER") ;
  delay(3000) ;
// This code directly above will send the message at 200WPM 100% of the time

   
  }
   }
/*      sendmsg(flat);   <---- does not work, want to transmit Lat/Long wia morse code using above code.
        sendmsg(flon);   <---- sendmsg wants char, not float.......

So why don't you convert flat to a char array? In C, one would use sprintf() with a %f format specifier, to convert the float to a string. Unfortunately, the %f specifier is not supported on the Arduino.

So, convert the float to two integers, and convert them to a string.

int whole = flat;
int frac = ((float)(flat - whole) + 0.00005)*10000;

The flat - whole portion gets the fractional portion of flat. The + 0.00005 portion is to round rather than truncate the value. The *10000 part makes a 4 digit number.

If flat was 12.56789, whole will be 12. Then, flat - whole will be 0.56789, Adding 0.00005 results in 0.56794. Multiplying by 10000 results in 5679 being stored in frac.

Then,

char flatStg[24];
sprintf(flatStg, "%d.%.4d", whole, frac);

will result in "12.5679" being stored in flatStg, which you can then use as an argument to sendmsg().

The %.4d says to print the value in not less than 4 characters, filling with leasing 0's as required. Had flat contained 12.00789, whole would have contained 79. Print frac and whole using %d.%d would have resulted in "12.79" being stored in the string, instead of "12.0079".