Skip to content

Commit

Permalink
Merge pull request #6 from barry-ha/pcb-v12
Browse files Browse the repository at this point in the history
added "GPS Cold Start" feature to control panel
  • Loading branch information
barry-ha committed Feb 15, 2024
2 parents c5ba901 + f1b6be7 commit ece140f
Show file tree
Hide file tree
Showing 13 changed files with 253 additions and 26 deletions.
14 changes: 13 additions & 1 deletion Griduino.ino
Expand Up @@ -111,6 +111,7 @@
#include "cfg_audio_type.h" // config audio Morse/speech
#include "cfg_crossing.h" // config 4/6 digit crossing
#include "cfg_gps.h" // config GPS (alphabetical order)
#include "cfg_gps_reset.h" // config GPS reset to factory
#include "cfg_nmea.h" // config NMEA broadcasting
#include "cfg_reboot.h" // show firmware update option
#include "cfg_rotation.h" // config screen rotation
Expand Down Expand Up @@ -331,6 +332,7 @@ enum VIEW_INDEX {
CFG_AUDIO_TYPE, // audio output Morse/speech
CFG_CROSSING, // announce grid crossing 4/6 digit boundaries
CFG_GPS, // gps/simulator
CFG_GPS_RESET, // factory reset GPS
CFG_NMEA, // broadcast NMEA
CFG_REBOOT, // confirm reboot
CFG_ROTATION, // screen rotation
Expand Down Expand Up @@ -369,6 +371,7 @@ ViewBaro baroView(&tft, BARO_VIEW); // instantiate derived c
ViewCfgAudioType cfgAudioType(&tft, CFG_AUDIO_TYPE);
ViewCfgCrossing cfgCrossing(&tft, CFG_CROSSING);
ViewCfgGPS cfgGPS(&tft, CFG_GPS);
ViewCfgGpsReset cfgGpsReset(&tft, CFG_GPS_RESET);
ViewCfgNMEA cfgNMEA(&tft, CFG_NMEA);
ViewCfgReboot cfgReboot(&tft, CFG_REBOOT);
ViewCfgRotation cfgRotation(&tft, CFG_ROTATION);
Expand Down Expand Up @@ -396,6 +399,7 @@ void selectNewView(int cmd) {
&cfgAudioType, // [CFG_AUDIO_TYPE]
&cfgCrossing, // [CFG_CROSSING]
&cfgGPS, // [CFG_GPS]
&cfgGpsReset, // [CFG_GPS_RESET]
&cfgNMEA, // [CFG_NMEA]
&cfgReboot, // [CFG_REBOOT]
&cfgRotation, // [CFG_ROTATION]
Expand Down Expand Up @@ -441,7 +445,8 @@ void selectNewView(int cmd) {
case CFG_AUDIO_TYPE: nextView = CFG_CROSSING; break;
case CFG_CROSSING: nextView = CFG_GPS; break;
case CFG_GPS: nextView = CFG_NMEA; break;
case CFG_NMEA: nextView = CFG_UNITS; break;
case CFG_NMEA: nextView = CFG_GPS_RESET; break;
case CFG_GPS_RESET: nextView = CFG_UNITS; break;
case CFG_UNITS: nextView = CFG_ROTATION; break;
#if defined(ARDUINO_ADAFRUIT_FEATHER_RP2040)
case CFG_ROTATION: nextView = CFG_REBOOT; break;
Expand Down Expand Up @@ -687,6 +692,13 @@ void setup() {
GPS.begin(57600);
delay(50);

/****************** DANGER ****************/
// one-time usage
// Full Cold Restart: reset the receiver to the factory status
//GPS.sendCommand("$PMTK104*37\r\n");
//delay(50);
/****************** DANGER ****************/

// init Quectel L86 chip to improve USA satellite acquisition
GPS.sendCommand("$PMTK353,1,0,0,0,0*2A"); // search American GPS satellites only (not Russian GLONASS satellites)
delay(50);
Expand Down
2 changes: 1 addition & 1 deletion cfg_audio_type.h
Expand Up @@ -204,7 +204,7 @@ void ViewCfgAudioType::startScreen() {
txtSettings5[ii].print();
}

showProgressBar(2, 7); // draw marker for advancing through settings
showProgressBar(2, 8); // draw marker for advancing through settings
showScreenBorder(); // optionally outline visible area
showScreenCenterline(); // optionally draw alignment bar

Expand Down
2 changes: 1 addition & 1 deletion cfg_crossing.h
Expand Up @@ -197,7 +197,7 @@ void ViewCfgCrossing::startScreen() {
txtSettings4[ii].print();
}

showProgressBar(3, 7); // draw marker for advancing through settings
showProgressBar(3, 8); // draw marker for advancing through settings
showScreenBorder(); // optionally outline visible area
showScreenCenterline(); // optionally draw alignment bar

Expand Down
3 changes: 1 addition & 2 deletions cfg_gps.h
Expand Up @@ -87,7 +87,6 @@ class ViewCfgGPS : public View {
{"%d crumbs", col1, yRow2, cLABEL}, // [TRAILCOUNT]
{"Route", col1, yRow3, cVALUE}, // [GPSTYPE]
{PROGRAM_VERDATE, -1, yRow9, cLABEL, ALIGNCENTER}, // [COMPILED]
//{"4 of 6", xPanel, 20, cFAINT}, // [PANEL]
};
// clang-format on

Expand Down Expand Up @@ -205,7 +204,7 @@ void ViewCfgGPS::startScreen() {
tft->drawCircle(xCenter, yCenter, 7, cVALUE);
}

showProgressBar(4, 7); // draw marker for advancing through settings
showProgressBar(4, 8); // draw marker for advancing through settings
updateScreen(); // fill in values immediately, don't wait for the main loop to eventually get around to it

showScreenCenterline(); // optionally draw alignment bar
Expand Down
192 changes: 192 additions & 0 deletions cfg_gps_reset.h
@@ -0,0 +1,192 @@
#pragma once // Please format this file with clang before check-in to GitHub
/*
File: cfg_gps_reset.h
Software: Barry Hansen, K7BWH, barry@k7bwh.com, Seattle, WA
Hardware: John Vanderbeck, KM7O, Seattle, WA
Purpose: Optionally reset GPS to factory state.
User interface calls it "cold restart" but really
the GPS is completely reset to as-shipped condition.
+-------------------------------------------+
| * GPS Cold Restart > |... yRow1
| |
| If your GPS receives no satellites |... yRow2
| for hours, this action might help. |... yRow3
| +---------------+ |... yBtn
| | | |
| | Restart GPS | |... yBtn
| | | |
| +---------------+ |
| : |
| Please allow time to acquire satellites. |... yRow8 Confirmation
| v1.14, Feb 15 2024 |... yRow9
+-------------:-----------------------------+
:
xBtn
*/

#include <Adafruit_ILI9341.h> // TFT color display library
#include "constants.h" // Griduino constants and colors
#include "logger.h" // conditional printing to Serial port
#include "TextField.h" // Optimize TFT display text for proportional fonts
#include "view.h" // Base class for all views

// ========== extern ===========================================
extern Logger logger; // Griduino.ino

#include "model_gps.h" // Model of a GPS for model-view-controller
extern Model *model;

// ========== class ViewCfgGpsReset ================================
class ViewCfgGpsReset : public View {
public:
// ---------- public interface ----------
// This derived class must implement the public interface:
ViewCfgGpsReset(Adafruit_ILI9341 *vtft, int vid) // ctor
: View{vtft, vid} {
background = cBACKGROUND; // every view can have its own background color
}
void updateScreen();
void startScreen();
bool onTouch(Point touch);

protected:
// ---------- local data for this derived class ----------
// color scheme: see constants.h

const int radius = 10; // rounded corners on buttons

// vertical placement of text rows
const int space = 24;
const int half = space / 2;

const int yRow1 = 36;
const int yRow2 = yRow1 + space + half;
const int yRow3 = yRow2 + space;
const int yBtn = yRow3 + space; // ul corner of big button
const int yRow8 = gScreenHeight - 10 - space; // Confirmation message
const int yRow9 = gScreenHeight - 10; // "v1.14, Feb 15 2024"

// ----- screen text
// names for the array indexes, must be named in same order as array below
enum txtIndex {
TITLE = 0,
LINE1,
LINE2,
NUMSATS,
CONFIRMATION,
COMPILED,
};

const int bWidth = 320 / 2;
const int bHeight = 64;

const int xBtn = 320 / 4;
const int yBtnText = yBtn + (bHeight / 2) + 6; // vertically center text inside big button

// ----- static screen text
// clang-format off
#define nRestartValues 6
TextField txtStatic[nRestartValues] = {
// text x, y color
{"GPS Cold Start", -1, 20, cHIGHLIGHT, ALIGNCENTER}, // [TITLE]
{"If your GPS receives no satellites", -1, yRow2, cFAINT, ALIGNCENTER, eFONTSMALLEST}, // [LINE1]
{"for hours, this action might help.", -1, yRow3, cFAINT, ALIGNCENTER, eFONTSMALLEST}, // [LINE2]
{"n#", (320-32), yBtnText, cLABEL, ALIGNRIGHT}, // [NUMSATS]
{"Done! Please allow time to acquire sats.", -1, yRow8, cBACKGROUND, ALIGNCENTER}, // [CONFIRMATION]
{PROGRAM_VERDATE, -1, yRow9, cFAINT, ALIGNCENTER, eFONTSMALLEST}, // [COMPILED]
};

enum buttonID {
eRESTART,
};
#define nRestartButtons 1
FunctionButton myButtons[nRestartButtons] = {
// label origin size { touch-target }
// text x,y w,h { x,y w,h }, radius, color, functionID
{"Cold Start GPS", xBtn,yBtn, bWidth,bHeight, {180,yBtn, 140,110 }, radius, cBUTTONLABEL, eRESTART},
};
// clang-format on

// ---------- local functions for this derived class ----------
void fRestart() {
logger.info("->->-> Clicked RESTART button.");
txtStatic[CONFIRMATION].color = cVALUEFAINT;
txtStatic[CONFIRMATION].dirty = true;
txtStatic[CONFIRMATION].print();

model->factoryReset(); // do the thing
}
void drawNumSatellites() {
char sTemp[4]; // strlen("12#") = 3
snprintf(sTemp, sizeof(sTemp), "%d#", model->gSatellites);
txtStatic[NUMSATS].print(sTemp); // number of satellites
}

}; // end class ViewCfgGpsReset

// ============== implement public interface ================
void ViewCfgGpsReset::updateScreen() {
// called on every pass through main()
// nothing to do in the main loop - this screen has no dynamic items
drawNumSatellites();
} // end updateScreen

void ViewCfgGpsReset::startScreen() {
// called once each time this view becomes active
this->clearScreen(this->background); // clear screen
txtStatic[0].setBackground(this->background); // set background for all TextFields in this view
TextField::setTextDirty(txtStatic, nRestartValues); // make sure all fields get re-printed on screen change

drawAllIcons(); // draw gear (settings) and arrow (next screen)
showDefaultTouchTargets(); // optionally draw box around default button-touch areas
showMyTouchTargets(myButtons, nRestartButtons); // optionally show this view's touch targets
showScreenBorder(); // optionally outline visible area
showScreenCenterline(); // optionally draw visual alignment bar

// ----- draw text fields
for (int ii = 0; ii < nRestartValues; ii++) {
txtStatic[ii].print();
}

// ----- draw buttons
setFontSize(eFONTSMALLEST);
for (int ii = 0; ii < nRestartButtons; ii++) {
FunctionButton item = myButtons[ii];
tft->fillRoundRect(item.x, item.y, item.w, item.h, item.radius, cBUTTONFILL);
tft->drawRoundRect(item.x, item.y, item.w, item.h, item.radius, cBUTTONOUTLINE);

// ----- label on top of button
int xx = getOffsetToCenterTextOnButton(item.text, item.x, item.w);

tft->setCursor(xx, item.y + item.h / 2 + 5); // place text centered inside button
tft->setTextColor(item.color);
tft->print(item.text);
}

showProgressBar(6, 8); // draw marker for advancing through settings
updateScreen(); // update UI immediately, don't wait for the main loop to eventually get around to it
} // end startScreen()

bool ViewCfgGpsReset::onTouch(Point touch) {
logger.info("->->-> Touched GPS restart screen.");
bool handled = false; // assume a touch target was not hit
for (int ii = 0; ii < nRestartButtons; ii++) {
FunctionButton item = myButtons[ii];
if (item.hitTarget.contains(touch)) {
handled = true; // hit!
switch (item.functionIndex) // do the thing
{
case eRESTART:
fRestart();
break;
default:
logger.error("Internal error, unknown function ", item.functionIndex);
break;
}
}
}
return handled; // true=handled, false=controller uses default action
} // end onTouch()
7 changes: 4 additions & 3 deletions cfg_nmea.h
Expand Up @@ -63,12 +63,13 @@ class ViewCfgNMEA : public View {
// color scheme: see constants.h

// vertical placement of text rows
const int space = 30;
const int yRow1 = 80;
const int yRow2 = yRow1 + 24;
const int yRow3 = yRow2 + 24;
const int yRow4 = yRow3 + 50;
const int yRow5 = yRow4 + 24;
const int yRow9 = gScreenHeight - 10; // "v1.14, Feb 12 2024"
const int yRow9 = gScreenHeight - 10; // "v1.14, Feb 15 2024"

const int yButton1 = 62;
const int yButton2 = yButton1 + 54;
Expand All @@ -82,7 +83,7 @@ class ViewCfgNMEA : public View {
#define nTextNMEA 6
TextField txtStatic[nTextNMEA] = {
// text x, y color
{"NMEA Sentences", -1, 20, cHIGHLIGHT, ALIGNCENTER},
{"GPS NMEA Sentences", -1, 20, cHIGHLIGHT, ALIGNCENTER},
{"Report GPS ", col1, yRow1, cVALUE},
{"positions", col1, yRow2, cVALUE},
{"NMEA sentences are available", -1, yRow4, cFAINT, ALIGNCENTER},
Expand Down Expand Up @@ -184,7 +185,7 @@ void ViewCfgNMEA::startScreen() {
tft->drawCircle(xCenter, yCenter, 7, cVALUE);
}

showProgressBar(5, 7); // draw marker for advancing through settings
showProgressBar(5, 8); // draw marker for advancing through settings
updateScreen(); // update UI immediately, don't wait for laggy mainline loop
} // end startScreen()

Expand Down
2 changes: 1 addition & 1 deletion cfg_reboot.h
Expand Up @@ -207,7 +207,7 @@ void ViewCfgReboot::startScreen() {
tft->print(item.text);
}

showProgressBar(7, 7); // draw marker for advancing through settings
showProgressBar(7, 8); // draw marker for advancing through settings
updateScreen(); // update UI immediately, don't wait for the main loop to eventually get around to it
} // end startScreen()

Expand Down
2 changes: 1 addition & 1 deletion cfg_rotation.h
Expand Up @@ -186,7 +186,7 @@ void ViewCfgRotation::startScreen() {
tft->drawCircle(xCenter, yCenter, 7, cVALUE);
}

showProgressBar(7, 7); // draw marker for advancing through settings
showProgressBar(8, 8); // draw marker for advancing through settings
updateScreen(); // update UI immediately, don't wait for laggy mainline loop
} // end startScreen()

Expand Down
2 changes: 1 addition & 1 deletion cfg_volume.h
Expand Up @@ -256,7 +256,7 @@ void ViewVolume::startScreen() {
yy = volButtons[1].y + volButtons[1].h / 2;
tft->fillTriangle(xx - ww, yy - nn, xx + ww, yy - nn, xx, yy + ht - nn, cVALUE); // arrow DOWN

showProgressBar(1, 7); // draw marker for advancing through settings
showProgressBar(1, 8); // draw marker for advancing through settings
updateScreen(); // update UI immediately, don't wait for laggy mainline loop
} // end startScreen()

Expand Down
2 changes: 1 addition & 1 deletion constants.h
Expand Up @@ -5,7 +5,7 @@
#if defined(ARDUINO_ADAFRUIT_FEATHER_RP2040)
#define PROGRAM_VERSION "v1.14 PCB v.7"
#else
#define PROGRAM_VERSION "v1.14"
#define PROGRAM_VERSION "v1.14 pcb12"
#endif
#define PROGRAM_LINE1 "Barry K7BWH"
#define PROGRAM_LINE2 "John KM7O"
Expand Down
18 changes: 12 additions & 6 deletions examples/GPS_Demo_Loopback/GPS_Demo_Loopback.ino
Expand Up @@ -287,13 +287,19 @@ void init_Adafruit_GPS() {
delay(50);

// ----- turn on additional satellite reporting to support NMEATime2
// GPGLL Geographic Latitude longitude
// | GPRMC Recommended Minimum Coordinates
// | | GPVTG Velocity Over Ground
// | | | GPGGA GPS Fix Data
// | | | | GPGSA GPS Satellites Active
// | | | | | GPGSV GPS Satellites in View
// GPGLL Geographic Latitude longitude
// | GPRMC Recommended Minimum Coordinates
// | | GPVTG Velocity Over Ground
// | | | GPGGA GPS Fix Data
// | | | | GPGSA GNSS DOPS and Active Satellites
// | | | | | GPGSV GNSS Satellites in View
#define PMTK_SENTENCE_FREQUENCIES "$PMTK314,0,1,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0*28"
// | | | | | PMTKDBG MTK debug information
// | | | | MTKDGP GPS differential correction information
// | | | PMTKEPH GPS ephemeris information
// | | PMTKALM GPS almanac information
// | GPGST GNSS Pseudorange Errors Statistics
// GPGRS GNSS Range Residuals
Serial.print("Sending command to set sentence output frequencies: ");
Serial.println(PMTK_SENTENCE_FREQUENCIES); // Echo command to console
GPS.sendCommand(PMTK_SENTENCE_FREQUENCIES); // Send command to GPS unit
Expand Down

0 comments on commit ece140f

Please sign in to comment.