mirror of
https://github.com/meshtastic/firmware.git
synced 2025-04-25 09:42:35 +00:00
Merge pull request #63 from girtsf/debug-screen-b49
fix #49: make debug screen show real data
This commit is contained in:
commit
f8857ad45b
@ -16,7 +16,6 @@ static uint32_t
|
|||||||
timeStartMsec; // Once we have a GPS lock, this is where we hold the initial msec clock that corresponds to that time
|
timeStartMsec; // Once we have a GPS lock, this is where we hold the initial msec clock that corresponds to that time
|
||||||
static uint64_t zeroOffsetSecs; // GPS based time in secs since 1970 - only updated once on initial lock
|
static uint64_t zeroOffsetSecs; // GPS based time in secs since 1970 - only updated once on initial lock
|
||||||
|
|
||||||
static bool hasValidLocation; // default to false, until we complete our first read
|
|
||||||
static bool wantNewLocation = true;
|
static bool wantNewLocation = true;
|
||||||
|
|
||||||
GPS::GPS() : PeriodicTask() {}
|
GPS::GPS() : PeriodicTask() {}
|
||||||
|
@ -45,8 +45,13 @@ class GPS : public PeriodicTask, public Observable
|
|||||||
/// Restart our lock attempt - try to get and broadcast a GPS reading ASAP
|
/// Restart our lock attempt - try to get and broadcast a GPS reading ASAP
|
||||||
void startLock();
|
void startLock();
|
||||||
|
|
||||||
|
/// Returns ture if we have acquired GPS lock.
|
||||||
|
bool hasLock() const { return hasValidLocation; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void readFromRTC();
|
void readFromRTC();
|
||||||
|
|
||||||
|
bool hasValidLocation = false; // default to false, until we complete our first read
|
||||||
};
|
};
|
||||||
|
|
||||||
extern GPS gps;
|
extern GPS gps;
|
||||||
|
53
src/main.cpp
53
src/main.cpp
@ -32,6 +32,7 @@
|
|||||||
#include "configuration.h"
|
#include "configuration.h"
|
||||||
#include "esp32/pm.h"
|
#include "esp32/pm.h"
|
||||||
#include "esp_pm.h"
|
#include "esp_pm.h"
|
||||||
|
#include "power.h"
|
||||||
#include "rom/rtc.h"
|
#include "rom/rtc.h"
|
||||||
#include "screen.h"
|
#include "screen.h"
|
||||||
#include "sleep.h"
|
#include "sleep.h"
|
||||||
@ -52,9 +53,8 @@ meshtastic::Screen screen(SSD1306_ADDRESS, I2C_SDA, I2C_SCL);
|
|||||||
meshtastic::Screen screen(SSD1306_ADDRESS, 0, 0);
|
meshtastic::Screen screen(SSD1306_ADDRESS, 0, 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// these flags are all in bss so they default false
|
// Global power status singleton
|
||||||
bool isCharging;
|
static meshtastic::PowerStatus powerStatus;
|
||||||
bool isUSBPowered;
|
|
||||||
|
|
||||||
bool ssd1306_found;
|
bool ssd1306_found;
|
||||||
bool axp192_found;
|
bool axp192_found;
|
||||||
@ -97,6 +97,21 @@ void scanI2Cdevice(void)
|
|||||||
DEBUG_MSG("done\n");
|
DEBUG_MSG("done\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef T_BEAM_V10
|
||||||
|
/// Reads power status to powerStatus singleton.
|
||||||
|
//
|
||||||
|
// TODO(girts): move this and other axp stuff to power.h/power.cpp.
|
||||||
|
void readPowerStatus()
|
||||||
|
{
|
||||||
|
powerStatus.haveBattery = axp.isBatteryConnect();
|
||||||
|
if (powerStatus.haveBattery) {
|
||||||
|
powerStatus.batteryVoltageMv = axp.getBattVoltage();
|
||||||
|
}
|
||||||
|
powerStatus.usb = axp.isVBUSPlug();
|
||||||
|
powerStatus.charging = axp.isChargeing();
|
||||||
|
}
|
||||||
|
#endif // T_BEAM_V10
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Init the power manager chip
|
* Init the power manager chip
|
||||||
*
|
*
|
||||||
@ -167,9 +182,7 @@ void axp192Init()
|
|||||||
1);
|
1);
|
||||||
axp.clearIRQ();
|
axp.clearIRQ();
|
||||||
#endif
|
#endif
|
||||||
|
readPowerStatus();
|
||||||
isCharging = axp.isChargeing() ? 1 : 0;
|
|
||||||
isUSBPowered = axp.isVBUSPlug() ? 1 : 0;
|
|
||||||
} else {
|
} else {
|
||||||
DEBUG_MSG("AXP192 Begin FAIL\n");
|
DEBUG_MSG("AXP192 Begin FAIL\n");
|
||||||
}
|
}
|
||||||
@ -302,7 +315,7 @@ uint32_t ledBlinker()
|
|||||||
setLed(ledOn);
|
setLed(ledOn);
|
||||||
|
|
||||||
// have a very sparse duty cycle of LED being on, unless charging, then blink 0.5Hz square wave rate to indicate that
|
// have a very sparse duty cycle of LED being on, unless charging, then blink 0.5Hz square wave rate to indicate that
|
||||||
return isCharging ? 1000 : (ledOn ? 2 : 1000);
|
return powerStatus.charging ? 1000 : (ledOn ? 2 : 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
Periodic ledPeriodic(ledBlinker);
|
Periodic ledPeriodic(ledBlinker);
|
||||||
@ -310,18 +323,21 @@ Periodic ledPeriodic(ledBlinker);
|
|||||||
#if 0
|
#if 0
|
||||||
// Turn off for now
|
// Turn off for now
|
||||||
|
|
||||||
uint32_t axpReads()
|
uint32_t axpDebugRead()
|
||||||
{
|
{
|
||||||
axp.debugCharging();
|
axp.debugCharging();
|
||||||
DEBUG_MSG("vbus current %f\n", axp.getVbusCurrent());
|
DEBUG_MSG("vbus current %f\n", axp.getVbusCurrent());
|
||||||
DEBUG_MSG("charge current %f\n", axp.getBattChargeCurrent());
|
DEBUG_MSG("charge current %f\n", axp.getBattChargeCurrent());
|
||||||
DEBUG_MSG("bat voltage %f\n", axp.getBattVoltage());
|
DEBUG_MSG("bat voltage %f\n", axp.getBattVoltage());
|
||||||
DEBUG_MSG("batt pct %d\n", axp.getBattPercentage());
|
DEBUG_MSG("batt pct %d\n", axp.getBattPercentage());
|
||||||
|
DEBUG_MSG("is battery connected %d\n", axp.isBatteryConnect());
|
||||||
|
DEBUG_MSG("is USB connected %d\n", axp.isVBUSPlug());
|
||||||
|
DEBUG_MSG("is charging %d\n", axp.isChargeing());
|
||||||
|
|
||||||
return 30 * 1000;
|
return 30 * 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
Periodic axpDebugOutput(axpReads);
|
Periodic axpDebugOutput(axpDebugRead);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void loop()
|
void loop()
|
||||||
@ -330,7 +346,6 @@ void loop()
|
|||||||
|
|
||||||
powerFSM.run_machine();
|
powerFSM.run_machine();
|
||||||
gps.loop();
|
gps.loop();
|
||||||
screen.loop();
|
|
||||||
service.loop();
|
service.loop();
|
||||||
|
|
||||||
ledPeriodic.loop();
|
ledPeriodic.loop();
|
||||||
@ -349,18 +364,16 @@ void loop()
|
|||||||
|
|
||||||
DEBUG_MSG("pmu irq!\n");
|
DEBUG_MSG("pmu irq!\n");
|
||||||
|
|
||||||
isCharging = axp.isChargeing() ? 1 : 0;
|
readPowerStatus();
|
||||||
isUSBPowered = axp.isVBUSPlug() ? 1 : 0;
|
|
||||||
|
|
||||||
axp.clearIRQ();
|
axp.clearIRQ();
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME AXP192 interrupt is not firing, remove this temporary polling of battery state
|
// FIXME AXP192 interrupt is not firing, remove this temporary polling of battery state
|
||||||
isCharging = axp.isChargeing() ? 1 : 0;
|
readPowerStatus();
|
||||||
isUSBPowered = axp.isVBUSPlug() ? 1 : 0;
|
#endif // PMU_IRQ
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif // T_BEAM_V10
|
||||||
|
|
||||||
#ifdef BUTTON_PIN
|
#ifdef BUTTON_PIN
|
||||||
// if user presses button for more than 3 secs, discard our network prefs and reboot (FIXME, use a debounce lib instead of
|
// if user presses button for more than 3 secs, discard our network prefs and reboot (FIXME, use a debounce lib instead of
|
||||||
@ -390,6 +403,14 @@ void loop()
|
|||||||
showingBootScreen = false;
|
showingBootScreen = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update the screen last, after we've figured out what to show.
|
||||||
|
screen.debug()->setNodeNumbersStatus(nodeDB.getNumOnlineNodes(), nodeDB.getNumNodes());
|
||||||
|
screen.debug()->setChannelNameStatus(channelSettings.name);
|
||||||
|
screen.debug()->setPowerStatus(powerStatus);
|
||||||
|
// TODO(#4): use something based on hdop to show GPS "signal" strength.
|
||||||
|
screen.debug()->setGPSStatus(gps.hasLock() ? "ok" : ":(");
|
||||||
|
screen.loop();
|
||||||
|
|
||||||
// No GPS lock yet, let the OS put the main CPU in low power mode for 100ms (or until another interrupt comes in)
|
// No GPS lock yet, let the OS put the main CPU in low power mode for 100ms (or until another interrupt comes in)
|
||||||
// i.e. don't just keep spinning in loop as fast as we can.
|
// i.e. don't just keep spinning in loop as fast as we can.
|
||||||
// DEBUG_MSG("msecs %d\n", msecstosleep);
|
// DEBUG_MSG("msecs %d\n", msecstosleep);
|
||||||
|
18
src/power.h
Normal file
18
src/power.h
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace meshtastic
|
||||||
|
{
|
||||||
|
|
||||||
|
/// Describes the state of the power system.
|
||||||
|
struct PowerStatus {
|
||||||
|
/// Whether we have a battery connected
|
||||||
|
bool haveBattery;
|
||||||
|
/// Battery voltage in mV, valid if haveBattery is true
|
||||||
|
int batteryVoltageMv;
|
||||||
|
/// Whether USB is connected
|
||||||
|
bool usb;
|
||||||
|
/// Whether we are charging the battery
|
||||||
|
bool charging;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace meshtastic
|
@ -135,15 +135,17 @@ static uint32_t drawRows(OLEDDisplay *display, int16_t x, int16_t y, const char
|
|||||||
display->drawString(xo, yo, *f);
|
display->drawString(xo, yo, *f);
|
||||||
xo += SCREEN_WIDTH / COLUMNS;
|
xo += SCREEN_WIDTH / COLUMNS;
|
||||||
// Wrap to next row, if needed.
|
// Wrap to next row, if needed.
|
||||||
if (++col > COLUMNS) {
|
if (++col >= COLUMNS) {
|
||||||
xo = x;
|
xo = x;
|
||||||
yo += FONT_HEIGHT;
|
yo += FONT_HEIGHT;
|
||||||
col = 0;
|
col = 0;
|
||||||
}
|
}
|
||||||
f++;
|
f++;
|
||||||
}
|
}
|
||||||
|
if (col != 0) {
|
||||||
yo += FONT_HEIGHT; // include the last line in our total
|
// Include last incomplete line in our total.
|
||||||
|
yo += FONT_HEIGHT;
|
||||||
|
}
|
||||||
|
|
||||||
return yo;
|
return yo;
|
||||||
}
|
}
|
||||||
@ -375,36 +377,6 @@ static void drawNodeInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_
|
|||||||
display->drawCircle(compassX, compassY, COMPASS_DIAM / 2);
|
display->drawCircle(compassX, compassY, COMPASS_DIAM / 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void drawDebugInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
|
|
||||||
{
|
|
||||||
display->setFont(ArialMT_Plain_10);
|
|
||||||
|
|
||||||
// The coordinates define the left starting point of the text
|
|
||||||
display->setTextAlignment(TEXT_ALIGN_LEFT);
|
|
||||||
|
|
||||||
static char usersStr[20];
|
|
||||||
snprintf(usersStr, sizeof(usersStr), "Users %d/%d", nodeDB.getNumOnlineNodes(), nodeDB.getNumNodes());
|
|
||||||
|
|
||||||
static char channelStr[20];
|
|
||||||
snprintf(channelStr, sizeof(channelStr), "%s", channelSettings.name);
|
|
||||||
|
|
||||||
// We don't show battery levels yet - for now just lie and show debug info
|
|
||||||
static char batStr[20];
|
|
||||||
snprintf(batStr, sizeof(batStr), "Batt %x%%", (isCharging << 1) + isUSBPowered);
|
|
||||||
|
|
||||||
static char gpsStr[20];
|
|
||||||
if (myNodeInfo.has_gps)
|
|
||||||
snprintf(gpsStr, sizeof(gpsStr), "GPS %d%%",
|
|
||||||
75); // FIXME, use something based on hdop
|
|
||||||
else
|
|
||||||
gpsStr[0] = '\0'; // Just show emptystring
|
|
||||||
|
|
||||||
const char *fields[] = {batStr, gpsStr, usersStr, channelStr, NULL};
|
|
||||||
uint32_t yo = drawRows(display, x, y, fields);
|
|
||||||
|
|
||||||
display->drawLogBuffer(x, yo);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
void _screen_header()
|
void _screen_header()
|
||||||
{
|
{
|
||||||
@ -467,6 +439,8 @@ void Screen::setup()
|
|||||||
ui.setFrameAnimation(SLIDE_LEFT);
|
ui.setFrameAnimation(SLIDE_LEFT);
|
||||||
// Don't show the page swipe dots while in boot screen.
|
// Don't show the page swipe dots while in boot screen.
|
||||||
ui.disableAllIndicators();
|
ui.disableAllIndicators();
|
||||||
|
// Store a pointer to Screen so we can get to it from static functions.
|
||||||
|
ui.getUiState()->userData = this;
|
||||||
|
|
||||||
// Add frames.
|
// Add frames.
|
||||||
static FrameCallback bootFrames[] = {drawBootScreen};
|
static FrameCallback bootFrames[] = {drawBootScreen};
|
||||||
@ -573,6 +547,12 @@ void Screen::doTask()
|
|||||||
setPeriod(1000 / targetFramerate);
|
setPeriod(1000 / targetFramerate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Screen::drawDebugInfoTrampoline(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
|
||||||
|
{
|
||||||
|
Screen *screen = reinterpret_cast<Screen *>(state->userData);
|
||||||
|
screen->debugInfo.drawFrame(display, state, x, y);
|
||||||
|
}
|
||||||
|
|
||||||
// restore our regular frame list
|
// restore our regular frame list
|
||||||
void Screen::setFrames()
|
void Screen::setFrames()
|
||||||
{
|
{
|
||||||
@ -595,7 +575,10 @@ void Screen::setFrames()
|
|||||||
normalFrames[numframes++] = drawNodeInfo;
|
normalFrames[numframes++] = drawNodeInfo;
|
||||||
|
|
||||||
// then the debug info
|
// then the debug info
|
||||||
normalFrames[numframes++] = drawDebugInfo;
|
//
|
||||||
|
// Since frames are basic function pointers, we have to use a helper to
|
||||||
|
// call a method on debugInfo object.
|
||||||
|
normalFrames[numframes++] = &Screen::drawDebugInfoTrampoline;
|
||||||
|
|
||||||
ui.setFrames(normalFrames, numframes);
|
ui.setFrames(normalFrames, numframes);
|
||||||
ui.enableAllIndicators();
|
ui.enableAllIndicators();
|
||||||
@ -642,4 +625,42 @@ void Screen::handleOnPress()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DebugInfo::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
|
||||||
|
{
|
||||||
|
display->setFont(ArialMT_Plain_10);
|
||||||
|
|
||||||
|
// The coordinates define the left starting point of the text
|
||||||
|
display->setTextAlignment(TEXT_ALIGN_LEFT);
|
||||||
|
|
||||||
|
char usersStr[20];
|
||||||
|
char channelStr[20];
|
||||||
|
char batStr[20];
|
||||||
|
char gpsStr[20];
|
||||||
|
{
|
||||||
|
LockGuard guard(&lock);
|
||||||
|
snprintf(usersStr, sizeof(usersStr), "Users %d/%d", nodesOnline, nodesTotal);
|
||||||
|
snprintf(channelStr, sizeof(channelStr), "%s", channelName.c_str());
|
||||||
|
if (powerStatus.haveBattery) {
|
||||||
|
// TODO: draw a battery icon instead of letter "B".
|
||||||
|
int batV = powerStatus.batteryVoltageMv / 1000;
|
||||||
|
int batCv = (powerStatus.batteryVoltageMv % 1000) / 10;
|
||||||
|
snprintf(batStr, sizeof(batStr), "B %01d.%02dV%c%c", batV, batCv, powerStatus.charging ? '+' : ' ',
|
||||||
|
powerStatus.usb ? 'U' : ' ');
|
||||||
|
} else {
|
||||||
|
snprintf(batStr, sizeof(batStr), "%s", powerStatus.usb ? "USB" : "");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!gpsStatus.empty()) {
|
||||||
|
snprintf(gpsStr, sizeof(gpsStr), "GPS %s", gpsStatus.c_str());
|
||||||
|
} else {
|
||||||
|
gpsStr[0] = '\0'; // Just show empty string.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *fields[] = {batStr, gpsStr, usersStr, channelStr, nullptr};
|
||||||
|
uint32_t yo = drawRows(display, x, y, fields);
|
||||||
|
|
||||||
|
display->drawLogBuffer(x, yo);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace meshtastic
|
} // namespace meshtastic
|
||||||
|
82
src/screen.h
82
src/screen.h
@ -7,14 +7,84 @@
|
|||||||
|
|
||||||
#include "PeriodicTask.h"
|
#include "PeriodicTask.h"
|
||||||
#include "TypedQueue.h"
|
#include "TypedQueue.h"
|
||||||
|
#include "lock.h"
|
||||||
|
#include "power.h"
|
||||||
|
|
||||||
namespace meshtastic
|
namespace meshtastic
|
||||||
{
|
{
|
||||||
|
|
||||||
|
// Forward declarations
|
||||||
|
class Screen;
|
||||||
|
|
||||||
|
/// Handles gathering and displaying debug information.
|
||||||
|
class DebugInfo
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DebugInfo(const DebugInfo &) = delete;
|
||||||
|
DebugInfo &operator=(const DebugInfo &) = delete;
|
||||||
|
|
||||||
|
/// Sets user statistics.
|
||||||
|
void setNodeNumbersStatus(int online, int total)
|
||||||
|
{
|
||||||
|
LockGuard guard(&lock);
|
||||||
|
nodesOnline = online;
|
||||||
|
nodesTotal = total;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sets the name of the channel.
|
||||||
|
void setChannelNameStatus(const char *name)
|
||||||
|
{
|
||||||
|
LockGuard guard(&lock);
|
||||||
|
channelName = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sets battery/charging/etc status.
|
||||||
|
//
|
||||||
|
void setPowerStatus(const PowerStatus& status)
|
||||||
|
{
|
||||||
|
LockGuard guard(&lock);
|
||||||
|
powerStatus = status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sets GPS status.
|
||||||
|
//
|
||||||
|
// If this function never gets called, we assume GPS does not exist on this
|
||||||
|
// device.
|
||||||
|
// TODO(girts): figure out what the format should be.
|
||||||
|
void setGPSStatus(const char *status)
|
||||||
|
{
|
||||||
|
LockGuard guard(&lock);
|
||||||
|
gpsStatus = status;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
friend Screen;
|
||||||
|
|
||||||
|
DebugInfo() {}
|
||||||
|
|
||||||
|
/// Renders the debug screen.
|
||||||
|
void drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y);
|
||||||
|
|
||||||
|
int nodesOnline = 0;
|
||||||
|
int nodesTotal = 0;
|
||||||
|
|
||||||
|
PowerStatus powerStatus;
|
||||||
|
|
||||||
|
std::string channelName;
|
||||||
|
|
||||||
|
std::string gpsStatus;
|
||||||
|
|
||||||
|
/// Protects all of internal state.
|
||||||
|
Lock lock;
|
||||||
|
};
|
||||||
|
|
||||||
/// Deals with showing things on the screen of the device.
|
/// Deals with showing things on the screen of the device.
|
||||||
//
|
//
|
||||||
// Other than setup(), this class is thread-safe. All state-changing calls are
|
// Other than setup(), this class is thread-safe. All state-changing calls are
|
||||||
// queued and executed when the main loop calls us.
|
// queued and executed when the main loop calls us.
|
||||||
|
//
|
||||||
|
// This class is thread-safe (as long as drawFrame is not called multiple times
|
||||||
|
// simultaneously).
|
||||||
class Screen : public PeriodicTask
|
class Screen : public PeriodicTask
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -66,6 +136,11 @@ class Screen : public PeriodicTask
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns a handle to the DebugInfo screen.
|
||||||
|
//
|
||||||
|
// Use this handle to set things like battery status, user count, GPS status, etc.
|
||||||
|
DebugInfo *debug() { return &debugInfo; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/// Updates the UI.
|
/// Updates the UI.
|
||||||
//
|
//
|
||||||
@ -108,7 +183,9 @@ class Screen : public PeriodicTask
|
|||||||
/// Rebuilds our list of frames (screens) to default ones.
|
/// Rebuilds our list of frames (screens) to default ones.
|
||||||
void setFrames();
|
void setFrames();
|
||||||
|
|
||||||
private:
|
/// Called when debug screen is to be drawn, calls through to debugInfo.drawFrame.
|
||||||
|
static void drawDebugInfoTrampoline(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y);
|
||||||
|
|
||||||
/// Queue of commands to execute in doTask.
|
/// Queue of commands to execute in doTask.
|
||||||
TypedQueue<CmdItem> cmdQueue;
|
TypedQueue<CmdItem> cmdQueue;
|
||||||
/// Whether we are using a display
|
/// Whether we are using a display
|
||||||
@ -118,6 +195,9 @@ class Screen : public PeriodicTask
|
|||||||
// Whether we are showing the regular screen (as opposed to booth screen or
|
// Whether we are showing the regular screen (as opposed to booth screen or
|
||||||
// Bluetooth PIN screen)
|
// Bluetooth PIN screen)
|
||||||
bool showingNormalScreen = false;
|
bool showingNormalScreen = false;
|
||||||
|
|
||||||
|
/// Holds state for debug information
|
||||||
|
DebugInfo debugInfo;
|
||||||
/// Display device
|
/// Display device
|
||||||
SSD1306Wire dispdev;
|
SSD1306Wire dispdev;
|
||||||
/// UI helper for rendering to frames and switching between them
|
/// UI helper for rendering to frames and switching between them
|
||||||
|
Loading…
Reference in New Issue
Block a user