diff --git a/src/Power.cpp b/src/Power.cpp index a9ed6360e..12b1a0ff2 100644 --- a/src/Power.cpp +++ b/src/Power.cpp @@ -853,7 +853,8 @@ int32_t Power::runOnce() #ifndef T_WATCH_S3 // FIXME - why is this triggering on the T-Watch S3? if (PMU->isPekeyLongPressIrq()) { LOG_DEBUG("PEK long button press"); - screen->setOn(false); + if (screen) + screen->setOn(false); } #endif diff --git a/src/PowerFSM.cpp b/src/PowerFSM.cpp index 02b637d3c..0263fed5f 100644 --- a/src/PowerFSM.cpp +++ b/src/PowerFSM.cpp @@ -82,7 +82,8 @@ static uint32_t secsSlept; static void lsEnter() { LOG_INFO("lsEnter begin, ls_secs=%u", config.power.ls_secs); - screen->setOn(false); + if (screen) + screen->setOn(false); secsSlept = 0; // How long have we been sleeping this time // LOG_INFO("lsEnter end"); @@ -160,7 +161,8 @@ static void lsExit() static void nbEnter() { LOG_DEBUG("State: NB"); - screen->setOn(false); + if (screen) + screen->setOn(false); #ifdef ARCH_ESP32 // Only ESP32 should turn off bluetooth setBluetoothEnable(false); @@ -190,7 +192,8 @@ static void serialExit() { // Turn bluetooth back on when we leave serial stream API setBluetoothEnable(true); - screen->print("Serial disconnected\n"); + if (screen) + screen->print("Serial disconnected\n"); } static void powerEnter() @@ -201,7 +204,7 @@ static void powerEnter() LOG_INFO("Loss of power in Powered"); powerFSM.trigger(EVENT_POWER_DISCONNECTED); } else { - if (config.display.displaymode != meshtastic_Config_DisplayConfig_DisplayMode_COLOR ) + if (screen) screen->setOn(true); setBluetoothEnable(true); // within enter() the function getState() returns the state we came from @@ -226,7 +229,7 @@ static void powerIdle() static void powerExit() { if (screen) - screen->setOn(true); + screen->setOn(true); setBluetoothEnable(true); // Mothballed: print change of power-state to device screen @@ -237,7 +240,8 @@ static void powerExit() static void onEnter() { LOG_DEBUG("State: ON"); - screen->setOn(true); + if (screen) + screen->setOn(true); setBluetoothEnable(true); } @@ -251,7 +255,8 @@ static void onIdle() static void screenPress() { - screen->onPress(); + if (screen) + screen->onPress(); } static void bootEnter() diff --git a/src/input/ScanAndSelect.cpp b/src/input/ScanAndSelect.cpp index 1262f99b4..306f96f0d 100644 --- a/src/input/ScanAndSelect.cpp +++ b/src/input/ScanAndSelect.cpp @@ -84,7 +84,8 @@ int32_t ScanAndSelectInput::runOnce() // Dismiss the alert screen several seconds after it appears if (!Throttle::isWithinTimespanMs(alertingSinceMs, durationAlertMs)) { alertingNoMessage = false; - screen->endAlert(); + if (screen) + screen->endAlert(); } } @@ -183,13 +184,15 @@ void ScanAndSelectInput::alertNoMessage() alertingSinceMs = millis(); // Graphics code: the alert frame to show on screen - screen->startAlert([](OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) -> void { - display->setTextAlignment(TEXT_ALIGN_CENTER_BOTH); - display->setFont(FONT_SMALL); - int16_t textX = display->getWidth() / 2; - int16_t textY = display->getHeight() / 2; - display->drawString(textX + x, textY + y, "No Canned Messages"); - }); + if (screen) { + screen->startAlert([](OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) -> void { + display->setTextAlignment(TEXT_ALIGN_CENTER_BOTH); + display->setFont(FONT_SMALL); + int16_t textX = display->getWidth() / 2; + int16_t textY = display->getHeight() / 2; + display->drawString(textX + x, textY + y, "No Canned Messages"); + }); + } } // Remove the canned message frame from screen diff --git a/src/main.cpp b/src/main.cpp index fb9799a43..0a08dec69 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1227,7 +1227,8 @@ void setup() nodeDB->saveToDisk(SEGMENT_CONFIG); if (!rIf->reconfigure()) { LOG_WARN("Reconfigure failed, rebooting"); - screen->startAlert("Rebooting..."); + if (screen) + screen->startAlert("Rebooting..."); rebootAtMsec = millis() + 5000; } } diff --git a/src/mesh/http/ContentHandler.cpp b/src/mesh/http/ContentHandler.cpp index 5841fe478..c1d5a8dbe 100644 --- a/src/mesh/http/ContentHandler.cpp +++ b/src/mesh/http/ContentHandler.cpp @@ -903,6 +903,7 @@ void handleBlinkLED(HTTPRequest *req, HTTPResponse *res) } } else { #if HAS_SCREEN + if (screen) screen->blink(); #endif } diff --git a/src/mesh/http/WebServer.cpp b/src/mesh/http/WebServer.cpp index 5f6ad9eb3..bf170de59 100644 --- a/src/mesh/http/WebServer.cpp +++ b/src/mesh/http/WebServer.cpp @@ -154,7 +154,8 @@ void createSSLCert() esp_task_wdt_reset(); #if HAS_SCREEN if (millis() / 1000 >= 3) { - screen->setSSLFrames(); + if (screen) + screen->setSSLFrames(); } #endif } diff --git a/src/modules/AdminModule.cpp b/src/modules/AdminModule.cpp index 3ff4fa74d..5cf5d778d 100644 --- a/src/modules/AdminModule.cpp +++ b/src/modules/AdminModule.cpp @@ -200,14 +200,16 @@ bool AdminModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshta #if defined(ARCH_ESP32) #if !MESHTASTIC_EXCLUDE_BLUETOOTH if (!BleOta::getOtaAppVersion().isEmpty()) { - screen->startFirmwareUpdateScreen(); + if (screen) + screen->startFirmwareUpdateScreen(); BleOta::switchToOtaApp(); LOG_INFO("Rebooting to BLE OTA"); } #endif #if !MESHTASTIC_EXCLUDE_WIFI if (WiFiOTA::trySwitchToOTA()) { - screen->startFirmwareUpdateScreen(); + if (screen) + screen->startFirmwareUpdateScreen(); WiFiOTA::saveConfig(&config.network); LOG_INFO("Rebooting to WiFi OTA"); } @@ -1111,7 +1113,8 @@ void AdminModule::handleGetDeviceUIConfig(const meshtastic_MeshPacket &req) void AdminModule::reboot(int32_t seconds) { LOG_INFO("Reboot in %d seconds", seconds); - screen->startAlert("Rebooting..."); + if (screen) + screen->startAlert("Rebooting..."); rebootAtMsec = (seconds < 0) ? 0 : (millis() + seconds * 1000); } diff --git a/src/modules/RemoteHardwareModule.cpp b/src/modules/RemoteHardwareModule.cpp index 9bc8512b6..c49c57eda 100644 --- a/src/modules/RemoteHardwareModule.cpp +++ b/src/modules/RemoteHardwareModule.cpp @@ -84,7 +84,8 @@ bool RemoteHardwareModule::handleReceivedProtobuf(const meshtastic_MeshPacket &r switch (p.type) { case meshtastic_HardwareMessage_Type_WRITE_GPIOS: { // Print notification to LCD screen - screen->print("Write GPIOs\n"); + if (screen) + screen->print("Write GPIOs\n"); pinModes(p.gpio_mask, OUTPUT, availablePins); for (uint8_t i = 0; i < NUM_GPIOS; i++) { diff --git a/src/modules/ReplyModule.cpp b/src/modules/ReplyModule.cpp index c4f63c6b1..37cbd30d8 100644 --- a/src/modules/ReplyModule.cpp +++ b/src/modules/ReplyModule.cpp @@ -14,8 +14,8 @@ meshtastic_MeshPacket *ReplyModule::allocReply() // The incoming message is in p.payload LOG_INFO("Received message from=0x%0x, id=%d, msg=%.*s", req.from, req.id, p.payload.size, p.payload.bytes); #endif - - screen->print("Send reply\n"); + if (screen) + screen->print("Send reply\n"); const char *replyStr = "Message Received"; auto reply = allocDataPacket(); // Allocate a packet for sending diff --git a/src/motion/BMX160Sensor.cpp b/src/motion/BMX160Sensor.cpp index a3909ea3a..003ee850c 100755 --- a/src/motion/BMX160Sensor.cpp +++ b/src/motion/BMX160Sensor.cpp @@ -37,7 +37,8 @@ int32_t BMX160Sensor::runOnce() if (!showingScreen) { powerFSM.trigger(EVENT_PRESS); // keep screen alive during calibration showingScreen = true; - screen->startAlert((FrameCallback)drawFrameCalibration); + if (screen) + screen->startAlert((FrameCallback)drawFrameCalibration); } if (magAccel.x > highestX) @@ -58,7 +59,8 @@ int32_t BMX160Sensor::runOnce() doCalibration = false; endCalibrationAt = 0; showingScreen = false; - screen->endAlert(); + if (screen) + screen->endAlert(); } // LOG_DEBUG("BMX160 min_x: %.4f, max_X: %.4f, min_Y: %.4f, max_Y: %.4f, min_Z: %.4f, max_Z: %.4f", lowestX, highestX, @@ -103,8 +105,8 @@ int32_t BMX160Sensor::runOnce() heading += 270; break; } - - screen->setHeading(heading); + if (screen) + screen->setHeading(heading); #endif return MOTION_SENSOR_CHECK_INTERVAL_MS; @@ -118,7 +120,8 @@ void BMX160Sensor::calibrate(uint16_t forSeconds) doCalibration = true; uint16_t calibrateFor = forSeconds * 1000; // calibrate for seconds provided endCalibrationAt = millis() + calibrateFor; - screen->setEndCalibration(endCalibrationAt); + if (screen) + screen->setEndCalibration(endCalibrationAt); #endif } diff --git a/src/motion/ICM20948Sensor.cpp b/src/motion/ICM20948Sensor.cpp index d03633124..a4c82c6ec 100755 --- a/src/motion/ICM20948Sensor.cpp +++ b/src/motion/ICM20948Sensor.cpp @@ -60,7 +60,8 @@ int32_t ICM20948Sensor::runOnce() if (!showingScreen) { powerFSM.trigger(EVENT_PRESS); // keep screen alive during calibration showingScreen = true; - screen->startAlert((FrameCallback)drawFrameCalibration); + if (screen) + screen->startAlert((FrameCallback)drawFrameCalibration); } if (magX > highestX) @@ -81,7 +82,8 @@ int32_t ICM20948Sensor::runOnce() doCalibration = false; endCalibrationAt = 0; showingScreen = false; - screen->endAlert(); + if (screen) + screen->endAlert(); } // LOG_DEBUG("ICM20948 min_x: %.4f, max_X: %.4f, min_Y: %.4f, max_Y: %.4f, min_Z: %.4f, max_Z: %.4f", lowestX, highestX, @@ -124,8 +126,8 @@ int32_t ICM20948Sensor::runOnce() heading += 270; break; } - - screen->setHeading(heading); + if (screen) + screen->setHeading(heading); #endif // Wake on motion using polling - this is not as efficient as using hardware interrupt pin (see above) @@ -159,7 +161,8 @@ void ICM20948Sensor::calibrate(uint16_t forSeconds) doCalibration = true; uint16_t calibrateFor = forSeconds * 1000; // calibrate for seconds provided endCalibrationAt = millis() + calibrateFor; - screen->setEndCalibration(endCalibrationAt); + if (screen) + screen->setEndCalibration(endCalibrationAt); #endif } // ---------------------------------------------------------------------- diff --git a/src/nimble/NimbleBluetooth.cpp b/src/nimble/NimbleBluetooth.cpp index 009439f25..80787092d 100644 --- a/src/nimble/NimbleBluetooth.cpp +++ b/src/nimble/NimbleBluetooth.cpp @@ -94,31 +94,33 @@ class NimbleBluetoothServerCallback : public NimBLEServerCallbacks bluetoothStatus->updateStatus(new meshtastic::BluetoothStatus(std::to_string(passkey))); #if HAS_SCREEN // Todo: migrate this display code back into Screen class, and observe bluetoothStatus - screen->startAlert([passkey](OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) -> void { - char btPIN[16] = "888888"; - snprintf(btPIN, sizeof(btPIN), "%06u", passkey); - int x_offset = display->width() / 2; - int y_offset = display->height() <= 80 ? 0 : 32; - display->setTextAlignment(TEXT_ALIGN_CENTER); - display->setFont(FONT_MEDIUM); - display->drawString(x_offset + x, y_offset + y, "Bluetooth"); + if (screen) { + screen->startAlert([passkey](OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) -> void { + char btPIN[16] = "888888"; + snprintf(btPIN, sizeof(btPIN), "%06u", passkey); + int x_offset = display->width() / 2; + int y_offset = display->height() <= 80 ? 0 : 32; + display->setTextAlignment(TEXT_ALIGN_CENTER); + display->setFont(FONT_MEDIUM); + display->drawString(x_offset + x, y_offset + y, "Bluetooth"); - display->setFont(FONT_SMALL); - y_offset = display->height() == 64 ? y_offset + FONT_HEIGHT_MEDIUM - 4 : y_offset + FONT_HEIGHT_MEDIUM + 5; - display->drawString(x_offset + x, y_offset + y, "Enter this code"); + display->setFont(FONT_SMALL); + y_offset = display->height() == 64 ? y_offset + FONT_HEIGHT_MEDIUM - 4 : y_offset + FONT_HEIGHT_MEDIUM + 5; + display->drawString(x_offset + x, y_offset + y, "Enter this code"); - display->setFont(FONT_LARGE); - String displayPin(btPIN); - String pin = displayPin.substring(0, 3) + " " + displayPin.substring(3, 6); - y_offset = display->height() == 64 ? y_offset + FONT_HEIGHT_SMALL - 5 : y_offset + FONT_HEIGHT_SMALL + 5; - display->drawString(x_offset + x, y_offset + y, pin); + display->setFont(FONT_LARGE); + String displayPin(btPIN); + String pin = displayPin.substring(0, 3) + " " + displayPin.substring(3, 6); + y_offset = display->height() == 64 ? y_offset + FONT_HEIGHT_SMALL - 5 : y_offset + FONT_HEIGHT_SMALL + 5; + display->drawString(x_offset + x, y_offset + y, pin); - display->setFont(FONT_SMALL); - String deviceName = "Name: "; - deviceName.concat(getDeviceName()); - y_offset = display->height() == 64 ? y_offset + FONT_HEIGHT_LARGE - 6 : y_offset + FONT_HEIGHT_LARGE + 5; - display->drawString(x_offset + x, y_offset + y, deviceName); - }); + display->setFont(FONT_SMALL); + String deviceName = "Name: "; + deviceName.concat(getDeviceName()); + y_offset = display->height() == 64 ? y_offset + FONT_HEIGHT_LARGE - 6 : y_offset + FONT_HEIGHT_LARGE + 5; + display->drawString(x_offset + x, y_offset + y, deviceName); + }); + } #endif passkeyShowing = true; @@ -134,7 +136,8 @@ class NimbleBluetoothServerCallback : public NimBLEServerCallbacks // Todo: migrate this display code back into Screen class, and observe bluetoothStatus if (passkeyShowing) { passkeyShowing = false; - screen->endAlert(); + if (screen) + screen->endAlert(); } } diff --git a/src/shutdown.h b/src/shutdown.h index f02cb7964..63066c988 100644 --- a/src/shutdown.h +++ b/src/shutdown.h @@ -41,7 +41,7 @@ void powerCommandsCheck() } #if defined(ARCH_ESP32) || defined(ARCH_NRF52) - if (shutdownAtMsec) { + if (shutdownAtMsec && screen) { screen->startAlert("Shutting down..."); } #endif diff --git a/src/sleep.cpp b/src/sleep.cpp index 8ffb08b04..2fe4c71cd 100644 --- a/src/sleep.cpp +++ b/src/sleep.cpp @@ -221,8 +221,8 @@ void doDeepSleep(uint32_t msecToWake, bool skipPreflight = false, bool skipSaveN #endif powerMon->setState(meshtastic_PowerMon_State_CPU_DeepSleep); - - screen->doDeepSleep(); // datasheet says this will draw only 10ua + if (screen) + screen->doDeepSleep(); // datasheet says this will draw only 10ua if (!skipSaveNodeDb) { nodeDB->saveToDisk();