GPS not updating with certain codes

I am testing the GPS shield on a MKR1000. Apparently, Serial.write(reinterpret_cast<char*>(dataArray, 20)); is the problem for some reason. This is the code that doesn't run:

#include <Arduino_MKRGPS.h>
#include <string.h>
#include <"gps_101.h path here">
//#include <avr/dtostrf.h>

float latitude   = GPS.latitude();
float longitude  = GPS.longitude();
float altitude   = GPS.altitude();
float speed      = GPS.speed();
//int   satellites = GPS.satellites();
char* dataArray[1024];
//byte fBuffer[4];
//char  nBuffer[8] = "";

void setup() {
  // initialize serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect.
  }
  if (!GPS.begin(GPS_MODE_SHIELD)) {
    Serial.write("Failed to initialize GPS!");
    while (1);
  }
  
  else {Serial.write("GPS initialized");
  }
}

void loop() {
//  delay(200);
  // check if there is new GPS data available
  if (GPS.available()) {
    // read GPS values
//    float 
latitude   = GPS.latitude();
//    float 
longitude  = GPS.longitude();
//    float 
altitude   = GPS.altitude();
//    float 
speed      = GPS.speed();
//    int   
//satellites = GPS.satellites();

    // print GPS values
    to_Bytes(&latitude,dataArray,0);
    to_Bytes(&longitude,dataArray,4);
    to_Bytes(&altitude,dataArray,8);
    to_Bytes(&speed,dataArray,12);
    //    byte fBuffer[32] = { 
//    ((uint8_t*)&latitude)[0], ((uint8_t*)&latitude)[1], 
//    ((uint8_t*)&latitude)[2], ((uint8_t*)&latitude)[3],
//    ((uint8_t*)&longitude)[0], ((uint8_t*)&longitude)[1],
//    ((uint8_t*)&longitude)[2], ((uint8_t*)&longitude)[3],
//    ((uint8_t*)&altitude)[0], ((uint8_t*)&altitude)[1],
//    ((uint8_t*)&altitude)[2], ((uint8_t*)&altitude)[3],
//    ((uint8_t*)&speed)[0], ((uint8_t*)&speed)[1],
//    ((uint8_t*)&speed)[2], ((uint8_t*)&speed)[3]
//    };
//    Serial.write(dtostrf(GPS.latitude(),3,3,nBuffer)); //Latitude
//    Serial.write(dtostrf(GPS.longitude(),3,3,nBuffer)); //Longitude
//    Serial.write(dtostrf(GPS.altitude(),5,3,nBuffer)); //Altitude 
//    Serial.write(dtostrf(GPS.speed(),3,3,nBuffer)); //Ground speed
    Serial.write(reinterpret_cast<char*>(dataArray, 20));
  }
  
//debug
//  else {
//    Serial.write("Pending data\n");
//  }
}

If I un-comment this part and other parts needed to run this snippet:

//    Serial.write(dtostrf(GPS.latitude(),3,3,nBuffer)); //Latitude
//    Serial.write(dtostrf(GPS.longitude(),3,3,nBuffer)); //Longitude
//    Serial.write(dtostrf(GPS.altitude(),5,3,nBuffer)); //Altitude 
//    Serial.write(dtostrf(GPS.speed(),3,3,nBuffer)); //Ground speed

and not using the to_Bytes function, then the code runs normally and GPS data is returned.

The gps_101.h file:

#ifndef gps_101_h
#define gps_101_h

template <typename T>
void to_Bytes(T* object, char* data, int startIdx);

#endif

The file with function:

#include <"gps_101.h path here">

template <typename T>
void to_Bytes(T* object, char* data[1024], int startIdx) {
    memcpy(&data[startIdx], object, sizeof(T));
}

The purpose of this function is to replace a data of any type to an array of bytes to be written to serial.
Video for demonstration of the problem (it will expire eventually so please understand): https://files.catbox.moe/kqogyc.mp4
Any hint on why the top code doesn't return anything is appreciated.

Can the GPS antenna see satellites or only the ceiling of the room ?

strange file extention

I can assure you hardware setup is not a problem.
Here is a video screen capture: https://files.catbox.moe/kqogyc.mp4
Running this again, I think that Serial.write(reinterpret_cast<char*>(dataArray, 20)); part is the problem. I'll update my post accordingly.

Reply to myself because I found the problem. It should be:
Serial.write(reinterpret_cast<char*>(dataArray), 20);
not
Serial.write(reinterpret_cast<char*>(dataArray, 20));

Can you explain why you are copying the binary float values to an array of char pointers in order to write the data to Serial? Would make more sense to me to use an array of uint8_t (unsigned char or byte), since each char pointer occupies more than a single byte of storage, making it more difficult to determine the correct offsets within the array.

The issue in your code is with the declaration of the dataArray variable. You have declared it as an array of pointers to char, which is not what you want. Instead, you should declare it as an array of char with a fixed size of 20 bytes.

Replace this line:

char* dataArray[1024];

with this line:

char dataArray[20];

Also, change the line where you call Serial.write() to pass the correct size of the data array:

Serial.write(reinterpret_cast<char*>(dataArray), sizeof(dataArray));

With these changes, your code should work correctly.

My intention was that I want the function to_Bytes to only modify dataArray without making a new copy of a 1024-byte array every time I call it since it will be called a lot when I continue coding.

Unfortunately this returned the following error:

Arduino: 1.8.19 (Windows 10), Board: "Arduino MKR1000"
sketch\gps_101.ino.cpp.o: In function `loop':
gps_101/gps_101.ino:47: undefined reference to `void to_Bytes<float>(float*, char*, int)'
gps_101/gps_101.ino:48: undefined reference to `void to_Bytes<float>(float*, char*, int)'
gps_101/gps_101.ino:49: undefined reference to `void to_Bytes<float>(float*, char*, int)'
gps_101/gps_101.ino:50: undefined reference to `void to_Bytes<float>(float*, char*, int)'

collect2.exe: error: ld returned 1 exit status
exit status 1
Error compiling for board Arduino MKR1000.

dataArray is not a 1024 byte array, it is an array of 1024 char pointers, which are 2 or possibly 4 bytes each, depending on the board you are using.

It's 4 bytes, so 4096 bytes. But still, I wanted a function to modify the value at that address.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.