diff --git a/libraries/AP_Notify/AP_Notify.cpp b/libraries/AP_Notify/AP_Notify.cpp index ff76730ac0706..dead0dc9af9c0 100644 --- a/libraries/AP_Notify/AP_Notify.cpp +++ b/libraries/AP_Notify/AP_Notify.cpp @@ -382,6 +382,16 @@ void AP_Notify::handle_rgb(uint8_t r, uint8_t g, uint8_t b, uint8_t rate_hz) } } +// handle display override from scripting +void AP_Notify::handle_scr_disp(uint8_t r, const char *str) +{ + for (uint8_t i = 0; i < _num_devices; i++) { + if (_devices[i] != nullptr) { + _devices[i]->scr_disp_overide(r, str); + } + } +} + // handle a PLAY_TUNE message void AP_Notify::handle_play_tune(const mavlink_message_t &msg) { diff --git a/libraries/AP_Notify/AP_Notify.h b/libraries/AP_Notify/AP_Notify.h index 88e6133d1a11d..b909520cc14fe 100644 --- a/libraries/AP_Notify/AP_Notify.h +++ b/libraries/AP_Notify/AP_Notify.h @@ -147,6 +147,9 @@ class AP_Notify // handle a PLAY_TUNE message static void handle_play_tune(const mavlink_message_t &msg); + // handle display override from scripting + static void handle_scr_disp(uint8_t r, const char *str); + // play a tune string static void play_tune(const char *tune); diff --git a/libraries/AP_Notify/Display.cpp b/libraries/AP_Notify/Display.cpp index c253aab0bbbd0..6b38331f17b2c 100644 --- a/libraries/AP_Notify/Display.cpp +++ b/libraries/AP_Notify/Display.cpp @@ -377,6 +377,17 @@ void Display::update() } timer = 0; + // If we have received an override from scripting recently allow update + if (AP_HAL::millis() - _last_scr_override <= _script_timeout_ms) { + if (_screenpage != 3) { + _driver->clear_screen(); + _screenpage = 3; + } + update_scr_screen(); + _driver->hw_update(); + return; + } + if (AP_Notify::flags.armed) { if (_screenpage != 1) { _driver->clear_screen(); @@ -582,3 +593,18 @@ void Display::update_text(uint8_t r) draw_text(COLUMN(0), ROW(0), msg); } + +// Allow scripting to override text lines on the display +void Display::scr_disp_overide(uint8_t r, const char *str) { + // Prevent chars being left from previous message by clearing with spaces first + memset(_scr_msg[r], ' ', DISPLAY_MESSAGE_SIZE-1); // leave null termination + strncpy(_scr_msg[r], str, strlen(str)); + + _last_scr_override = AP_HAL::millis(); +} + +void Display::update_scr_screen() { + for (uint8_t i = 0; i < 6; i++) { + draw_text(COLUMN(0), ROW(i), _scr_msg[i]); + } +} diff --git a/libraries/AP_Notify/Display.h b/libraries/AP_Notify/Display.h index 25369e1c7d25f..950a1dfe5d4b9 100644 --- a/libraries/AP_Notify/Display.h +++ b/libraries/AP_Notify/Display.h @@ -16,6 +16,9 @@ class Display: public NotifyDevice { bool init(void) override; void update() override; + // Allows scripting to override the display message + void scr_disp_overide(uint8_t r, const char *str) override; + private: void draw_char(uint16_t x, uint16_t y, const char c); void draw_text(uint16_t x, uint16_t y, const char *c); @@ -36,6 +39,14 @@ class Display: public NotifyDevice { uint8_t _movedelay; // ticker delay before shifting after new message displayed uint8_t _screenpage; + void update_scr_screen(void); + + // stop scripting override if we have not recieved anything for 5 sec + static const uint16_t _script_timeout_ms = 5000; + + uint32_t _last_scr_override; + char _scr_msg[6][DISPLAY_MESSAGE_SIZE] = {}; + // stop showing text in display after this many millis: const uint16_t _send_text_valid_millis = 20000; }; diff --git a/libraries/AP_Notify/NotifyDevice.h b/libraries/AP_Notify/NotifyDevice.h index b2e91e849c2df..f7db04190fca6 100644 --- a/libraries/AP_Notify/NotifyDevice.h +++ b/libraries/AP_Notify/NotifyDevice.h @@ -27,6 +27,9 @@ class NotifyDevice { // give RGB and flash rate, used with scripting virtual void rgb_control(uint8_t r, uint8_t g, uint8_t b, uint8_t rate_hz) {} + // Allows scripting to override the display message + virtual void scr_disp_overide(uint8_t r, const char *str) {} + // this pointer is used to read the parameters relative to devices const AP_Notify *pNotify; }; diff --git a/libraries/AP_Scripting/examples/use_notify_display.lua b/libraries/AP_Scripting/examples/use_notify_display.lua new file mode 100644 index 0000000000000..1f31f9b06c76d --- /dev/null +++ b/libraries/AP_Scripting/examples/use_notify_display.lua @@ -0,0 +1,37 @@ +-- This is a simple script example that shows how to use the notify display override. +-- In this example battery voltage and percent remaining is retrieved and displayed +-- on screen to act as a handy onboard display for checking the batteries. + +local function update() + + local voltage = 0 + local remaining = 0 + local healthy = battery:healthy(0) + + -- Update display + -- First argument is line number. There are up to 6 lines available. 0 based numbering is used + -- Second argument is the string to be displayed. Up to 19 characters can be displayed on each line + notify:handle_scr_disp(0," --- ArduPilot --- ") + + if (healthy) then + -- Get voltage and display it on line 3 + voltage = battery:voltage(0) + notify:handle_scr_disp(2, string.format(" Voltage: %.2f V", voltage)) + + -- Get pack remaining and display it on line 5 + remaining = battery:capacity_remaining_pct(0) + notify:handle_scr_disp(4, string.format("Remaining: %.2f %%", remaining)) + + else + -- voltage monitor is unhealthy + notify:handle_scr_disp(3, " Battery Monitor ") + notify:handle_scr_disp(4, " Unhealthy ") + end + + -- Display is updated at 2 Hz so no point in calling any faster than that + return update, 500 + +end + +-- Wait for 5 sec before starting script +return update, 5000 diff --git a/libraries/AP_Scripting/generator/description/bindings.desc b/libraries/AP_Scripting/generator/description/bindings.desc index 39308fbb185b1..89d815a559079 100644 --- a/libraries/AP_Scripting/generator/description/bindings.desc +++ b/libraries/AP_Scripting/generator/description/bindings.desc @@ -127,6 +127,7 @@ include AP_Notify/AP_Notify.h singleton AP_Notify alias notify singleton AP_Notify method play_tune void string singleton AP_Notify method handle_rgb void uint8_t 0 UINT8_MAX uint8_t 0 UINT8_MAX uint8_t 0 UINT8_MAX uint8_t 0 UINT8_MAX +singleton AP_Notify method handle_scr_disp void uint8_t 0 5 string include AP_Proximity/AP_Proximity.h