I don't see the current system configuration, so I don't know what the receiving HC-12 is connected to... but if it connected to an Arduino, you should not be sending the NMEA sentences. As I have said multiple times, just send the fix structure (31 bytes) instead of ~150 bytes of two reconstructed NMEA sentences. It's doubly silly to parse the raw characters and then send a reconstructed version.
The whole point of providing you with the NMEAprint routines was so that you could send fix structures Over The Air and then emit reconstructed NMEA sentences at the receiver. Instead of this:
void loop() {
while (gps.available()) {
fix = gps.read();
NMEAprintRMC( &DEBUG_PORT, fix ); // These could be too much to print!
NMEAprintGGA( &DEBUG_PORT, fix ); // This will delay your sketch by about 90ms.
NMEAprintRMC( &HC12, fix ); // Don't send raw NMEA! This will also delay your sketch.
NMEAprintGGA( &HC12, fix );
}
... just do this on the transmitter:
void loop() {
while (gps.available()) {
fix = gps.read();
HC12.print( F("FIX=") ); // A "start marker" that the receiver can watch for...
HC12.write( (uint8_t *) &fix, sizeof(fix) ); // Transmit binary structure to remote
}
This short message will not delay your sketch at all. The message will be sent in the background, and your sketch can continue to do other things.
- NOTE: You can add all kinds of things to make this short transmission more reliable, since the HC12 doesn't do that for you. Checksums, error detection and correction codes, go crazy.On the receiver, you simply read the 31 bytes into a fix structure after receiving the special "FIX=" start marker. Then use the NMEAprint routines to emit the reconstructed NMEA sentences. Something like this on the receiver:
enum receiverState_t { WAITING_FOR_FIX, RECEIVING_FIX };
receiverState_t receiverState = WAITING_FOR_FIX;
const char startMarker[] = "FIX=";
size_t startCount = 0;
gps_fix fix; // loaded with received bytes
size_t fixCount; // the count of received bytes
void loop()
{
if (HC12.available()) {
char c = HC12.read();
switch (receiverState) {
case WAITING_FOR_FIX:
// Did we receive the next character of the start marker?
if (startMarker[ startCount ] == c) {
startCount++;
// Yes, is this the whole start marker?
if (startCount == sizeof(startMarker)-1) {
// Yes, the next bytes are the binary fix structure
receiverState = RECEIVING_FIX;
fixCount = 0;
}
} else {
// The character didn't match, start over...
startCount = 0;
}
break;
case RECEIVING_FIX:
{
// Save the next received byte into the local fix structure
uint8_t *fixBytes = (uint8_t *) &fix; // an "alias" for the fix structure's memory bytes
fixBytes[ fixCount++ ] = c; // increments the counter, too
if (fixCount >= sizeof(fix)) {
// Complete fix received! Print reconstructed NMEA sentences from the fix.
NMEAprintRMC( &DEBUG_PORT, fix );
NMEAprintGGA( &DEBUG_PORT, fix );
// Restart the process
receiverState = WAITING_FOR_FIX;
startCount = 0;
}
}
break;
} // end switch
}
}
This is similar to the Serial Input Basics tutorial in that it watches for a special start string and then gradually accumulates bytes (in the fix
memory bytes). When the required count of bytes has been received, the fix structure has been completely filled out. No NMEA parsing required, because all of that was performed at the transmitter. The fix structure can be used for whatever purpose at the receiver, including recreating the original (verbose) NMEA character stream.
Both NMEAprint routines use the same method to print CR/LF (aka '\r' and '\n'), so the HC12 transmission might be dropping a byte. I don't see any receiver code (or the system connections), so I can't suggest why a LF is being dropped somewhere. Of course, adding some kind of error detection to the transmitted message would have told you for sure... :-/