Skip to content

Commit ed33370

Browse files
authored
Merge pull request #215 from sparkfun/RC_Display_Refactoring
Setup 'Button' Refactoring
2 parents e562df4 + fed957a commit ed33370

File tree

8 files changed

+365
-337
lines changed

8 files changed

+365
-337
lines changed

Firmware/RTK_Everywhere/Begin.ino

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -974,6 +974,7 @@ void beginSystemState()
974974
}
975975
else if (productVariant == RTK_EVK)
976976
{
977+
firstRoverStart = false; // Screen should have been tested when it was made ;-)
977978
// Return to either NTP, Base or Rover Not Started. The last state previous to power down.
978979
systemState = settings.lastState;
979980
}

Firmware/RTK_Everywhere/Display.ino

Lines changed: 96 additions & 168 deletions
Original file line numberDiff line numberDiff line change
@@ -1308,14 +1308,17 @@ void paintHorizontalAccuracy(displayCoords textCoords)
13081308
// Display clock with moving hands
13091309
void paintClock(std::vector<iconPropertyBlinking> *iconList, bool blinking)
13101310
{
1311-
// Animate icon to show system running
1312-
static uint8_t clockIconDisplayed = CLOCK_ICON_STATES - 1;
1313-
clockIconDisplayed++; // Goto next icon
1314-
clockIconDisplayed %= CLOCK_ICON_STATES; // Wrap
1311+
// Animate icon to show system running. The 2* makes the blink correct
1312+
static uint8_t clockIconDisplayed = (2 * CLOCK_ICON_STATES) - 1;
1313+
clockIconDisplayed++; // Goto next icon
1314+
clockIconDisplayed %= (2 * CLOCK_ICON_STATES); // Wrap
13151315

13161316
iconPropertyBlinking prop;
1317-
prop.icon = ClockIconProperties.iconDisplay[clockIconDisplayed][present.display_type];
1318-
prop.duty = 0b01010101;
1317+
prop.icon = ClockIconProperties.iconDisplay[clockIconDisplayed / 2][present.display_type];
1318+
if (blinking)
1319+
prop.duty = 0b01010101;
1320+
else
1321+
prop.duty = 0b11111111;
13191322
iconList->push_back(prop);
13201323

13211324
displayCoords textCoords;
@@ -1717,19 +1720,21 @@ void printTextwithKerning(const char *newText, uint8_t xPos, uint8_t yPos, uint8
17171720
// Show transmission of RTCM correction data packets to NTRIP caster
17181721
void paintRTCM(std::vector<iconPropertyBlinking> *iconList)
17191722
{
1720-
uint8_t xPos = CrossHairProperties.iconDisplay[present.display_type].xPos;
1721-
uint8_t yPos = CrossHairProperties.iconDisplay[present.display_type].yPos;
1722-
17231723
// Determine if the NTRIP Server is casting
17241724
bool casting = false;
17251725
for (int serverIndex = 0; serverIndex < NTRIP_SERVER_MAX; serverIndex++)
17261726
casting |= online.ntripServer[serverIndex];
17271727

1728-
// Note: the "yPos - 1" is potentially brittle. TODO: find a better solution for this
1728+
uint8_t xPos = CrossHairProperties.iconDisplay[present.display_type].xPos;
1729+
uint8_t yPos = CrossHairProperties.iconDisplay[present.display_type].yPos;
1730+
1731+
if (present.display_type == DISPLAY_64x48)
1732+
yPos = yPos - 1; // Move text up by 1 pixel on 64x48. Note: this is brittle. TODO: find a better solution
1733+
17291734
if (casting)
1730-
printTextCenter("Casting", yPos - 1, QW_FONT_8X16, 1, false); // text, y, font type, kerning, inverted
1735+
printTextAt("Casting", xPos + 4, yPos, QW_FONT_8X16, 1); // text, y, font type, kerning
17311736
else
1732-
printTextCenter("Xmitting", yPos - 1, QW_FONT_8X16, 1, false); // text, y, font type, kerning, inverted
1737+
printTextAt("Xmitting", xPos, yPos, QW_FONT_8X16, 1); // text, y, font type, kerning
17331738

17341739
xPos = SIVIconProperties.iconDisplay[present.display_type].xPos;
17351740
yPos = SIVIconProperties.iconDisplay[present.display_type].yPos;
@@ -1771,7 +1776,8 @@ void paintRTCM(std::vector<iconPropertyBlinking> *iconList)
17711776
paintResets();
17721777
}
17731778

1774-
// Show connecting to NTRIP caster service
1779+
// Show connecting to NTRIP caster service.
1780+
// Note: NOT USED. TODO: if this is used, the text position needs to be changed for 128x64
17751781
void paintConnectingToNtripCaster()
17761782
{
17771783
int yPos = 18;
@@ -2254,19 +2260,29 @@ void paintProfile(uint8_t profileUnit)
22542260
if (getProfileNameFromUnit(profileUnit, profileName, sizeof(profileName)) ==
22552261
true) // Load the profile name, limited to 8 chars
22562262
{
2257-
settings.updateGNSSSettings = true; // When this profile is loaded next, force system to update GNSS settings.
2258-
recordSystemSettings(); // Before switching, we need to record the current settings to LittleFS and SD
2263+
// Lookup profileNumber based on unit.
2264+
// getProfileNumberFromUnit should not fail (return -1), because we have already called getProfileNameFromUnit.
2265+
int8_t profileNumber = getProfileNumberFromUnit(profileUnit);
22592266

2260-
// Lookup profileNumber based on unit
2261-
uint8_t profileNumber = getProfileNumberFromUnit(profileUnit);
2262-
recordProfileNumber(profileNumber); // Update internal settings with user's choice, mark unit for config update
2267+
if (profileNumber >= 0)
2268+
{
2269+
settings.updateGNSSSettings = true; // When this profile is loaded next, force system to update GNSS settings.
2270+
recordSystemSettings(); // Before switching, we need to record the current settings to LittleFS and SD
22632271

2264-
log_d("Going to profile number %d from unit %d, name '%s'", profileNumber, profileUnit, profileName);
2272+
recordProfileNumber((uint8_t)profileNumber); // Update internal settings with user's choice, mark unit for config update
22652273

2266-
snprintf(profileMessage, sizeof(profileMessage), "Loading %s", profileName);
2267-
displayMessage(profileMessage, 2000);
2268-
ESP.restart(); // Profiles require full restart to take effect
2274+
log_d("Going to profile number %d from unit %d, name '%s'", profileNumber, profileUnit, profileName);
2275+
2276+
snprintf(profileMessage, sizeof(profileMessage), "Loading %s", profileName);
2277+
displayMessage(profileMessage, 2000);
2278+
ESP.restart(); // Profiles require full restart to take effect
2279+
}
22692280
}
2281+
2282+
log_d("Cannot go to profileUnit %d. No profile name / number. Restarting...", profileUnit);
2283+
snprintf(profileMessage, sizeof(profileMessage), "Invalid profile%d", profileUnit);
2284+
displayMessage(profileMessage, 2000);
2285+
ESP.restart(); // Something bad happened. Restart...
22702286
}
22712287

22722288
// Display unit self-tests until user presses a button to exit
@@ -2434,168 +2450,62 @@ void paintSystemTest()
24342450
}
24352451
}
24362452

2437-
// Display the setup profiles
2438-
void paintDisplaySetupProfile(const char *firstState)
2453+
// Show different menu 'buttons'.
2454+
// The first button is always highlighted, ready for selection. The user needs to double tap it to select it
2455+
void paintDisplaySetup()
24392456
{
2440-
int index;
2441-
int itemsDisplayed;
2442-
char profileName[8 + 1];
2457+
constructSetupDisplay(&setupButtons); // Construct the vector (linked list) of buttons
24432458

2444-
// Display the first state if this is the first profile
2445-
itemsDisplayed = 0;
2446-
if (displayProfile == 0)
2447-
{
2448-
printTextCenter(firstState, 12 * itemsDisplayed, QW_FONT_8X16, 1, false);
2449-
itemsDisplayed++;
2450-
}
2459+
uint8_t maxButtons = ((present.display_type == DISPLAY_128x64) ? 5 : 4);
24512460

2452-
// Display Bubble if this is the second profile
2453-
if (displayProfile <= 1)
2454-
{
2455-
printTextCenter("Bubble", 12 * itemsDisplayed, QW_FONT_8X16, 1, false);
2456-
itemsDisplayed++;
2457-
}
2461+
uint8_t printedButtons = 0;
24582462

2459-
// Display Config if this is the third profile
2460-
if (displayProfile <= 2)
2461-
{
2462-
printTextCenter("Config", 12 * itemsDisplayed, QW_FONT_8X16, 1, false);
2463-
itemsDisplayed++;
2464-
}
2463+
uint8_t thisIsButton = 0;
24652464

2466-
// displayProfile itemsDisplayed index
2467-
// 0 3 0
2468-
// 1 2 0
2469-
// 2 1 0
2470-
// 3 0 0
2471-
// 4 0 1
2472-
// 5 0 2
2473-
// n >= 3 0 n - 3
2474-
2475-
// Display the profile names
2476-
for (index = (displayProfile >= 3) ? displayProfile - 3 : 0; itemsDisplayed < 4; itemsDisplayed++)
2465+
for (auto it = setupButtons.begin(); it != setupButtons.end(); it = std::next(it))
24772466
{
2478-
// Lookup next available profile, limit to 8 characters
2479-
getProfileNameFromUnit(index, profileName, sizeof(profileName));
2480-
2481-
profileName[6] = 0; // Shorten profileName to 6 characters
2482-
2483-
char miniProfileName[16] = {0};
2484-
snprintf(miniProfileName, sizeof(miniProfileName), "%d_%s", index, profileName); // Prefix with index #
2485-
2486-
printTextCenter(miniProfileName, 12 * itemsDisplayed, QW_FONT_8X16, 1, itemsDisplayed == 3);
2487-
index++;
2488-
}
2489-
}
2467+
setupButton theButton = *it;
24902468

2491-
// Show different menu 'buttons' to allow user to pause on one to select it
2492-
void paintDisplaySetup()
2493-
{
2494-
if (setupState == STATE_ROVER_NOT_STARTED)
2495-
{
2496-
if (present.ethernet_ws5500 == true)
2497-
{
2498-
printTextCenter("Base", 12 * 0, QW_FONT_8X16, 1, false); // string, y, font type, kerning, inverted
2499-
printTextCenter("Rover", 12 * 1, QW_FONT_8X16, 1, true);
2500-
printTextCenter("NTP", 12 * 2, QW_FONT_8X16, 1, false);
2501-
printTextCenter("Cfg Eth", 12 * 3, QW_FONT_8X16, 1, false);
2502-
}
2503-
else
2504-
{
2505-
printTextCenter("Mark", 12 * 0, QW_FONT_8X16, 1, false);
2506-
printTextCenter("Rover", 12 * 1, QW_FONT_8X16, 1, true);
2507-
printTextCenter("Base", 12 * 2, QW_FONT_8X16, 1, false);
2508-
printTextCenter("Config", 12 * 3, QW_FONT_8X16, 1, false);
2509-
}
2510-
}
2511-
else if (setupState == STATE_BASE_NOT_STARTED)
2512-
{
2513-
if (present.ethernet_ws5500 == true)
2469+
if (thisIsButton >= setupSelectedButton) // Should we display this button based on the global setupSelectedButton?
25142470
{
2515-
printTextCenter("Base", 12 * 0, QW_FONT_8X16, 1, true); // string, y, font type, kerning, inverted
2516-
printTextCenter("Rover", 12 * 1, QW_FONT_8X16, 1, false);
2517-
printTextCenter("NTP", 12 * 2, QW_FONT_8X16, 1, false);
2518-
printTextCenter("Cfg Eth", 12 * 3, QW_FONT_8X16, 1, false);
2519-
}
2520-
else
2521-
{
2522-
printTextCenter("Mark", 12 * 0, QW_FONT_8X16, 1, false); // string, y, font type, kerning, inverted
2523-
printTextCenter("Rover", 12 * 1, QW_FONT_8X16, 1, false);
2524-
printTextCenter("Base", 12 * 2, QW_FONT_8X16, 1, true);
2525-
printTextCenter("Config", 12 * 3, QW_FONT_8X16, 1, false);
2526-
}
2527-
}
2528-
else if (setupState == STATE_NTPSERVER_NOT_STARTED)
2529-
{
2530-
{
2531-
printTextCenter("Base", 12 * 0, QW_FONT_8X16, 1, false); // string, y, font type, kerning, inverted
2532-
printTextCenter("Rover", 12 * 1, QW_FONT_8X16, 1, false);
2533-
printTextCenter("NTP", 12 * 2, QW_FONT_8X16, 1, true);
2534-
printTextCenter("Cfg Eth", 12 * 3, QW_FONT_8X16, 1, false);
2535-
}
2536-
}
2537-
else if (setupState == STATE_CONFIG_VIA_ETH_NOT_STARTED)
2538-
{
2539-
printTextCenter("Base", 12 * 0, QW_FONT_8X16, 1, false); // string, y, font type, kerning, inverted
2540-
printTextCenter("Rover", 12 * 1, QW_FONT_8X16, 1, false);
2541-
printTextCenter("NTP", 12 * 2, QW_FONT_8X16, 1, false);
2542-
printTextCenter("Cfg Eth", 12 * 3, QW_FONT_8X16, 1, true);
2543-
}
2544-
else if (setupState == STATE_WIFI_CONFIG_NOT_STARTED)
2545-
{
2546-
if (present.ethernet_ws5500 == true)
2547-
{
2548-
printTextCenter("Rover", 12 * 0, QW_FONT_8X16, 1, false); // string, y, font type, kerning, inverted
2549-
printTextCenter("NTP", 12 * 1, QW_FONT_8X16, 1, false);
2550-
printTextCenter("Cfg Eth", 12 * 2, QW_FONT_8X16, 1, false);
2551-
printTextCenter("CfgWiFi", 12 * 3, QW_FONT_8X16, 1, true);
2552-
}
2553-
else
2554-
{
2555-
printTextCenter("Mark", 12 * 0, QW_FONT_8X16, 1, false);
2556-
printTextCenter("Rover", 12 * 1, QW_FONT_8X16, 1, false);
2557-
printTextCenter("Base", 12 * 2, QW_FONT_8X16, 1, false);
2558-
printTextCenter("Config", 12 * 3, QW_FONT_8X16, 1, true);
2471+
if (printedButtons < maxButtons) // Do we have room to display it?
2472+
{
2473+
if (theButton.newState == STATE_PROFILE)
2474+
{
2475+
int nameWidth = ((present.display_type == DISPLAY_128x64) ? 17 : 9);
2476+
char miniProfileName[nameWidth] = {0};
2477+
snprintf(miniProfileName, sizeof(miniProfileName), "%d_%s", theButton.newProfile, theButton.name); // Prefix with index #
2478+
printTextCenter(miniProfileName, 12 * printedButtons, QW_FONT_8X16, 1, printedButtons == 0);
2479+
}
2480+
else
2481+
printTextCenter(theButton.name, 12 * printedButtons, QW_FONT_8X16, 1, printedButtons == 0);
2482+
printedButtons++;
2483+
}
25592484
}
2560-
}
25612485

2562-
// If we are on an L-Band unit, display GetKeys option
2563-
else if (setupState == STATE_KEYS_NEEDED)
2564-
{
2565-
printTextCenter("Rover", 12 * 0, QW_FONT_8X16, 1, false);
2566-
printTextCenter("Base", 12 * 1, QW_FONT_8X16, 1, false);
2567-
printTextCenter("Config", 12 * 2, QW_FONT_8X16, 1, false);
2568-
printTextCenter("GetKeys", 12 * 3, QW_FONT_8X16, 1, true);
2486+
thisIsButton++;
25692487
}
25702488

2571-
else if (setupState == STATE_ESPNOW_PAIRING_NOT_STARTED)
2489+
// If we printed less than maxButtons, print more.
2490+
// This causes Base to be printed below Exit, indicating you can "go round again".
2491+
// I think that's what we want?
2492+
// If not, we could comment this and leave the display blank below Exit.
2493+
while (printedButtons < maxButtons)
25722494
{
2573-
if (present.ethernet_ws5500 == true)
2574-
{
2575-
printTextCenter("NTP", 12 * 0, QW_FONT_8X16, 1, false); // string, y, font type, kerning, inverted
2576-
printTextCenter("Cfg Eth", 12 * 1, QW_FONT_8X16, 1, false);
2577-
printTextCenter("CfgWiFi", 12 * 2, QW_FONT_8X16, 1, false);
2578-
printTextCenter("E-Pair", 12 * 3, QW_FONT_8X16, 1, true);
2579-
}
2580-
else if (settings.pointPerfectCorrectionsSource != POINTPERFECT_CORRECTIONS_DISABLED)
2581-
{
2582-
// If we are on an L-Band unit, scroll GetKeys option
2583-
printTextCenter("Base", 12 * 0, QW_FONT_8X16, 1, false);
2584-
printTextCenter("Config", 12 * 1, QW_FONT_8X16, 1, false);
2585-
printTextCenter("GetKeys", 12 * 2, QW_FONT_8X16, 1, false);
2586-
printTextCenter("E-Pair", 12 * 3, QW_FONT_8X16, 1, true);
2587-
}
2588-
else
2495+
for (auto it = setupButtons.begin(); it != setupButtons.end(); it = std::next(it))
25892496
{
2590-
printTextCenter("Rover", 12 * 0, QW_FONT_8X16, 1, false);
2591-
printTextCenter("Base", 12 * 1, QW_FONT_8X16, 1, false);
2592-
printTextCenter("Config", 12 * 2, QW_FONT_8X16, 1, false);
2593-
printTextCenter("E-Pair", 12 * 3, QW_FONT_8X16, 1, true);
2497+
setupButton theButton = *it;
2498+
2499+
if (printedButtons < maxButtons) // Do we have room to display it?
2500+
{
2501+
printTextCenter(theButton.name, 12 * printedButtons, QW_FONT_8X16, 1, printedButtons == 0);
2502+
printedButtons++;
2503+
}
2504+
2505+
if (printedButtons == maxButtons)
2506+
break;
25942507
}
25952508
}
2596-
2597-
else if (setupState == STATE_PROFILE)
2598-
paintDisplaySetupProfile("Base");
25992509
}
26002510

26012511
// Given text, and location, print text center of the screen
@@ -2635,6 +2545,24 @@ void printTextCenter(const char *text, uint8_t yPos, QwiicFont &fontType, uint8_
26352545
}
26362546
}
26372547

2548+
// Given text, and location, print text to the screen
2549+
void printTextAt(const char *text, uint8_t xPos, uint8_t yPos, QwiicFont &fontType, uint8_t kerning) // text, x, y, font type, kearning, inverted
2550+
{
2551+
oled->setFont(fontType);
2552+
oled->setDrawMode(grROPXOR);
2553+
2554+
uint8_t fontWidth = fontType.width;
2555+
if (fontWidth == 8)
2556+
fontWidth = 7; // 8x16, but widest character is only 7 pixels.
2557+
2558+
for (int x = 0; x < strlen(text); x++)
2559+
{
2560+
oled->setCursor(xPos, yPos);
2561+
oled->print(text[x]);
2562+
xPos += fontWidth + kerning;
2563+
}
2564+
}
2565+
26382566
// Given a message (one or two words) display centered
26392567
void displayMessage(const char *message, uint16_t displayTime)
26402568
{

Firmware/RTK_Everywhere/NVM.ino

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1888,8 +1888,8 @@ bool getProfileNameFromUnit(uint8_t profileUnit, char *profileName, uint8_t prof
18881888

18891889
// Return profile number based on units
18901890
// Profiles may not be sequential (user might have empty profile #2, but filled #3) so we look up the profile unit and
1891-
// return the count
1892-
uint8_t getProfileNumberFromUnit(uint8_t profileUnit)
1891+
// return the count. Return -1 if profileUnit is not found.
1892+
int8_t getProfileNumberFromUnit(uint8_t profileUnit)
18931893
{
18941894
uint8_t located = 0;
18951895

@@ -1906,7 +1906,7 @@ uint8_t getProfileNumberFromUnit(uint8_t profileUnit)
19061906
}
19071907
log_d("Profile unit %d not found", profileUnit);
19081908

1909-
return (0);
1909+
return (-1);
19101910
}
19111911

19121912
// Record large character blob to file

Firmware/RTK_Everywhere/RTK_Everywhere.ino

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ TwoWire *i2cDisplay = nullptr;
175175

176176
#define MAX_PROFILE_COUNT 8
177177
uint8_t activeProfiles; // Bit vector indicating which profiles are active
178-
uint8_t displayProfile; // Range: 0 - (MAX_PROFILE_COUNT - 1)
178+
uint8_t displayProfile; // Profile Unit - Range: 0 - (MAX_PROFILE_COUNT - 1)
179179
uint8_t profileNumber = MAX_PROFILE_COUNT; // profileNumber gets set once at boot to save loading time
180180
char profileNames[MAX_PROFILE_COUNT][50]; // Populated based on names found in LittleFS and SD
181181
char settingsFileName[60]; // Contains the %s_Settings_%d.txt with current profile number set
@@ -675,8 +675,10 @@ uint32_t rtcmLastReceived;
675675

676676
uint32_t maxSurveyInWait_s = 60L * 15L; // Re-start survey-in after X seconds
677677

678-
uint32_t lastSetupMenuChange; // Auto-selects the setup menu option after 1500ms
678+
uint32_t lastSetupMenuChange; // Limits how much time is spent in the setup menu
679679
uint32_t lastTestMenuChange; // Avoids exiting the test menu for at least 1 second
680+
uint8_t setupSelectedButton = 0; // In Display Setup, start displaying at this button. This is the selected (highlighted) button.
681+
std::vector<setupButton> setupButtons; // A vector (linked list) of the setup 'butttons'
680682

681683
bool firstRoverStart; // Used to detect if the user is toggling the power button at POR to enter the test menu
682684

0 commit comments

Comments
 (0)