Adding Real-time Values
Section titled “Adding Real-time Values”Relevant source files
- main/display/cnc/esp3d_system_translations_defs.inc
- main/display/cnc/screens/firmware_status_screen.cpp
- main/display/cnc/screens/main_screen.cpp
- main/display/cnc/screens/settings_list_screen.cpp
- main/display/esp3d_translations_defs.inc
- main/display/screens/polling_screen.cpp
- main/display/screens/screen_timeout_screen.cpp
- main/display/screens/update_screen.cpp
- main/target/cnc/esp3d_system_values_defs.inc
- main/target/cnc/fluidnc/esp3d_gcode_handler_service.h
This page explains how to extend the ESP3DValues pub/sub system to add new real-time data streams that propagate from the G-code handler or network modules to UI screens. This is essential for displaying new firmware information, machine states, or sensor data in the pendant interface.
System Architecture
Section titled “System Architecture”The ESP3DValues system provides a centralized pub/sub architecture for distributing real-time data from various services to multiple UI components without tight coupling. The singleton instance esp3dXValues manages all global states. Data typically enters the system via set_value() and leaves via callback notifications to subscribers.
Data Flow Diagram
Section titled “Data Flow Diagram”Titled: “Real-time Value Propagation Flow”
Sources:
set_valueusage in update: main/display/screens/update_screen.cpp#58-71subscribeusage in main: main/display/cnc/screens/main_screen.cpp#74-85subscribeusage in status screen: main/display/cnc/screens/firmware_status_screen.cpp#76-84
Value Index Definition
Section titled “Value Index Definition”All real-time values are identified by the ESP3DValuesIndex enum. This system uses an X-Macro pattern to maintain consistency between the enumeration and the static definitions stored in RAM/Flash.
Key Files for Definitions
Section titled “Key Files for Definitions”esp3d_system_values_defs.inc: Contains system-wide values including position strings (position_wx), overrides, and job management data main/target/cnc/esp3d_system_values_defs.inc#1-110esp3d_target_values_defs.inc: Contains firmware-specific values defined per target (e.g., FluidNC vs grblHAL).esp3d_values.h: Declares theESP3DValuesIndexenumeration dynamically using the include files above.
Common Value Categories
Section titled “Common Value Categories”| Index | Purpose | Subscriber Example |
|---|---|---|
server_status | Connection state: ‘C’ (Connected), ‘T’ (Connecting), ’?’ (Disconnected) | onConnectionStatusUpdate in main_screen.cppmain/display/cnc/screens/main_screen.cpp#74-85 |
firmware_status | Machine state (Idle, Run, Hold, Alarm) | firmware_status_screen.cppmain/display/cnc/screens/firmware_status_screen.cpp#76-86 |
message_history | Buffer for MSG:ERR or MSG:INFO messages | firmware_status_screen.cppmain/display/cnc/screens/firmware_status_screen.cpp#77 |
update_progress | Flash progress percentage (0-100) | update_screen.cppmain/display/screens/update_screen.cpp#138-149 |
Sources:
esp3d_system_values_defs.inccontent: main/target/cnc/esp3d_system_values_defs.inc#18-105- Connection status handling: main/display/cnc/screens/main_screen.cpp#74-85
- Update progress handling: main/display/screens/update_screen.cpp#138-149
Adding a New Value Index
Section titled “Adding a New Value Index”To add a new real-time value, follow these steps:
1. Update the Definition Include
Section titled “1. Update the Definition Include”Add the new value to esp3d_system_values_defs.inc using the ESP3D_VAL_DEF macro. You must specify the buffer size (in bytes) required to hold the string representation of the value.
// Format: ESP3D_VAL_DEF(name, type, size, initial_value)ESP3D_VAL_DEF(probe_result, string_t, 32, "0.000")Reference for current definitions:main/target/cnc/esp3d_system_values_defs.inc#102-106
2. Publishing the Value
Section titled “2. Publishing the Value”Use the set_value method on the esp3dXValues global instance.
Example from update_screen.cpp:
The update service calls back to the UI, which propagates the progress to the global values system:
main/display/screens/update_screen.cpp#62-63
esp3dXValues.set_value(ESP3DValuesIndex::update_progress, std::to_string(percent).c_str());Subscribing to Values in Screens
Section titled “Subscribing to Values in Screens”Screens and UI components subscribe to value updates to react in real-time.
Code Entity Mapping: Subscription Lifecycle
Section titled “Code Entity Mapping: Subscription Lifecycle”Titled: “Subscription Lifecycle in GenericScreen”
Sources:
- Status screen subscription: main/display/cnc/screens/firmware_status_screen.cpp#76-86
- Main screen subscription: main/display/cnc/screens/main_screen.cpp#74-85
Implementation Pattern
Section titled “Implementation Pattern”- Define a Callback: The callback signature must be
bool(ESP3DValuesIndex, const char *, ESP3DValuesCbAction). - Filter Actions: Always check if
action == ESP3DValuesCbAction::Updatemain/display/screens/update_screen.cpp#131-133 - Update LVGL Objects: Ensure you verify object validity using
lv_obj_is_valid()before updating UI elements main/display/screens/update_screen.cpp#140-141 - Unsubscribe: In
prepareForDestruction(), remove the subscription to prevent the system from calling a pointer to a destroyed screen.
Best Practices
Section titled “Best Practices”| Requirement | Implementation Detail |
|---|---|
| Unsubscribe | Must be called in prepareForDestruction for both system and target values main/display/cnc/screens/main_screen.cpp#56-59 |
| Initial Sync | After subscribing, the callback is not automatically fired. You may need to call get_value(index) to set the initial UI state. |
| Heap Safety | Avoid complex logic inside the callback; just update labels, styles, or icons. |
| Return Value | Return true to maintain the subscription. Returning false will cause esp3dXValues to automatically remove the subscriber. |
Sources:
- Destruction guard usage: main/display/screens/polling_screen.cpp#103-106
- Callback return logic: main/display/screens/update_screen.cpp#162
- UI Refresh pattern: main/display/cnc/screens/firmware_status_screen.cpp#76-86