Skip to content

Commit

Permalink
fixed hang condition in startup Hint screen
Browse files Browse the repository at this point in the history
The GPS data logger history buffer was too large, causing memory problems. Reduced size from 'history[1600]' to 'history[1500]'. Change file signature to v11, to force everyone to rewrite new GPS data log.
  • Loading branch information
barry-ha committed Jun 8, 2022
1 parent 008e4c8 commit 8a878f0
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 23 deletions.
2 changes: 1 addition & 1 deletion Griduino.ino
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ int gFrequency = 1100; // initial Morse code sidetone pitch
int gWordsPerMinute = 18; // initial Morse code sending speed

// ------------ definitions
const int howLongToWait = 5; // max number of seconds at startup waiting for Serial port to console
const int howLongToWait = 6; // max number of seconds at startup waiting for Serial port to console

// ---------- Morse Code ----------
#include "morse_dac.h" // Morse Code using digital-audio converter DAC0
Expand Down
84 changes: 67 additions & 17 deletions model_gps.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,30 @@ class Model {

float gSeaLevelPressure = DEFAULT_SEALEVEL_HPA; // default starting value, hPa; adjustable by touch in view_altimeter.h

Location history[1600]; // remember a list of GPS coordinates
int nextHistoryItem = 0; // index of next item to write
const int numHistory = sizeof(history) / sizeof(Location);
// Size of array history: Our goal is to keep track of a good day's travel, at least 250 miles.
// If 180 pixels horiz = 100 miles, then we need (250*180/100) = 450 entries.
// If 160 pixels vert = 70 miles, then we need (250*160/70) = 570 entries.
// In reality, with a drunken-sailor route around the Olympic Peninsula,
// we need 800 entries to capture the 500-mile loop.
// we need at least 800 entries to capture the 500-mile loop.
// However, Arduino has memory problems if there history[] array is too large.
//
// y = mx + b = 24x + 78 where y=total size in bytes, x=number of 'history[]' elements
//
// history[x] sizeof(modelGPS) sizeof(history) result
// x= 800, 19,336 bytes . no trouble found
// x=1300, 31,396 . ntf
// x=1400, 33,736 > 32767 . ntf
// x=1500, 36,136 >> 32767 36,000 ntf
// x=1550, 37,336 >> 32767 37,200 ntf
// x=1565, 37,696 37,560 ntf
// x=1573, 37,888 37,752 ntf
// x=1576, 37,960 37,824 hang on startup hint screen
// x=1580, 38,056 37,920 hang on startup hint screen
// x=1600, 38,632 38,400 hang on startup hint screen
// x=3200, xx xx hang on startup product version credits screen
Location history[1500]; // remember a list of GPS coordinates -- DO NOT EXCEED 1573!
int nextHistoryItem = 0; // index of next item to write
const int numHistory = sizeof(history) / sizeof(Location);

protected:
int gPrevFix = false; // previous value of gHaveGPSfix, to help detect "signal lost"
Expand All @@ -73,8 +89,8 @@ class Model {
}

// ========== load/save config setting =========================
const char MODEL_FILE[25] = "/Griduino/gpsmodel.cfg"; // CONFIG_FOLDER
const char MODEL_VERS[15] = "GPS Model v10"; // <-- always change version when changing model data
const char MODEL_FILE[25] = CONFIG_FOLDER "/gpsmodel.cfg"; // CONFIG_FOLDER
const char MODEL_VERS[15] = "GPS Model v11"; // <-- always change version when changing model data

// ----- save user's GPS state to non-volatile memory -----
int save() {
Expand All @@ -92,12 +108,22 @@ class Model {
int restore() {
// restore current GPS state from non-volatile memory
SaveRestore sdram(MODEL_FILE, MODEL_VERS);
Model tempModel;

extern Model modelGPS; // debug
Model tempModel; // temp buffer for restoring the "Model" object from RAM file system

Serial.print(". source: sizeof(tempModel) = ");
Serial.println(sizeof(tempModel));
Serial.print(". target: sizeof(modelGPS) = ");
Serial.println(sizeof(modelGPS));
Serial.print(". GPS history buffer, sizeof(history) = ");
Serial.println(sizeof(history));

if (sdram.readConfig((byte *)&tempModel, sizeof(Model))) {
// warning: this can corrupt our object's data if something failed
// so we blob the bytes to a work area and copy individual values
Serial.println("Success, GPS Model restored from SDRAM");
copyFrom(tempModel);
Serial.println("Success, GPS Model restored from SDRAM");
} else {
Serial.println("Error, failed to restore GPS Model object to SDRAM");
return 0; // return failure
Expand All @@ -109,8 +135,6 @@ class Model {

// pick'n pluck values from the restored instance
void copyFrom(const Model from) {
// return; // debug

gLatitude = from.gLatitude; // GPS position, floating point, decimal degrees
gLongitude = from.gLongitude; // GPS position, floating point, decimal degrees
gAltitude = from.gAltitude; // Altitude in meters above MSL
Expand All @@ -123,19 +147,45 @@ class Model {
compare4digits = from.compare4digits; //
gSeaLevelPressure = from.gSeaLevelPressure; // hPa

Serial.print(". Copying ");
Serial.print(numHistory);
Serial.println(" items from saved GPS history");

for (int ii = 0; ii < numHistory; ii++) {
history[ii] = from.history[ii];
// printLocation(ii, from.history[ii]); // debug
history[ii].loc = from.history[ii].loc; // copy contents
history[ii].timestamp = from.history[ii].timestamp;
}

Serial.print(". nextHistoryItem = ");
Serial.println(from.nextHistoryItem);
nextHistoryItem = from.nextHistoryItem;
if (nextHistoryItem >= numHistory) {
char msg[256];
snprintf(msg, sizeof(msg), ". Error! Expected nextHistoryItem < %d but got %d",
numHistory, nextHistoryItem);
Serial.println(msg);
nextHistoryItem = 0; // reset index, ignore restored erroneous value
}
}

// sanity check data from NVR
void printLocation(int ii, Location item) {
Serial.print(". lat/long[");
Serial.print(ii);
Serial.print("] = ");
Serial.print(item.loc.lat);
Serial.print(", ");
Serial.println(item.loc.lng);
}

// read GPS hardware
virtual void getGPS() { // "virtual" allows derived class MockModel to replace it
if (GPS.fix) { // DO NOT use "GPS.fix" anywhere else in the program,
// or the simulated position in MockModel won't work correctly
gLatitude = GPS.latitudeDegrees; // double-precision float
gLongitude = GPS.longitudeDegrees;
gAltitude = GPS.altitude;
virtual void getGPS() { // "virtual" allows derived class MockModel to replace it
if (GPS.fix) { // DO NOT use "GPS.fix" anywhere else in the program,
// or the simulated position in MockModel won't work correctly
gLatitude = GPS.latitudeDegrees; // double-precision float
gLongitude = GPS.longitudeDegrees;
gAltitude = GPS.altitude;
// save timestamp as compact 4-byte integer (number of seconds since Jan 1 1970)
// using https://github.com/PaulStoffregen/Time
TimeElements tm{GPS.seconds, GPS.minute, GPS.hour, 0, GPS.day, GPS.month, GPS.year};
Expand Down
6 changes: 3 additions & 3 deletions save_restore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ static void dumpHex(const char *text, char *buff, int len) {
}

// ========== load configuration ======================
int SaveRestore::readConfig(byte *pData, const int sizeData) {
int SaveRestore::readConfig(byte *pData, const unsigned int sizeData) {
// returns 1=success, 0=failure
int result = 1; // assume success
Serial.println("Starting to read config from SDRAM...");
Expand Down Expand Up @@ -123,7 +123,7 @@ int SaveRestore::readConfig(byte *pData, const int sizeData) {
}
// data looks good, read third field (setting) and use its value
count = readFile.read(pData, sizeData);
dumpHex("pData", (char *)pData, sizeData); // debug
// dumpHex("pData", (char *)pData, sizeData); // debug
if (count == -1) {
Serial.print("Error, failed to read integer value from (");
Serial.print(fqFilename);
Expand All @@ -142,7 +142,7 @@ int SaveRestore::readConfig(byte *pData, const int sizeData) {
return result;
}
// ========== save configuration ======================
int SaveRestore::writeConfig(const byte *pData, const int sizeData) {
int SaveRestore::writeConfig(const byte *pData, const unsigned int sizeData) {
// initialize configuration file in file system, called by setup() if needed
// assumes this is Feather M4 Express with 2 MB Quad-SPI flash memory
// returns 1=success, 0=failure
Expand Down
4 changes: 2 additions & 2 deletions save_restore.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,12 @@ class SaveRestore {
/*
* Save our class data to SDRAM
*/
int writeConfig(const byte *pBuffer, const int sizeBuffer);
int writeConfig(const byte *pBuffer, const unsigned int sizeBuffer);

/*
* Load our class data from SDRAM
*/
int readConfig(byte *pBuffer, const int sizeBuffer);
int readConfig(byte *pBuffer, const unsigned int sizeBuffer);

/*
* List files in SDRAM
Expand Down

0 comments on commit 8a878f0

Please sign in to comment.