diff --git a/src/PowerFSM.cpp b/src/PowerFSM.cpp index 6804242c2..e2cf94258 100644 --- a/src/PowerFSM.cpp +++ b/src/PowerFSM.cpp @@ -35,7 +35,7 @@ static bool isPowered() static void sdsEnter() { - LOG_INFO("Enter state: SDS\n"); + LOG_DEBUG("Enter state: SDS\n"); // FIXME - make sure GPS and LORA radio are off first - because we want close to zero current draw doDeepSleep(getConfiguredOrDefaultMs(config.power.sds_secs)); } @@ -44,7 +44,7 @@ extern Power *power; static void shutdownEnter() { - LOG_INFO("Enter state: SHUTDOWN\n"); + LOG_DEBUG("Enter state: SHUTDOWN\n"); power->shutdown(); } @@ -135,7 +135,7 @@ static void lsExit() static void nbEnter() { - LOG_INFO("Enter state: NB\n"); + LOG_DEBUG("Enter state: NB\n"); screen->setOn(false); setBluetoothEnable(false); @@ -150,7 +150,7 @@ static void darkEnter() static void serialEnter() { - LOG_INFO("Enter state: SERIAL\n"); + LOG_DEBUG("Enter state: SERIAL\n"); setBluetoothEnable(false); screen->setOn(true); screen->print("Serial connected\n"); @@ -163,7 +163,7 @@ static void serialExit() static void powerEnter() { - LOG_INFO("Enter state: POWER\n"); + LOG_DEBUG("Enter state: POWER\n"); if (!isPowered()) { // If we got here, we are in the wrong state - we should be in powered, let that state ahndle things LOG_INFO("Loss of power in Powered\n"); @@ -198,7 +198,7 @@ static void powerExit() static void onEnter() { - LOG_INFO("Enter state: ON\n"); + LOG_DEBUG("Enter state: ON\n"); screen->setOn(true); setBluetoothEnable(true); } @@ -218,7 +218,7 @@ static void screenPress() static void bootEnter() { - LOG_INFO("Enter state: BOOT\n"); + LOG_DEBUG("Enter state: BOOT\n"); } State stateSHUTDOWN(shutdownEnter, NULL, NULL, "SHUTDOWN"); diff --git a/src/RedirectablePrint.cpp b/src/RedirectablePrint.cpp index 39ea76c00..0e8e1c798 100644 --- a/src/RedirectablePrint.cpp +++ b/src/RedirectablePrint.cpp @@ -62,6 +62,9 @@ size_t RedirectablePrint::vprintf(const char *format, va_list arg) size_t RedirectablePrint::log(const char *logLevel, const char *format, ...) { + if (moduleConfig.serial.override_console_serial_port && strcmp(logLevel, "DEBUG") == 0) { + return 0; + } size_t r = 0; if (!inDebugPrint) { diff --git a/src/graphics/Screen.cpp b/src/graphics/Screen.cpp index 072a9d14d..fb6806fb0 100644 --- a/src/graphics/Screen.cpp +++ b/src/graphics/Screen.cpp @@ -711,13 +711,6 @@ static float estimatedHeading(double lat, double lon) return b; } -/// Sometimes we will have Position objects that only have a time, so check for -/// valid lat/lon -static bool hasPosition(meshtastic_NodeInfo *n) -{ - return n->has_position && (n->position.latitude_i != 0 || n->position.longitude_i != 0); -} - static uint16_t getCompassDiam(OLEDDisplay *display) { uint16_t diam = 0; @@ -856,12 +849,12 @@ static void drawNodeInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_ } bool hasNodeHeading = false; - if (ourNode && hasPosition(ourNode)) { + if (ourNode && hasValidPosition(ourNode)) { meshtastic_Position &op = ourNode->position; float myHeading = estimatedHeading(DegD(op.latitude_i), DegD(op.longitude_i)); drawCompassNorth(display, compassX, compassY, myHeading); - if (hasPosition(node)) { + if (hasValidPosition(node)) { // display direction toward node hasNodeHeading = true; meshtastic_Position &p = node->position; @@ -892,7 +885,8 @@ static void drawNodeInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_ if (!hasNodeHeading) { // direction to node is unknown so display question mark // Debug info for gps lock errors - // LOG_DEBUG("ourNode %d, ourPos %d, theirPos %d\n", !!ourNode, ourNode && hasPosition(ourNode), hasPosition(node)); + // LOG_DEBUG("ourNode %d, ourPos %d, theirPos %d\n", !!ourNode, ourNode && hasValidPosition(ourNode), + // hasValidPosition(node)); display->drawString(compassX - FONT_HEIGHT_SMALL / 4, compassY - FONT_HEIGHT_SMALL / 2, "?"); } display->drawCircle(compassX, compassY, getCompassDiam(display) / 2); diff --git a/src/mesh/MeshService.cpp b/src/mesh/MeshService.cpp index 3b9ae26d2..4408f408e 100644 --- a/src/mesh/MeshService.cpp +++ b/src/mesh/MeshService.cpp @@ -239,7 +239,7 @@ void MeshService::sendNetworkPing(NodeNum dest, bool wantReplies) meshtastic_NodeInfo *node = nodeDB.getNode(nodeDB.getNodeNum()); assert(node); - if (node->has_position && (node->position.latitude_i != 0 || node->position.longitude_i != 0)) { + if (hasValidPosition(node)) { if (positionModule) { LOG_INFO("Sending position ping to 0x%x, wantReplies=%d, channel=%d\n", dest, wantReplies, node->channel); positionModule->sendOurPosition(dest, wantReplies, node->channel); diff --git a/src/mesh/NodeDB.cpp b/src/mesh/NodeDB.cpp index feabd5029..b1dd3d06d 100644 --- a/src/mesh/NodeDB.cpp +++ b/src/mesh/NodeDB.cpp @@ -584,10 +584,10 @@ void NodeDB::saveToDisk(int saveWhat) } } -const meshtastic_NodeInfo *NodeDB::readNextInfo() +const meshtastic_NodeInfo *NodeDB::readNextInfo(uint32_t &readIndex) { - if (readPointer < *numNodes) - return &nodes[readPointer++]; + if (readIndex < *numNodes) + return &nodes[readIndex++]; else return NULL; } diff --git a/src/mesh/NodeDB.h b/src/mesh/NodeDB.h index 541b51f83..65ab72c8c 100644 --- a/src/mesh/NodeDB.h +++ b/src/mesh/NodeDB.h @@ -46,8 +46,6 @@ class NodeDB meshtastic_NodeInfo *nodes; pb_size_t *numNodes; - uint32_t readPointer = 0; - public: bool updateGUI = false; // we think the gui should definitely be redrawn, screen will clear this once handled meshtastic_NodeInfo *updateGUIforNode = NULL; // if currently showing this node, we think you should update the GUI @@ -104,11 +102,8 @@ class NodeDB their denial?) */ - /// Called from bluetooth when the user wants to start reading the node DB from scratch. - void resetReadPointer() { readPointer = 0; } - /// Allow the bluetooth layer to read our next nodeinfo record, or NULL if done reading - const meshtastic_NodeInfo *readNextInfo(); + const meshtastic_NodeInfo *readNextInfo(uint32_t &readIndex); /// pick a provisional nodenum we hope no one is using void pickNewNodeNum(); @@ -217,6 +212,13 @@ inline uint32_t getConfiguredOrDefaultMs(uint32_t configuredInterval, uint32_t d return defaultInterval * 1000; } +/// Sometimes we will have Position objects that only have a time, so check for +/// valid lat/lon +static inline bool hasValidPosition(const meshtastic_NodeInfo *n) +{ + return n->has_position && (n->position.latitude_i != 0 || n->position.longitude_i != 0); +} + /** The current change # for radio settings. Starts at 0 on boot and any time the radio settings * might have changed is incremented. Allows others to detect they might now be on a new channel. */ diff --git a/src/mesh/PhoneAPI.cpp b/src/mesh/PhoneAPI.cpp index 559f7ed31..76c2ba3db 100644 --- a/src/mesh/PhoneAPI.cpp +++ b/src/mesh/PhoneAPI.cpp @@ -40,9 +40,8 @@ void PhoneAPI::handleStartConfig() state = STATE_SEND_MY_INFO; LOG_INFO("Starting API client config\n"); - nodeInfoForPhone = NULL; // Don't keep returning old nodeinfos - nodeDB.resetReadPointer(); // FIXME, this read pointer should be moved out of nodeDB and into this class - because - // this will break once we have multiple instances of PhoneAPI running independently + nodeInfoForPhone = NULL; // Don't keep returning old nodeinfos + resetReadIndex(); } void PhoneAPI::close() @@ -373,7 +372,7 @@ bool PhoneAPI::available() case STATE_SEND_NODEINFO: if (!nodeInfoForPhone) - nodeInfoForPhone = nodeDB.readNextInfo(); + nodeInfoForPhone = nodeDB.readNextInfo(readIndex); return true; // Always say we have something, because we might need to advance our state machine case STATE_SEND_PACKETS: { diff --git a/src/mesh/PhoneAPI.h b/src/mesh/PhoneAPI.h index af8f1be26..2ea4d3a0c 100644 --- a/src/mesh/PhoneAPI.h +++ b/src/mesh/PhoneAPI.h @@ -58,6 +58,9 @@ class PhoneAPI /// Use to ensure that clients don't get confused about old messages from the radio uint32_t config_nonce = 0; + uint32_t readIndex = 0; + + void resetReadIndex() { readIndex = 0; } public: PhoneAPI(); diff --git a/src/modules/PositionModule.cpp b/src/modules/PositionModule.cpp index 89503d2b9..12f2fedc3 100644 --- a/src/modules/PositionModule.cpp +++ b/src/modules/PositionModule.cpp @@ -154,7 +154,7 @@ int32_t PositionModule::runOnce() if (lastGpsSend == 0 || msSinceLastSend >= intervalMs) { // Only send packets if the channel is less than 40% utilized. if (airTime->isTxAllowedChannelUtil()) { - if (node->has_position && (node->position.latitude_i != 0 || node->position.longitude_i != 0)) { + if (hasValidPosition(node)) { lastGpsSend = now; lastGpsLatitude = node->position.latitude_i; @@ -173,7 +173,7 @@ int32_t PositionModule::runOnce() if (airTime->isTxAllowedChannelUtil(config.device.role != meshtastic_Config_DeviceConfig_Role_TRACKER)) { meshtastic_NodeInfo *node2 = service.refreshMyNodeInfo(); // should guarantee there is now a position - if (node2->has_position && (node2->position.latitude_i != 0 || node2->position.longitude_i != 0)) { + if (hasValidPosition(node2)) { // The minimum distance to travel before we are able to send a new position packet. const uint32_t distanceTravelThreshold = config.position.broadcast_smart_minimum_distance > 0 ? config.position.broadcast_smart_minimum_distance : 100; diff --git a/src/modules/SerialModule.cpp b/src/modules/SerialModule.cpp index 2c342b318..1a7c081c6 100644 --- a/src/modules/SerialModule.cpp +++ b/src/modules/SerialModule.cpp @@ -62,10 +62,10 @@ SerialModule::SerialModule() : StreamAPI(&Serial2), concurrency::OSThread("Seria char serialBytes[meshtastic_Constants_DATA_PAYLOAD_LEN]; size_t serialPayloadSize; +static Print *serialPrint = &Serial2; SerialModuleRadio::SerialModuleRadio() : MeshModule("SerialModuleRadio") { - switch (moduleConfig.serial.mode) { case meshtastic_ModuleConfig_SerialConfig_Serial_Mode_TEXTMSG: ourPortNum = meshtastic_PortNum_TEXT_MESSAGE_APP; @@ -96,40 +96,51 @@ int32_t SerialModule::runOnce() without having to configure it from the PythonAPI or WebUI. */ - // moduleConfig.serial.enabled = 1; + // moduleConfig.serial.enabled = true; // moduleConfig.serial.rxd = 35; // moduleConfig.serial.txd = 15; + // moduleConfig.serial.override_console_serial_port = true; + // moduleConfig.serial.mode = meshtastic_ModuleConfig_SerialConfig_Serial_Mode_CALTOPO; // moduleConfig.serial.timeout = 1000; // moduleConfig.serial.echo = 1; - if (moduleConfig.serial.enabled && moduleConfig.serial.rxd && moduleConfig.serial.txd) { + if (!moduleConfig.serial.enabled) + return disable(); + if (moduleConfig.serial.override_console_serial_port || (moduleConfig.serial.rxd && moduleConfig.serial.txd)) { if (firstTime) { - // Interface with the serial peripheral from in here. LOG_INFO("Initializing serial peripheral interface\n"); uint32_t baud = getBaudRate(); + if (moduleConfig.serial.override_console_serial_port) { + Serial.flush(); + serialPrint = &Serial; + // Give it a chance to flush out 💩 + delay(10); + } else { + serialPrint = &Serial2; + } #ifdef ARCH_ESP32 - Serial2.setRxBufferSize(RX_BUFFER); if (moduleConfig.serial.rxd && moduleConfig.serial.txd) { + Serial2.setRxBufferSize(RX_BUFFER); Serial2.begin(baud, SERIAL_8N1, moduleConfig.serial.rxd, moduleConfig.serial.txd); + } else { + Serial.begin(baud); + Serial.setTimeout(moduleConfig.serial.timeout > 0 ? moduleConfig.serial.timeout : TIMEOUT); } #else - if (moduleConfig.serial.rxd && moduleConfig.serial.txd) + if (moduleConfig.serial.rxd && moduleConfig.serial.txd) { Serial2.setPins(moduleConfig.serial.rxd, moduleConfig.serial.txd); - - Serial2.begin(baud, SERIAL_8N1); - -#endif - if (moduleConfig.serial.timeout) { - Serial2.setTimeout(moduleConfig.serial.timeout); // Number of MS to wait to set the timeout for the string. + Serial2.begin(baud, SERIAL_8N1); + Serial2.setTimeout(moduleConfig.serial.timeout > 0 ? moduleConfig.serial.timeout : TIMEOUT); } else { - Serial2.setTimeout(TIMEOUT); // Number of MS to wait to set the timeout for the string. + Serial.begin(baud, SERIAL_8N1); + Serial.setTimeout(moduleConfig.serial.timeout > 0 ? moduleConfig.serial.timeout : TIMEOUT); } - +#endif serialModuleRadio = new SerialModuleRadio(); firstTime = 0; @@ -139,21 +150,25 @@ int32_t SerialModule::runOnce() emitRebooted(); } } else { - if (moduleConfig.serial.mode == meshtastic_ModuleConfig_SerialConfig_Serial_Mode_PROTO) { return runOncePart(); - } else if (moduleConfig.serial.mode == meshtastic_ModuleConfig_SerialConfig_Serial_Mode_NMEA || - moduleConfig.serial.mode == meshtastic_ModuleConfig_SerialConfig_Serial_Mode_CALTOPO) { + } else if (moduleConfig.serial.mode == meshtastic_ModuleConfig_SerialConfig_Serial_Mode_NMEA) { // in NMEA mode send out GGA every 2 seconds, Don't read from Port if (millis() - lastNmeaTime > 2000) { lastNmeaTime = millis(); - if (moduleConfig.serial.mode == meshtastic_ModuleConfig_SerialConfig_Serial_Mode_CALTOPO) { - printWPL(outbuf, sizeof(outbuf), nodeDB.getNode(myNodeInfo.my_node_num)->position, - nodeDB.getNode(myNodeInfo.my_node_num)->user.long_name, true); - } else { - printGGA(outbuf, sizeof(outbuf), nodeDB.getNode(myNodeInfo.my_node_num)->position); + printGGA(outbuf, sizeof(outbuf), nodeDB.getNode(myNodeInfo.my_node_num)->position); + serialPrint->printf("%s", outbuf); + } + } else if (moduleConfig.serial.mode == meshtastic_ModuleConfig_SerialConfig_Serial_Mode_CALTOPO) { + if (millis() - lastNmeaTime > 10000) { + lastNmeaTime = millis(); + uint32_t readIndex = 0; + const meshtastic_NodeInfo *tempNodeInfo = nodeDB.readNextInfo(readIndex); + while (tempNodeInfo != NULL && tempNodeInfo->has_user && hasValidPosition(tempNodeInfo)) { + printWPL(outbuf, sizeof(outbuf), tempNodeInfo->position, tempNodeInfo->user.long_name, true); + serialPrint->printf("%s", outbuf); + tempNodeInfo = nodeDB.readNextInfo(readIndex); } - Serial2.printf("%s", outbuf); } } else { while (Serial2.available()) { @@ -162,7 +177,6 @@ int32_t SerialModule::runOnce() } } } - return (10); } else { return disable(); @@ -219,22 +233,23 @@ ProcessMessage SerialModuleRadio::handleReceived(const meshtastic_MeshPacket &mp if (lastRxID != mp.id) { lastRxID = mp.id; // LOG_DEBUG("* * Message came this device\n"); - // Serial2.println("* * Message came this device"); - Serial2.printf("%s", p.payload.bytes); + // serialPrint->println("* * Message came this device"); + serialPrint->printf("%s", p.payload.bytes); } } } else { if (moduleConfig.serial.mode == meshtastic_ModuleConfig_SerialConfig_Serial_Mode_DEFAULT || moduleConfig.serial.mode == meshtastic_ModuleConfig_SerialConfig_Serial_Mode_SIMPLE) { - Serial2.printf("%s", p.payload.bytes); + serialPrint->printf("%s", p.payload.bytes); } else if (moduleConfig.serial.mode == meshtastic_ModuleConfig_SerialConfig_Serial_Mode_TEXTMSG) { meshtastic_NodeInfo *node = nodeDB.getNode(getFrom(&mp)); String sender = (node && node->has_user) ? node->user.short_name : "???"; - Serial2.println(); - Serial2.printf("%s: %s", sender, p.payload.bytes); - Serial2.println(); - } else if (moduleConfig.serial.mode == meshtastic_ModuleConfig_SerialConfig_Serial_Mode_NMEA) { + serialPrint->println(); + serialPrint->printf("%s: %s", sender, p.payload.bytes); + serialPrint->println(); + } else if (moduleConfig.serial.mode == meshtastic_ModuleConfig_SerialConfig_Serial_Mode_NMEA || + moduleConfig.serial.mode == meshtastic_ModuleConfig_SerialConfig_Serial_Mode_CALTOPO) { // Decode the Payload some more meshtastic_Position scratch; meshtastic_Position *decoded = NULL; @@ -246,7 +261,7 @@ ProcessMessage SerialModuleRadio::handleReceived(const meshtastic_MeshPacket &mp // send position packet as WPL to the serial port printWPL(outbuf, sizeof(outbuf), *decoded, nodeDB.getNode(getFrom(&mp))->user.long_name, moduleConfig.serial.mode == meshtastic_ModuleConfig_SerialConfig_Serial_Mode_CALTOPO); - Serial2.printf("%s", outbuf); + serialPrint->printf("%s", outbuf); } } } @@ -256,9 +271,7 @@ ProcessMessage SerialModuleRadio::handleReceived(const meshtastic_MeshPacket &mp uint32_t SerialModule::getBaudRate() { - if (moduleConfig.serial.baud == meshtastic_ModuleConfig_SerialConfig_Serial_Baud_BAUD_DEFAULT) { - return 38400; - } else if (moduleConfig.serial.baud == meshtastic_ModuleConfig_SerialConfig_Serial_Baud_BAUD_110) { + if (moduleConfig.serial.baud == meshtastic_ModuleConfig_SerialConfig_Serial_Baud_BAUD_110) { return 110; } else if (moduleConfig.serial.baud == meshtastic_ModuleConfig_SerialConfig_Serial_Baud_BAUD_300) { return 300; @@ -289,6 +302,6 @@ uint32_t SerialModule::getBaudRate() } else if (moduleConfig.serial.baud == meshtastic_ModuleConfig_SerialConfig_Serial_Baud_BAUD_921600) { return 921600; } - return 38400; + return BAUD; } #endif