Development Guide
Section titled “Development Guide”Relevant source files
- CMakeLists.txt
- boards/ESP32_C3_BARE/build_scripts/common.py
- boards/ESP32_S3_WROOM_CAM/build_scripts/common.py
- boards/fysetc_wifi_pro/build_scripts/common.py
- boards/pibot_pendant_v1_0/board_config.cmake
- boards/pibot_pendant_v1_0/build_scripts/common.py
- cmake/features.cmake
- cmake/sanity_check.cmake
- docs/guides/ui_resources_guide.md
- docs/ui_resources/development.md
- docs/ui_resources/roadmap.md
- docs/user documentation/ui_resources_customization.md
- main/CMakeLists.txt
- tools/build_scripts/build_mgr.py
- tools/build_scripts/package_user_resources_kit.py
- tools/flash_scripts/flash_mgr.py
- tools/fonts/font_c_to_fnt.py
- tools/fonts/requirements.txt
- tools/fonts/ttf_to_fnt.py
- tools/images/image_c_to_bin.py
This document provides practical guidance for developers extending or modifying the PiBot CNC Pendant firmware. It covers common development tasks including adding settings, creating screens, extending G-code support, and working with the translation system.
Related Documentation:
- For system architecture overview, see System Architecture
- For settings management details, see Settings Management
- For UI system architecture, see User Interface System
- For G-code handler details, see G-code Handler Service
Core Architecture Patterns
Section titled “Core Architecture Patterns”Before diving into specific development tasks, understanding these foundational patterns is essential for maintaining code quality and consistency.
X-Macro Pattern for Settings
Section titled “X-Macro Pattern for Settings”The firmware uses X-macros to define settings in a single location, generating both enum values and metadata tables at compile time. This ensures consistency between setting identifiers and their storage keys.
Title: Settings Generation Flow
Sources: main/core/includes/esp3d_settings.h#97-108, main/core/esp3d_settings.cpp#108-119, main/core/esp3d_settings.cpp#125-144
UI Resource Management
Section titled “UI Resource Management”Icons and fonts are not compiled into the firmware but reside in a dedicated ui_resources flash partition. This allows for customization without full firmware reflashing.
Title: UI Resource Build Flow
Sources: docs/guides/ui_resources_guide.md#46-56, docs/ui_resources/development.md#13-28, tools/build_scripts/generate_resources.py#156-159
Component Lifecycle Pattern
Section titled “Component Lifecycle Pattern”All UI components follow a strict two-phase destruction pattern to prevent race conditions from late-arriving hardware events or callbacks.
Title: UI Component Lifecycle
Sources: main/display/cnc/fluidnc/screens/files_screen.cpp#104-107, main/display/cnc/fluidnc/screens/files_screen.cpp#139-145
Build System and Feature Flags
Section titled “Build System and Feature Flags”The firmware uses a CMake-based build system integrated with the ESP-IDF. Feature selection is handled via OPTION() flags in the root CMakeLists.txt, which are then translated into C++ preprocessor defines in cmake/features.cmake.
- Firmware Targets: Only one firmware target (e.g.,
TARGET_FW_FLUIDNC) can be active at a time cmake/sanity_check.cmake#43. - Hardware Features: Flags like
HARDWARE_ENCODERorHARDWARE_BUTTONScontrol the inclusion of specific input drivers boards/pibot_pendant_v1_0/board_config.cmake#92-95. - Resource Constraints: WiFi and Bluetooth are mutually exclusive on ESP32 boards without PSRAM to avoid memory contention cmake/sanity_check.cmake#71-77.
- Logging Backends: The
ESP3D_LOG_BACKENDflag (0=Serial, 1=SD, 2=UART2, 3=Telnet, 4=WebSocket) determines which output module is linked main/CMakeLists.txt#25-33.
For details, see Build System and Feature Flags.
Sources: CMakeLists.txt#6-55, cmake/features.cmake#6-64, cmake/sanity_check.cmake#68-77, main/CMakeLists.txt#25-33
Adding New Screens
Section titled “Adding New Screens”Screens are the primary UI containers. Adding a new screen involves extending the GenericScreen class and registering the new type in the UIManager.
- Enum Definition: Add a new value to
ESP3DScreenTypemain/display/cnc/fluidnc/screens/esp3d_screen_type.h#26-61. - Implementation: Create a new class/namespace inheriting from
GenericScreenpatterns. - Registration: Update the centralized
createScreen()function to instantiate your class main/display/cnc/fluidnc/screens/esp3d_screen_type.cpp#122-232.
For details, see Adding New Screens.
Sources: main/display/cnc/fluidnc/screens/esp3d_screen_type.h#26-61, main/display/cnc/fluidnc/screens/esp3d_screen_type.cpp#122-232
Adding New Settings
Section titled “Adding New Settings”Settings are persistent configuration values stored in NVS. The system uses an X-macro pattern defined in .inc files to manage metadata, validation, and defaults.
- Definition: Modify
esp3d_settings_defs.incoresp3d_target_settings_defs.inc. - Validation: Implement custom logic in
isValidIntegerSetting()or similar functions inesp3d_settings.cpp. - Access: Use
esp3dTftsettings.readUint32()oresp3dTftsettings.readString().
For details, see Adding New Settings.
Sources: main/core/includes/esp3d_settings.h#97-108, main/core/esp3d_settings.cpp#699-737
Adding Real-time Values
Section titled “Adding Real-time Values”The esp3dTftValues service manages real-time system state (e.g., positions, status).
- Index: Add a new index to
ESP3DValuesIndex. - Propagation: Update the G-code status parser to extract and set the value.
- Subscription: Screens can subscribe to updates using
add_callback()main/display/cnc/fluidnc/screens/files_screen.cpp#149-150.
For details, see Adding Real-time Values.
Sources: main/display/cnc/fluidnc/screens/files_screen.cpp#149-150, main/display/cnc/fluidnc/screens/files_screen.cpp#170-171
Extending G-code Support
Section titled “Extending G-code Support”G-code handling is centralized in the ESP3DGcodeHandlerService.
- Commands: Extend
sendGcode()to support new custom commands. - Parsing: Modify parsing logic to handle new fields in the controller’s status report (e.g.,
MPos,WCO, or custom firmware fields).
For details, see Extending G-code Support.
Sources: main/display/cnc/fluidnc/screens/files_screen.cpp#159-160
Working with Translations
Section titled “Working with Translations”The translation system uses X-macros to compile translations directly into the firmware, avoiding external file dependencies for core UI strings.
- Labels: Add new
ESP3D_TR_DEFentries inesp3d_translations_defs.incmain/display/esp3d_translations_list.h#36-47. - English Fallback: Update the English table in
esp3d_translations_init.cppmain/display/esp3d_translations_init.cpp#31-37. - Usage: Retrieve strings using
esp3dTranslationService.translate(ESP3DLabel::my_label).
For details, see Working with Translations.
Sources: main/display/esp3d_translations_init.cpp#31-37, main/display/esp3d_translations_list.h#36-47, tools/language_packs/template.lng#11-122
Creating Custom UI Components
Section titled “Creating Custom UI Components”Reusable components should inherit standard lifecycle patterns to ensure stability.
- Lifecycle: Implement
prepareForDestruction()to clean up LVGL objects and timers main/display/cnc/fluidnc/screens/files_screen.cpp#139-145. - Registration: Use
ComponentTypeto identify the component main/display/cnc/fluidnc/screens/esp3d_screen_type.h#64-76.
For details, see Creating Custom UI Components.
Sources: main/display/cnc/fluidnc/screens/files_screen.cpp#139-145, main/display/cnc/fluidnc/screens/esp3d_screen_type.h#64-76
Debugging and Testing
Section titled “Debugging and Testing”The firmware includes several tools for development:
- Logging: Use
esp3d_log()for debug-only messages main/display/cnc/fluidnc/screens/files_screen.cpp#187. - Feature Flags: Toggle features in
CMakeLists.txtto isolate components CMakeLists.txt#62-79. - Safety Checks: The
cmake/sanity_check.cmakescript prevents invalid hardware/software combinations at build time cmake/sanity_check.cmake#71-77.
For details, see Debugging and Testing.
Sources: main/display/cnc/fluidnc/screens/files_screen.cpp#187, CMakeLists.txt#62-79, cmake/sanity_check.cmake#71-77