diff --git a/docs/Settings.md b/docs/Settings.md index b886f6702ac..76b82df69ae 100644 --- a/docs/Settings.md +++ b/docs/Settings.md @@ -4772,6 +4772,16 @@ Value above which to make the OSD distance from home indicator blink (meters) --- +### osd_elements_updated_per_cycle + +Number of OSD elements to update per OSD cycle. Increase this value to reduce the time it takes to update all OSD elements, at the cost of higher CPU usage. Decrease this value to reduce CPU usage, at the cost of slower OSD element updates. + +| Default | Min | Max | +| --- | --- | --- | +| 5 | 1 | 10 | + +--- + ### osd_esc_rpm_precision Number of characters used to display the RPM value. diff --git a/src/main/fc/settings.yaml b/src/main/fc/settings.yaml index 01ca6149bfb..2aaa51f6ed4 100644 --- a/src/main/fc/settings.yaml +++ b/src/main/fc/settings.yaml @@ -3329,6 +3329,12 @@ groups: max: 600 type: int16_t field: msp_displayport_fullframe_interval + - name: osd_elements_updated_per_cycle + description: "Number of OSD elements to update per OSD cycle. Increase this value to reduce the time it takes to update all OSD elements, at the cost of higher CPU usage. Decrease this value to reduce CPU usage, at the cost of slower OSD element updates." + default_value: 5 + field: elements_updated_per_cycle + min: 1 + max: 10 - name: osd_units description: "IMPERIAL, METRIC, UK" default_value: "METRIC" diff --git a/src/main/io/osd.c b/src/main/io/osd.c index c7a40e982cc..84ee5ed6a5d 100644 --- a/src/main/io/osd.c +++ b/src/main/io/osd.c @@ -4242,18 +4242,28 @@ uint8_t osdIncElementIndex(uint8_t elementIndex) return elementIndex; } -void osdDrawNextElement(void) +void osdDrawNextElements(void) { static uint8_t elementIndex = 0; - // Flag for end of loop, also prevents infinite loop when no elements are enabled - uint8_t index = elementIndex; - do { - elementIndex = osdIncElementIndex(elementIndex); - } while (!osdDrawSingleElement(elementIndex) && index != elementIndex); + + for (uint8_t i = 1; i <= osdConfig()->elements_updated_per_cycle; i++) { + // Flag for end of loop, also prevents infinite loop when no elements are enabled + uint8_t index = elementIndex; + do { + elementIndex = osdIncElementIndex(elementIndex); + } while (!osdDrawSingleElement(elementIndex) && index != elementIndex); + + if (index == elementIndex || elementIndex == 0) { + break; + } + } // Draw artificial horizon + tracking telemetry last - osdDrawSingleElement(OSD_ARTIFICIAL_HORIZON); - if (osdConfig()->telemetry>0){ + if (osdElementEnabled(OSD_ARTIFICIAL_HORIZON, true)) { + osdDrawSingleElement(OSD_ARTIFICIAL_HORIZON); + } + + if (osdConfig()->telemetry > 0){ osdDisplayTelemetry(); } } @@ -4304,6 +4314,7 @@ PG_RESET_TEMPLATE(osdConfig_t, osdConfig, .video_system = SETTING_OSD_VIDEO_SYSTEM_DEFAULT, .row_shiftdown = SETTING_OSD_ROW_SHIFTDOWN_DEFAULT, .msp_displayport_fullframe_interval = SETTING_OSD_MSP_DISPLAYPORT_FULLFRAME_INTERVAL_DEFAULT, + .elements_updated_per_cycle = SETTING_OSD_ELEMENTS_UPDATED_PER_CYCLE_DEFAULT, .ahi_reverse_roll = SETTING_OSD_AHI_REVERSE_ROLL_DEFAULT, .ahi_max_pitch = SETTING_OSD_AHI_MAX_PITCH_DEFAULT, @@ -5976,7 +5987,7 @@ static void osdRefresh(timeUs_t currentTimeUs) displayClearScreen(osdDisplayPort); fullRedraw = false; } - osdDrawNextElement(); + osdDrawNextElements(); displayHeartbeat(osdDisplayPort); displayCommitTransaction(osdDisplayPort); #ifdef OSD_CALLS_CMS diff --git a/src/main/io/osd.h b/src/main/io/osd.h index bbaa68f862d..15d388b63a6 100644 --- a/src/main/io/osd.h +++ b/src/main/io/osd.h @@ -451,6 +451,7 @@ typedef struct osdConfig_s { videoSystem_e video_system; uint8_t row_shiftdown; int16_t msp_displayport_fullframe_interval; + uint8_t elements_updated_per_cycle; // Preferences uint8_t main_voltage_decimals;