diff --git a/.github/workflows/compile-rtk-firmware.yml b/.github/workflows/compile-rtk-firmware.yml index f28e60008..0deae0607 100644 --- a/.github/workflows/compile-rtk-firmware.yml +++ b/.github/workflows/compile-rtk-firmware.yml @@ -71,7 +71,7 @@ jobs: ArduinoJson@6.19.4 pubsubclient@2.8.0 ESP32_BleSerial@1.0.4 - "SparkFun u-blox GNSS v3"@3.0.8 + "SparkFun u-blox GNSS v3"@3.0.9 "SparkFun MAX1704x Fuel Gauge Arduino Library"@1.0.4 "SparkFun LIS2DH12 Arduino Library"@1.0.3 "ESP32-OTA-Pull"@1.0.0 diff --git a/Firmware/RTK_Surveyor/Begin.ino b/Firmware/RTK_Surveyor/Begin.ino index 355896c13..3eafe5292 100644 --- a/Firmware/RTK_Surveyor/Begin.ino +++ b/Firmware/RTK_Surveyor/Begin.ino @@ -754,6 +754,23 @@ void configureGNSS() if (HAS_GNSS_TP_INT) theGNSS.setAutoTIMTPcallbackPtr(&storeTIMTPdata); //Enable automatic TIM TP messages with callback to storeTIMTPdata + if (HAS_ANTENNA_SHORT_OPEN) + { + theGNSS.newCfgValset(); + + theGNSS.addCfgValset(UBLOX_CFG_HW_ANT_CFG_SHORTDET, 1); // Enable antenna short detection + theGNSS.addCfgValset(UBLOX_CFG_HW_ANT_CFG_OPENDET, 1); // Enable antenna open detection + + if (theGNSS.sendCfgValset()) + { + theGNSS.setAutoMONHWcallbackPtr(&storeMONHWdata); //Enable automatic MON HW messages with callback to storeMONHWdata + } + else + { + systemPrintln("Failed to configure GNSS antenna detection"); + } + } + //Configuring the ZED can take more than 2000ms. We save configuration to //ZED so there is no need to update settings unless user has modified //the settings file or internal settings. diff --git a/Firmware/RTK_Surveyor/Display.ino b/Firmware/RTK_Surveyor/Display.ino index 6ac393989..add0fbef3 100644 --- a/Firmware/RTK_Surveyor/Display.ino +++ b/Firmware/RTK_Surveyor/Display.ino @@ -72,6 +72,10 @@ //Right bottom #define ICON_LOGGING_NTP (1<<10) +//Left bottom +#define ICON_ANTENNA_SHORT (1<<11) +#define ICON_ANTENNA_OPEN (1<<12) + //---------------------------------------- //Locals //---------------------------------------- @@ -140,6 +144,31 @@ void displayBatteryVsEthernet() icons |= (blinking_icons & ICON_ETHERNET); //Top Right } } +void displaySivVsOpenShort() +{ + if (!HAS_ANTENNA_SHORT_OPEN) + icons |= paintSIV(); + else + { + if (aStatus == SFE_UBLOX_ANTENNA_STATUS_SHORT) + { + blinking_icons ^= ICON_ANTENNA_SHORT; + icons |= (blinking_icons & ICON_ANTENNA_SHORT); + } + else if (aStatus == SFE_UBLOX_ANTENNA_STATUS_OPEN) + { + blinking_icons ^= ICON_ANTENNA_OPEN; + icons |= (blinking_icons & ICON_ANTENNA_OPEN); + } + else + { + blinking_icons &= ~ICON_ANTENNA_SHORT; + blinking_icons &= ~ICON_ANTENNA_OPEN; + icons |= paintSIV(); + } + } +} + //Given the system state, display the appropriate information void updateDisplay() @@ -218,24 +247,24 @@ void updateDisplay() case (STATE_ROVER_NOT_STARTED): icons = ICON_CROSS_HAIR //Center left | ICON_HORIZONTAL_ACCURACY //Center right - | paintSIV() //Bottom left | ICON_LOGGING; //Bottom right + displaySivVsOpenShort(); //Bottom left displayBatteryVsEthernet(); //Top right iconsRadio = setRadioIcons(); //Top left break; case (STATE_ROVER_NO_FIX): icons = ICON_CROSS_HAIR //Center left | ICON_HORIZONTAL_ACCURACY //Center right - | paintSIV() //Bottom left | ICON_LOGGING; //Bottom right + displaySivVsOpenShort(); //Bottom left displayBatteryVsEthernet(); //Top right iconsRadio = setRadioIcons(); //Top left break; case (STATE_ROVER_FIX): icons = ICON_CROSS_HAIR //Center left | ICON_HORIZONTAL_ACCURACY //Center right - | paintSIV() //Bottom left | ICON_LOGGING; //Bottom right + displaySivVsOpenShort(); //Bottom left displayBatteryVsEthernet(); //Top right iconsRadio = setRadioIcons(); //Top left break; @@ -243,16 +272,16 @@ void updateDisplay() blinking_icons ^= ICON_CROSS_HAIR_DUAL; icons = (blinking_icons & ICON_CROSS_HAIR_DUAL) //Center left | ICON_HORIZONTAL_ACCURACY //Center right - | paintSIV() //Bottom left | ICON_LOGGING; //Bottom right + displaySivVsOpenShort(); //Bottom left displayBatteryVsEthernet(); //Top right iconsRadio = setRadioIcons(); //Top left break; case (STATE_ROVER_RTK_FIX): icons = ICON_CROSS_HAIR_DUAL//Center left | ICON_HORIZONTAL_ACCURACY //Center right - | paintSIV() //Bottom left | ICON_LOGGING; //Bottom right + displaySivVsOpenShort(); //Bottom left displayBatteryVsEthernet(); //Top right iconsRadio = setRadioIcons(); //Top left break; @@ -268,8 +297,8 @@ void updateDisplay() blinking_icons ^= ICON_CROSS_HAIR; icons = (blinking_icons & ICON_CROSS_HAIR) //Center left | ICON_HORIZONTAL_ACCURACY //Center right - | paintSIV() //Bottom left | ICON_LOGGING; //Bottom right + displaySivVsOpenShort(); //Bottom left displayBatteryVsEthernet(); //Top right iconsRadio = setRadioIcons(); //Top left break; @@ -301,8 +330,8 @@ void updateDisplay() case (STATE_NTPSERVER_NO_SYNC): blinking_icons ^= ICON_CLOCK; icons = (blinking_icons & ICON_CLOCK) //Center left - | ICON_CLOCK_ACCURACY //Center right - | paintSIV(); //Bottom left + | ICON_CLOCK_ACCURACY; //Center right + displaySivVsOpenShort(); //Bottom left if (online.ethernetStatus == ETH_CONNECTED) blinking_icons |= ICON_ETHERNET; //Don't blink if link is up else @@ -314,8 +343,8 @@ void updateDisplay() case (STATE_NTPSERVER_SYNC): icons = ICON_CLOCK //Center left | ICON_CLOCK_ACCURACY //Center right - | paintSIV() //Bottom left | ICON_LOGGING_NTP; //Bottom right + displaySivVsOpenShort(); //Bottom left if (online.ethernetStatus == ETH_CONNECTED) blinking_icons |= ICON_ETHERNET; //Don't blink if link is up else @@ -539,6 +568,10 @@ void updateDisplay() displayBitmap(2, 35, SIV_Antenna_Width, SIV_Antenna_Height, SIV_Antenna); else if (icons & ICON_SIV_ANTENNA_LBAND) displayBitmap(2, 35, SIV_Antenna_LBand_Width, SIV_Antenna_LBand_Height, SIV_Antenna_LBand); + else if (icons & ICON_ANTENNA_SHORT) + displayBitmap(2, 35, Antenna_Short_Width, Antenna_Short_Height, Antenna_Short); + else if (icons & ICON_ANTENNA_OPEN) + displayBitmap(2, 35, Antenna_Open_Width, Antenna_Open_Height, Antenna_Open); //Bottom right corner if (icons & ICON_LOGGING) @@ -1647,9 +1680,37 @@ void paintBaseTempSurveyStarted() else oled.print(">10"); - oled.setCursor(0, 39); //x, y - oled.setFont(QW_FONT_5X7); - oled.print("Time:"); + if (!HAS_ANTENNA_SHORT_OPEN) + { + oled.setCursor(0, 39); //x, y + oled.setFont(QW_FONT_5X7); + oled.print("Time:"); + } + else + { + static uint32_t blinkers = 0; + if (aStatus == SFE_UBLOX_ANTENNA_STATUS_SHORT) + { + blinkers ^= ICON_ANTENNA_SHORT; + if (blinkers & ICON_ANTENNA_SHORT) + displayBitmap(2, 35, Antenna_Short_Width, Antenna_Short_Height, Antenna_Short); + } + else if (aStatus == SFE_UBLOX_ANTENNA_STATUS_OPEN) + { + blinkers ^= ICON_ANTENNA_OPEN; + if (blinkers & ICON_ANTENNA_OPEN) + displayBitmap(2, 35, Antenna_Open_Width, Antenna_Open_Height, Antenna_Open); + } + else + { + blinkers &= ~ICON_ANTENNA_SHORT; + blinkers &= ~ICON_ANTENNA_OPEN; + oled.setCursor(0, 39); //x, y + oled.setFont(QW_FONT_5X7); + oled.print("Time:"); + } + } + oled.setCursor(30, 36); //x, y oled.setFont(QW_FONT_8X16); @@ -1680,9 +1741,37 @@ void paintRTCM() else printTextCenter("Xmitting", yPos, QW_FONT_8X16, 1, false); //text, y, font type, kerning, inverted - oled.setCursor(0, 39); //x, y - oled.setFont(QW_FONT_5X7); - oled.print("RTCM:"); + + if (!HAS_ANTENNA_SHORT_OPEN) + { + oled.setCursor(0, 39); //x, y + oled.setFont(QW_FONT_5X7); + oled.print("RTCM:"); + } + else + { + static uint32_t blinkers = 0; + if (aStatus == SFE_UBLOX_ANTENNA_STATUS_SHORT) + { + blinkers ^= ICON_ANTENNA_SHORT; + if (blinkers & ICON_ANTENNA_SHORT) + displayBitmap(2, 35, Antenna_Short_Width, Antenna_Short_Height, Antenna_Short); + } + else if (aStatus == SFE_UBLOX_ANTENNA_STATUS_OPEN) + { + blinkers ^= ICON_ANTENNA_OPEN; + if (blinkers & ICON_ANTENNA_OPEN) + displayBitmap(2, 35, Antenna_Open_Width, Antenna_Open_Height, Antenna_Open); + } + else + { + blinkers &= ~ICON_ANTENNA_SHORT; + blinkers &= ~ICON_ANTENNA_OPEN; + oled.setCursor(0, 39); //x, y + oled.setFont(QW_FONT_5X7); + oled.print("RTCM:"); + } + } if (rtcmPacketsSent < 100) oled.setCursor(30, 36); //x, y - Give space for two digits diff --git a/Firmware/RTK_Surveyor/RTK_Surveyor.ino b/Firmware/RTK_Surveyor/RTK_Surveyor.ino index 70d009e2d..13395fdf2 100644 --- a/Firmware/RTK_Surveyor/RTK_Surveyor.ino +++ b/Firmware/RTK_Surveyor/RTK_Surveyor.ino @@ -306,6 +306,8 @@ bool timTpUpdated = false; uint32_t timTpEpoch; uint32_t timTpMicros; +uint8_t aStatus = SFE_UBLOX_ANTENNA_STATUS_DONTKNOW; + const byte haeNumberOfDecimals = 8; //Used for printing and transmitting lat/lon //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= diff --git a/Firmware/RTK_Surveyor/Rover.ino b/Firmware/RTK_Surveyor/Rover.ino index 03bb9a73e..d8fc0f8ea 100644 --- a/Firmware/RTK_Surveyor/Rover.ino +++ b/Firmware/RTK_Surveyor/Rover.ino @@ -248,6 +248,11 @@ void storeTIMTPdata(UBX_TIM_TP_data_t *ubxDataStruct) timTpUpdated = true; } +void storeMONHWdata(UBX_MON_HW_data_t *ubxDataStruct) +{ + aStatus = ubxDataStruct->aStatus; +} + //Helper method to convert GNSS time and date into Unix Epoch void convertGnssTimeToEpoch(uint32_t *epochSecs, uint32_t *epochMicros) { diff --git a/Firmware/RTK_Surveyor/System.ino b/Firmware/RTK_Surveyor/System.ino index c96d321f4..cd67718f2 100644 --- a/Firmware/RTK_Surveyor/System.ino +++ b/Firmware/RTK_Surveyor/System.ino @@ -626,6 +626,10 @@ bool setMessages(int maxRetries) if (ubxMessages[messageNumber].msgID == UBX_NMEA_GGA) if (rate == 0) rate = 1; + if (ubxMessages[messageNumber].msgClass == UBX_CLASS_MON) + if (ubxMessages[messageNumber].msgID == UBX_MON_HW) + if (rate == 0) + rate = 1; } response &= theGNSS.addCfgValset(ubxMessages[messageNumber].msgConfigKey + spiOffset, rate); diff --git a/Firmware/RTK_Surveyor/icons.h b/Firmware/RTK_Surveyor/icons.h index a9cb17982..298501232 100644 --- a/Firmware/RTK_Surveyor/icons.h +++ b/Firmware/RTK_Surveyor/icons.h @@ -363,6 +363,64 @@ const uint8_t SIV_Antenna_LBand [] = { 0x00, 0x10, 0x10, 0x1F, 0x1F, 0x12, 0x12, 0x04, 0x04, 0x05, 0x06, 0x00 }; +/* + Antenna_Short [12, 13] + + 1 + 123456789012 + .------------. + 0x01| * | + 0x02| * | + 0x04| * | + 0x08| ** | + 0x10| * * | + 0x20| * ***** | + 0x40| * * | + 0x80| ***** * | + 0x01| * * | + 0x02| ** | + 0x04| * | + 0x08| * | + 0x10| * | + '------------' +*/ + +const int Antenna_Short_Height = 13; +const int Antenna_Short_Width = 12; +const uint8_t Antenna_Short [] = { + 0x00, 0x80, 0xC0, 0xA0, 0x90, 0x88, 0x3F, 0x20, 0xA0, 0x60, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00 +}; + +/* + Antenna_Open [12, 13] + + 1 + 123456789012 + .------------. + 0x01| ** | + 0x02| ** | + 0x04| ** | + 0x08| ** | + 0x10| ** | + 0x20| ** | + 0x40| ** ** | + 0x80| ** | + 0x01| ** | + 0x02| ** | + 0x04| ** | + 0x08| ** | + 0x10| ** | + '------------' +*/ + +const int Antenna_Open_Height = 13; +const int Antenna_Open_Width = 12; +const uint8_t Antenna_Open [] = { + 0x00, 0x00, 0x00, 0x60, 0x70, 0x1F, 0x0F, 0xC0, 0xC0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x1F, 0x01, 0x00, 0x00, 0x00, 0x00 +}; + /* Rover_Fusion [15, 9] diff --git a/Firmware/RTK_Surveyor/settings.h b/Firmware/RTK_Surveyor/settings.h index 4ff4f2f34..29f4abff0 100644 --- a/Firmware/RTK_Surveyor/settings.h +++ b/Firmware/RTK_Surveyor/settings.h @@ -86,6 +86,9 @@ ProductVariant productVariant = RTK_SURVEYOR; #define HAS_NO_BATTERY (productVariant == REFERENCE_STATION) #define HAS_BATTERY (!HAS_NO_BATTERY) +//Macro to show if the the RTK variant has antenna short circuit / open circuit detection +#define HAS_ANTENNA_SHORT_OPEN (productVariant == REFERENCE_STATION) + typedef enum { BUTTON_ROVER = 0,