diff --git a/docs/display-led.md b/docs/display-led.md
index 3f0f56316..aa843fa69 100644
--- a/docs/display-led.md
+++ b/docs/display-led.md
@@ -13,6 +13,64 @@ If you're using a device with OLED display, or if you add such one to the I2C bu
by pressing the button of the device.
+# Notes on powering OLED display
+
+**Different OLED display pinouts:**
+
+The TTGO T-beam boards do have solder pads for a pinheader which seems to be just right for a commonly used OLED display like the SSD1306.
+
+The most relevant pin pads are from left to right:
+
+- GND
+- 3V3
+- GND
+- 22 (SCL)
+- 21 (SDA)
+- 3.3V (label oddly differs from the other 3V3 labelled pin)
+
+However there are 2 versions of the SSD1306 OLED display available:
+
+- Most common available: GND/Vdd/SCL/SDA
+- Hard to find: Vdd/GND/SCL/SDA
+
+As can be seen, GND and Vdd are swapped and thus the most commonly available display version cannot be used without some tweaking.
+
+In order to make the most commonly available version fit, you can strip of the plastics from the power pins and carefully bend both GND and Vdd pins in a Z-shape so they will fit in the adjacent pin hole.
+
+
+
+This way the display is still positioned correctly to fit in the many available 3D printable enclosure designs out there.
+
+
+**Hardware mod for power-on issues:**
+
+Some boards like the TTGO T-beam v1.0 and newer do have a power management chip.
+
+- T-beam v1.0 and v1.1 use the AXP192
+- T-beam v1.2 uses AXP2101
+
+At least the ones using the AXP192 power management chip do have a annoying oversight in the board design.
+
+When powering on the board, the AXP192 is set to output 1.8V to both pads in the aforementioned pin header labelled "3V3" and "3.3V".
+If a display like the SSD1306 is soldered to use this as a power source, both I2C pins will be pulled down to about 1.8V + 0.3V = 2.1V by the protection diodes in the display controller.
+This may be too low to work properly for all other I2C connected devices.
+
+So the ESP32 may not be able to scan the I2C bus for any available I2C device and also not able to setup the AXP192 chip to output a higher voltage on the DCDC1 pin which powers the OLED display.
+
+This catch-22 situation can be resolved by adding a simple diode from GPIO-0 to the "3.3V" pad. (the 'line' on the diode towards the "3.3V" pad)
+
+
+
+In this test setup, a basic 1N4001 is used, which has a voltage drop of about 0.5V.
+Another option is to use a germanium diode like the 1N4148, which does have a voltage drop of 0.3V.
+
+GPIO-0 is pulled up to the 3V3 net of the ESP32. This is required for the ESP32 to boot the flashed sketch and not enter flash mode when powered on.
+
+So as soon as the ESP32 is powered, the Vdd of the OLED display will be pulled up to 3.3V - 0.5V = 2.8V.
+This is enough for the I2C pins of the display to not being pulled down and thus the ESP32 can communicate with the AXP192 power management chip.
+
+N.B. Make sure the leads of the diode cannot short any of the other pins.
+
# LED blink pattern
**Mono color LED:**
diff --git a/docs/img/SSD1306_OLED_t-beam.jpg b/docs/img/SSD1306_OLED_t-beam.jpg
new file mode 100644
index 000000000..479db9cdc
Binary files /dev/null and b/docs/img/SSD1306_OLED_t-beam.jpg differ
diff --git a/docs/img/SSD1306_t-beam_diode_mod.jpg b/docs/img/SSD1306_t-beam_diode_mod.jpg
new file mode 100644
index 000000000..8f94c7090
Binary files /dev/null and b/docs/img/SSD1306_t-beam_diode_mod.jpg differ
diff --git a/include/globals.h b/include/globals.h
index 1e8a06752..a6a94c7de 100644
--- a/include/globals.h
+++ b/include/globals.h
@@ -88,11 +88,11 @@ typedef struct {
} MessageBuffer_t;
typedef struct {
- int32_t latitude;
- int32_t longitude;
- uint8_t satellites;
- uint16_t hdop;
- int16_t altitude;
+ int32_t latitude{};
+ int32_t longitude{};
+ uint8_t satellites{};
+ uint16_t hdop{};
+ int16_t altitude{};
} gpsStatus_t;
typedef struct {
diff --git a/include/gpsread.h b/include/gpsread.h
index cb234eb18..934d8fbc6 100644
--- a/include/gpsread.h
+++ b/include/gpsread.h
@@ -11,12 +11,13 @@
#endif
extern TinyGPSPlus gps; // Make TinyGPS++ instance globally availabe
+extern bool gps_location_isupdated; // Keep track of whether it was updated when showing on the display
extern TaskHandle_t GpsTask;
int gps_init(void);
int gps_config();
bool gps_hasfix();
-void gps_storelocation(gpsStatus_t *gps_store);
+bool gps_storelocation(gpsStatus_t *gps_store);
void gps_loop(void *pvParameters);
time_t get_gpstime(uint16_t *msec);
diff --git a/src/display.cpp b/src/display.cpp
index e5332afff..aac010518 100644
--- a/src/display.cpp
+++ b/src/display.cpp
@@ -327,6 +327,14 @@ void dp_refresh(bool nextPage) {
// show latitude and longitude
dp_setFont(MY_FONT_STRETCHED);
dp->setCursor(0, MY_DISPLAY_FIRSTLINE);
+ if (gps.location.isUpdated()) {
+ // When reading the GPS location, the updated flag is reset.
+ // However if we also need to send the GPS location data,
+ // we must know whether there has been an update since the last time
+ // we sent the location.
+ gps_location_isupdated = true;
+ }
+
dp->printf("%c%09.6f\r\n", gps.location.rawLat().negative ? 'S' : 'N',
gps.location.lat());
dp->printf("%c%09.6f", gps.location.rawLng().negative ? 'W' : 'E',
diff --git a/src/gpsread.cpp b/src/gpsread.cpp
index 91e942b80..39f3fe36d 100644
--- a/src/gpsread.cpp
+++ b/src/gpsread.cpp
@@ -5,6 +5,7 @@
TinyGPSPlus gps;
+bool gps_location_isupdated = false;
TaskHandle_t GpsTask;
HardwareSerial GPS_Serial(1); // use UART #1
@@ -142,15 +143,20 @@ int gps_init(void) {
} // gps_init()
// store current GPS location data in struct
-void gps_storelocation(gpsStatus_t *gps_store) {
- if (gps.location.isUpdated() && gps.location.isValid() &&
- (gps.location.age() < 1500)) {
- gps_store->latitude = (int32_t)(gps.location.lat() * 1e6);
- gps_store->longitude = (int32_t)(gps.location.lng() * 1e6);
- gps_store->satellites = (uint8_t)gps.satellites.value();
- gps_store->hdop = (uint16_t)gps.hdop.value();
- gps_store->altitude = (int16_t)gps.altitude.meters();
+bool gps_storelocation(gpsStatus_t *gps_store) {
+ if (gps.location.isUpdated() || gps_location_isupdated) {
+ gps_location_isupdated = false;
+ if (gps.location.isValid() &&
+ (gps.location.age() < 1500)) {
+ gps_store->latitude = (int32_t)(gps.location.lat() * 1e6);
+ gps_store->longitude = (int32_t)(gps.location.lng() * 1e6);
+ gps_store->satellites = (uint8_t)gps.satellites.value();
+ gps_store->hdop = (uint16_t)gps.hdop.value();
+ gps_store->altitude = (int16_t)gps.altitude.meters();
+ return true;
+ }
}
+ return false;
}
bool gps_hasfix() {
diff --git a/src/senddata.cpp b/src/senddata.cpp
index a9a68253f..d3569654a 100644
--- a/src/senddata.cpp
+++ b/src/senddata.cpp
@@ -87,8 +87,9 @@ void sendData() {
if (GPSPORT == COUNTERPORT) {
// send GPS position only if we have a fix
if (gps_hasfix()) {
- gps_storelocation(&gps_status);
- payload.addGPS(gps_status);
+ if (gps_storelocation(&gps_status)) {
+ payload.addGPS(gps_status);
+ }
} else
ESP_LOGD(TAG, "No valid GPS position");
}
@@ -134,10 +135,11 @@ void sendData() {
if (GPSPORT != COUNTERPORT) {
// send GPS position only if we have a fix
if (gps_hasfix()) {
- gps_storelocation(&gps_status);
- payload.reset();
- payload.addGPS(gps_status);
- SendPayload(GPSPORT);
+ if (gps_storelocation(&gps_status)) {
+ payload.reset();
+ payload.addGPS(gps_status);
+ SendPayload(GPSPORT);
+ }
} else
ESP_LOGD(TAG, "No valid GPS position");
}