plunger | extruder

This commit is contained in:
lovebird 2026-03-10 19:56:29 +01:00
parent 809d3d2219
commit a105c5ee85
23 changed files with 1463 additions and 1400 deletions

View File

@ -1,15 +1,16 @@
#ifndef PLUNGER_H
#define PLUNGER_H
#ifndef EXTRUDER_H
#define EXTRUDER_H
#include "config.h"
#ifdef ENABLE_EXTRUDER
#include "config.h"
#include <Component.h>
#include <ArduinoLog.h>
#include "./SAKO_VFD.h"
#include "./3PosAnalog.h"
#include "./POT.h"
#include "./SAKO_VFD.h"
#include "enums.h"
#include <ArduinoLog.h>
#include <Component.h>
#include <modbus/ModbusTCP.h>
// Component Constants
@ -17,110 +18,123 @@
#define EXTRUDER_COMPONENT_NAME "Extruder"
// Speed Presets (in 0.01 Hz units for SAKO_VFD)
#define EXTRUDER_SPEED_SLOW_HZ 10 // 10.00 Hz
#define EXTRUDER_SPEED_SLOW_HZ 10 // 10.00 Hz
#define EXTRUDER_SPEED_MEDIUM_HZ 25 // 25.00 Hz
#define EXTRUDER_SPEED_FAST_HZ 50 // 50.00 Hz (currently unused, but defined)
#define EXTRUDER_SPEED_FAST_HZ 50 // 50.00 Hz (currently unused, but defined)
// Speed POT Configuration for Extruding (multiplier for MEDIUM speed)
// POT value 0-100. Example: 0 maps to 0.5x, 50 maps to 1.0x, 100 maps to 1.5x MEDIUM speed.
// POT value 0-100. Example: 0 maps to 0.5x, 50 maps to 1.0x, 100 maps to 1.5x
// MEDIUM speed.
#define EXTRUDER_SPEED_POT_MIN_MULTIPLIER 0.5f
#define EXTRUDER_SPEED_POT_MAX_MULTIPLIER 1.5f
// Overload POT Configuration and Jamming (using VFD Torque %)
// POT value 0-100. Maps to a torque threshold in percent (0-100).
// SAKO_VFD component now provides getTorque() returning 0-100.
#define EXTRUDER_OVERLOAD_POT_MIN_TORQUE_PERCENT 50 // Example: 50% Torque
#define EXTRUDER_OVERLOAD_POT_MAX_TORQUE_PERCENT 95 // Example: 95% Torque
#define PLUNGER_JAMMED_DURATION_MS 2000 // Time torque must be above threshold to be JAMMED
#define EXTRUDER_VFD_READ_INTERVAL_MS 200 // How often to check VFD torque for jamming
#define EXTRUDER_AUTO_MODE_HOLD_DURATION_MS 2000 // Time joystick must be held for auto mode
#define EXTRUDER_OVERLOAD_POT_MIN_TORQUE_PERCENT 50 // Example: 50% Torque
#define EXTRUDER_OVERLOAD_POT_MAX_TORQUE_PERCENT 95 // Example: 95% Torque
#define PLUNGER_JAMMED_DURATION_MS \
2000 // Time torque must be above threshold to be JAMMED
#define EXTRUDER_VFD_READ_INTERVAL_MS \
200 // How often to check VFD torque for jamming
#define EXTRUDER_AUTO_MODE_HOLD_DURATION_MS \
2000 // Time joystick must be held for auto mode
// Modbus Configuration
#define EXTRUDER_MB_BASE_ADDRESS EXTRUDER_COMPONENT_ID // Using component ID as base
#define EXTRUDER_MB_BASE_ADDRESS \
EXTRUDER_COMPONENT_ID // Using component ID as base
#define EXTRUDER_MB_STATE_OFFSET 0
#define EXTRUDER_MB_COMMAND_OFFSET 1
#define EXTRUDER_MB_BLOCK_COUNT 2
#define EXTRUDER_MAX_RUN_TIME_MEDIUM_SPEED_MS 15000 // Max runtime at medium speed
#define EXTRUDER_MAX_RUN_TIME_MEDIUM_SPEED_MS \
15000 // Max runtime at medium speed
enum class ExtruderModbusCommand : short {
NO_COMMAND = 0,
CMD_EXTRUDE = 2,
CMD_STOP = 3,
CMD_INFO = 4
NO_COMMAND = 0,
CMD_EXTRUDE = 2,
CMD_STOP = 3,
CMD_INFO = 4
};
// Extruder States
enum class ExtruderState : uint8_t {
IDLE,
EXTRUDING_MANUAL, // Joystick held UP, VFD forwarding, monitoring for auto-mode hold time
EXTRUDING_AUTO, // Auto-extruding after joystick hold, VFD forwarding
STOPPING, // Transition state to stop VFD
JAMMED,
RESETTING_JAM // State to handle reset after jam
IDLE,
EXTRUDING_MANUAL, // Joystick held UP, VFD forwarding, monitoring for
// auto-mode hold time
EXTRUDING_AUTO, // Auto-extruding after joystick hold, VFD forwarding
STOPPING, // Transition state to stop VFD
JAMMED,
RESETTING_JAM // State to handle reset after jam
};
class Extruder : public Component {
public:
Extruder(Component* owner, SAKO_VFD* vfd, Pos3Analog* joystick = nullptr, POT* speedPot = nullptr, POT* overloadPot = nullptr);
~Extruder() override = default;
Extruder(Component *owner, SAKO_VFD *vfd, Pos3Analog *joystick = nullptr,
POT *speedPot = nullptr, POT *overloadPot = nullptr);
~Extruder() override = default;
short setup() override;
short loop() override;
short info() override;
short debug() override;
short serial_register(Bridge* b) override;
short init();
short reset();
short setup() override;
short loop() override;
short info() override;
short debug() override;
short serial_register(Bridge *b) override;
short init();
short reset();
// Modbus TCP Interface
ModbusBlockView* mb_tcp_blocks() const override;
void mb_tcp_register(ModbusTCP* mgr) override;
short mb_tcp_read(MB_Registers* reg) override;
short mb_tcp_write(MB_Registers* reg, short networkValue) override;
// Modbus TCP Interface
ModbusBlockView *mb_tcp_blocks() const override;
void mb_tcp_register(ModbusTCP *mgr) override;
short mb_tcp_read(MB_Registers *reg) override;
short mb_tcp_write(MB_Registers *reg, short networkValue) override;
// Public commands for serial/external control
short cmd_extrude();
short cmd_stop();
// Public commands for serial/external control
short cmd_extrude();
short cmd_stop();
private:
SAKO_VFD* _vfd;
Pos3Analog* _joystick;
POT* _speedPot;
POT* _overloadPot;
SAKO_VFD *_vfd;
Pos3Analog *_joystick;
POT *_speedPot;
POT *_overloadPot;
ExtruderState _currentState;
Pos3Analog::E_POS3_DIRECTION _lastJoystickDirection;
ExtruderState _currentState;
Pos3Analog::E_POS3_DIRECTION _lastJoystickDirection;
uint16_t _currentSpeedPotValue; // 0-100, defaults to 100 if pot is null
uint16_t _currentOverloadPotValue; // 0-100, defaults to 100 if pot is null
float _calculatedExtrudingSpeedHz; // Calculated speed for extruding (0.01Hz units)
uint8_t _calculatedOverloadThresholdPercent; // Calculated torque threshold (0-100%)
uint16_t _currentSpeedPotValue; // 0-100, defaults to 100 if pot is null
uint16_t _currentOverloadPotValue; // 0-100, defaults to 100 if pot is null
float _calculatedExtrudingSpeedHz; // Calculated speed for extruding (0.01Hz
// units)
uint8_t _calculatedOverloadThresholdPercent; // Calculated torque threshold
// (0-100%)
unsigned long _lastStateChangeTimeMs;
unsigned long _jammedStartTimeMs;
unsigned long _lastVfdReadTimeMs;
unsigned long _joystickHoldStartTimeMs; // Timer for joystick hold duration
short _modbusCommandRegisterValue; // Holds the current value of the Modbus command register
unsigned long _operationStartTimeMs; // Start time of current extrude operation
unsigned long _currentMaxOperationTimeMs; // Calculated max duration for current operation
unsigned long _lastStateChangeTimeMs;
unsigned long _jammedStartTimeMs;
unsigned long _lastVfdReadTimeMs;
unsigned long _joystickHoldStartTimeMs; // Timer for joystick hold duration
short _modbusCommandRegisterValue; // Holds the current value of the Modbus
// command register
unsigned long
_operationStartTimeMs; // Start time of current extrude operation
unsigned long _currentMaxOperationTimeMs; // Calculated max duration for
// current operation
// Helper methods
void _handleIdleState();
void _handleExtrudingManualState();
void _handleExtrudingAutoState();
void _handleStoppingState();
void _handleJammedState();
void _handleResettingJamState();
// Helper methods
void _handleIdleState();
void _handleExtrudingManualState();
void _handleExtrudingAutoState();
void _handleStoppingState();
void _handleJammedState();
void _handleResettingJamState();
void _updatePotValues();
void _checkVfdForJam();
void _transitionToState(ExtruderState newState);
void _updatePotValues();
void _checkVfdForJam();
void _transitionToState(ExtruderState newState);
// VFD interaction wrappers
void _vfdStartForward(uint16_t frequencyCentiHz);
void _vfdStartReverse(uint16_t frequencyCentiHz);
void _vfdStop();
void _vfdResetJam();
// VFD interaction wrappers
void _vfdStartForward(uint16_t frequencyCentiHz);
void _vfdStartReverse(uint16_t frequencyCentiHz);
void _vfdStop();
void _vfdResetJam();
};
#endif
#endif // EXTRUDER_H
#endif // EXTRUDER_H

File diff suppressed because it is too large Load Diff

View File

@ -701,7 +701,7 @@ void RESTServer::getSystemInfoHandler(AsyncWebServerRequest *request)
doc["freeHeapKb"] = ESP.getFreeHeap() / 1024;
doc["maxFreeBlockKb"] = heap_caps_get_largest_free_block(MALLOC_CAP_DEFAULT) / 1024;
doc["fragmentationPercent"] = static_cast<App *>(owner)->getHeapFragmentation();
doc["cpuTicks"] = (uint32_t)esp_cpu_get_ccount();
doc["cpuTicks"] = (uint32_t)esp_cpu_get_cycle_count();
doc["loopDurationMs"] = owner->getLoopDurationUs();
// --- Calculate Average CPU Load ---
float cpuLoadPercent = -1.0; // Default value if stats are unavailable
@ -1618,7 +1618,7 @@ void RESTServer::handleWebSocketMessage(AsyncWebSocketClient *client, void *arg,
responseDoc["freeHeapKb"] = ESP.getFreeHeap() / 1024.0;
responseDoc["maxFreeBlockKb"] = heap_caps_get_largest_free_block(MALLOC_CAP_DEFAULT) / 1024.0;
responseDoc["fragmentationPercent"] = static_cast<App *>(owner)->getHeapFragmentation();
responseDoc["cpuTicks"] = (uint32_t)esp_cpu_get_ccount();
responseDoc["cpuTicks"] = (uint32_t)esp_cpu_get_cycle_count();
responseDoc["loopDurationMs"] = owner->getLoopDurationUs();
// --- Calculate Average CPU Load ---
float cpuLoadPercent = -1.0; // Default value if stats are unavailable

View File

@ -2,24 +2,32 @@
#define ESP32_COMPAT_H
#include <Arduino.h>
#if __has_include(<sdkconfig.h>)
#include <sdkconfig.h>
#endif
// Include esp_cpu.h for all ESP32 variants
#if defined(ESP32) || defined(ESP32S2) || defined(ESP32S3) || defined(ESP32C3) || defined(ESP32P4)
#if defined(ESP32) || defined(ESP32S2) || defined(ESP32S3) || defined(ESP32C3) || defined(ESP32P4) || defined(CONFIG_IDF_TARGET_ESP32P4)
#include <esp_cpu.h>
#endif
// ESP-IDF v5.x and later renamed esp_cpu_get_ccount to esp_cpu_get_cycle_count.
// For compatibility, we provide esp_cpu_get_cycle_count if it doesn't exist
// Include esp_idf_version.h for version checking
#if __has_include(<esp_idf_version.h>)
#include <esp_idf_version.h>
#endif
// ESP-IDF v5.x renamed esp_cpu_get_ccount to esp_cpu_get_cycle_count.
// We use esp_cpu_get_cycle_count in the code.
// For legacy versions (IDF < 5.0), we map it back to esp_cpu_get_ccount.
#if defined(ESP_IDF_VERSION) && ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0)
#ifndef esp_cpu_get_cycle_count
#define esp_cpu_get_cycle_count esp_cpu_get_ccount
#endif
#endif
// ESP32-P4 compatibility layer
#ifdef CONFIG_IDF_TARGET_ESP32P4
// ESP32-P4 specific compatibility
#ifndef esp_cpu_get_cycle_count
#define esp_cpu_get_cycle_count esp_cpu_get_ccount
#endif
// P4 Stub if needed (currently using native esp_cpu_get_cycle_count)
#endif
// ArduinoLog compatibility

View File

@ -7,7 +7,10 @@
"build": "pio run -e waveshare",
"build:p4": "pio run -e esp32-p4-evboard",
"upload:p4": "pio run -e esp32-p4-evboard -t upload",
"monitor:p4": "pio device monitor --filter esp32_exception_decoder -e esp32-p4-evboard",
"monitor:p4": "pio device monitor --filter esp32_exception_decoder -e esp32-p4-evboard -b 115200",
"update:p4": "npm run build:p4 && npm run upload:p4",
"uploadfs:p4": "pio run -e esp32-p4-evboard -t uploadfs",
"build:p4:fs": "pio run -e esp32-p4-evboard -t uploadfs",
"build:dev": "cross-env DEV_IP_OVERRIDE_STA_IP=192.168.1.251 pio run -e waveshare",
"update:dev": "npm run build:dev && npm run upload",
"idf:build": "bash scripts/idf-build.sh",
@ -52,6 +55,7 @@
"web:build-dist": "cd ../web/packages/modbus-ui && npm run build",
"web:uploadfs": "pio run -t uploadfs -e waveshare",
"web:uploadfs-release": "pio run -t uploadfs -e waveshare-release",
"web:uploadfs:p4": "pio run -t uploadfs -e esp32-p4-evboard",
"web:clean": "rm -rf data/*",
"web:update": "npm run web:clean && npm run web:build-dist && npm run web:sync && npm run web:uploadfs",
"web:update-release": "npm run web:clean && npm run web:build-dist && npm run web:sync && npm run web:uploadfs-release",

6
platform.ini.md Normal file
View File

@ -0,0 +1,6 @@
-DCONFIG_ASYNC_TCP_STACK_SIZE=1024
-DCONFIG_ASYNC_TCP_QUEUE_SIZE=4
-DCONFIG_ASYNC_TCP_PRIORITY=2
-DCONFIG_ASYNC_TCP_MAX_ACK_TIME=500
-DCONFIG_ASYNC_TCP_RUNNING_CORE=1
-DASYNCWEBSERVER_USE_CHUNK_INFLIGHT=0

117
platformio-p4.ini Normal file
View File

@ -0,0 +1,117 @@
;-D DEV_IP_OVERRIDE_STA_IP=${sysenv.DEV_IP_OVERRIDE_STA_IP}
[common]
;extra_scripts = scripts/LittleFSBuilder.py
extra_scripts = scripts/strip_elf.py
lib_ignore = WebServer
upload_protocol = esptool
debug_init_break = tbreak setup
monitor_filters = esp32_exception_decoder
board_upload.speed = 115200
board_build.mcu = esp32s3
board_build.variant = esp32s3
board_build.filesystem = littlefs
[env:waveshare_base]
extends = common
debug_tool = esp-builtin
platform = espressif32
board = esp32-s3-devkitc-1
framework = arduino
monitor_filters = esp32_exception_decoder
board_build.flash_mode = dio
board_build.prsam_type = opi
build_flags =
-std=gnu++17
-I src
-I lib/polymech-base/src
board_build.extra_flags =
-DBOARD_HAS_PSRAM
-DARDUINO_ESP32S3_DEV
-DARDUINO_USB_MODE=1
-DWS_MAX_QUEUED_MESSAGES=64
-DWS_SEND_QUEUE_SIZE=64
-DWS_MIN_SEND_INTERVAL_MS=10
-DPROJECT_DIR="\"${PROJECT_DIR}\""
lib_deps =
https://github.com/eModbus/eModbus.git
https://github.com/janelia-arduino/Vector.git
https://github.com/thijse/Arduino-Log.git
https://github.com/bblanchon/ArduinoJson.git
https://github.com/ESP32Async/ESPAsyncWebServer.git
[env:waveshare]
monitor_filters = esp32_exception_decoder
extends = env:waveshare_base
lib_deps =
${env:waveshare_base.lib_deps}
board_build.extra_flags =
${env:waveshare_base.board_build.extra_flags}
-DARDUINO_USB_CDC_ON_BOOT=1
-DLOG_LEVEL=LOG_LEVEL_INFO
-DENABLE_LOGGING
-DWS_MAX_QUEUED_MESSAGES=16
-DWS_SEND_QUEUE_SIZE=16
-DWS_MIN_SEND_INTERVAL_MS=80
[env:waveshare-release]
monitor_filters = esp32_exception_decoder
build_type = release
extends = env:waveshare_base
board_build.extra_flags =
${env:waveshare_base.board_build.extra_flags}
-DARDUINO_USB_CDC_ON_BOOT=0
-DLOG_LEVEL=0
-DDISABLE_LOGGING
-DPIO_DISABLE_LOGGER
-DCONFIG_LOG_DEFAULT_LEVEL=0
-DCONFIG_LOG_MAXIMUM_LEVEL=0
-DLOG_LOCAL_LEVEL=0
-Wl,--gc-sections
lib_ignore = WebServer
lib_deps =
${env:waveshare_base.lib_deps}
[env:waveshare-release-debug]
monitor_filters = esp32_exception_decoder
build_type = release
extends = env:waveshare_base
board_build.extra_flags =
${env:waveshare_base.board_build.extra_flags}
-DARDUINO_USB_CDC_ON_BOOT=0
-DLOG_LEVEL=LOG_LEVEL_INFO
-DENABLE_LOGGING
-Wl,--gc-sections
lib_ignore = WebServer
lib_deps =
${env:waveshare_base.lib_deps}
[env:esp32-p4-evboard]
extra_scripts = scripts/LittleFSBuilder.py
lib_ignore = WebServer
upload_protocol = esptool
debug_init_break = tbreak setup
monitor_filters = esp32_exception_decoder
board_upload.speed = 115200
board_build.filesystem = littlefs
platform = https://github.com/pioarduino/platform-espressif32/releases/download/55.03.30-2/platform-espressif32.zip
board = esp32-p4-evboard
framework = arduino
monitor_speed = 115200
lib_deps =
${env:waveshare_base.lib_deps}
build_flags =
-DARDUINO_USB_MODE=1
-DARDUINO_USB_CDC_ON_BOOT=0
-DLOG_LEVEL=LOG_LEVEL_INFO
-DENABLE_LOGGING
-DWS_MAX_QUEUED_MESSAGES=16
-DWS_SEND_QUEUE_SIZE=16
-DWS_MIN_SEND_INTERVAL_MS=80
-DENABLE_P4_MIN
-std=gnu++17
-I src
-I lib/polymech-base/src
-DPROJECT_DIR="\"${PROJECT_DIR}\""

View File

@ -85,25 +85,3 @@ board_build.extra_flags =
lib_ignore = WebServer
lib_deps =
${env:waveshare_base.lib_deps}
;[env:esp32-p4-evboard]
;extra_scripts = scripts/LittleFSBuilder.py
;lib_ignore = WebServer
;upload_protocol = esptool
;debug_init_break = tbreak setup
;monitor_filters = esp32_exception_decoder
;board_upload.speed = 115200
;board_build.filesystem = littlefs
;platform = https://github.com/pioarduino/platform-espressif32/releases/download/55.03.30-2/platform-espressif32.zip
;board = esp32-p4-evboard
;framework = arduino
;monitor_speed = 115200
;lib_deps =
; ${env:waveshare_base.lib_deps}
;build_flags =
; -DARDUINO_USB_MODE=1
; -DARDUINO_USB_CDC_ON_BOOT=1
; -std=gnu++17
; -I src
; -I lib/polymech-base/src

View File

@ -2,6 +2,7 @@ sh scripts/create-bundle.sh
sh scripts/build-deps.sh
cp ./clients/mesint/master/* ./dist/data/
osr-sync zip --source=./dist/ --target=./clients/mesint/master.zip --cwd=./dist --profile=./sync-clients.json --verbose --debug
# sh scripts/create-bundle.sh

View File

@ -1,5 +1,6 @@
sh scripts/create-bundle.sh
sh scripts/build-deps.sh
cp ./clients/plastichub/master/* ./dist/data/
osr-sync zip --source=./dist/ --target=./clients/plastichub/master.zip --cwd=./dist --profile=./sync-clients.json --verbose --debug

View File

@ -1,9 +1,9 @@
sh scripts/create-bundle.sh
sh scripts/build-deps.sh
cp ./clients/plastiq/master/* ./dist/data/
osr-sync zip --source=./dist/ --target=./clients/plastiq/master.zip --cwd=./dist --profile=./sync-clients.json --verbose --debug
sh scripts/create-bundle.sh
cp ./clients/plastiq/slave/* ./dist/data/
osr-sync zip --source=./dist/ --target=./clients/plastiq/slave.zip --cwd=./dist --profile=./sync-clients.json --verbose --debug

View File

@ -4,7 +4,7 @@
# Define local and remote paths
LOCAL_DIR="./clients/plastiq"
GDRIVE_DIR="polymech.info:/httpdocs/plastiq"
GDRIVE_DIR="pm-site:/plastiq"
rclone copy "${LOCAL_DIR}/" "${GDRIVE_DIR}" --progress --transfers 4 --include "*.zip" --verbose

View File

@ -241,9 +241,9 @@ def main():
# pm-fw-cli.exe dump --targethost=http://<IP> --directory=./backup
backup_args = ["dump", f"--targethost=http://{target_host_ip}", "--directory=./backup"]
if not run_pm_cli(backup_args):
print("❌ Backup failed. Aborting update.")
return 1
print("✅ Backup completed successfully.")
print("🔶 Warning: Backup failed. Proceeding with update anyway...")
else:
print("✅ Backup completed successfully.")
# --- 2. FIRMWARE/FS UPDATE ---
print("\n=== PHASE 2: FIRMWARE UPDATE ===")
@ -282,12 +282,7 @@ def main():
# pm-fw-cli.exe restore --directory=./backup --targethost=http://<IP>
restore_args = ["restore", "--directory=./backup", f"--targethost=http://{target_host_ip}"]
if not run_pm_cli(restore_args):
print("❌ Restore failed.")
# We don't abort reset here, usually we still want to reset?
# But if restore failed, maybe we should stop.
# User said: "assume the worst :)", implying logs will help.
# But if restore fails, maybe we shouldn't reset to avoid bootlooping on bad config?
# For now, we'll try to proceed to Reset because the firmware was just updated.
print("🔶 Warning: Restore failed. Proceeding with reset anyway...")
else:
print("✅ Restore completed successfully.")

View File

@ -2,7 +2,8 @@
cp -r ./config/* ./data/
rm ./data/assets/*.js
rm ./data/assets/*.css
pm-config patch-app --src=./data/index.html --dst ./data/index.html
pm-fw-cli patch-app --src=./data/index.html --dst ./data/index.html
#rm ./data/assets/*.gz
#rm ./data/assets/*.woff
#rm ./data/assets/*.woff2

File diff suppressed because it is too large Load Diff

View File

@ -65,6 +65,7 @@ class InfluxDB;
class IFTTTWebhook;
class OmronE5;
class DELTA_VFD;
class Settings;
#if defined(ENABLE_AMPERAGE_BUDGET_MANAGER)
bool PHApp_canUsePID(Component *owner, OmronE5 *device);

View File

@ -53,11 +53,14 @@ short PHApp::restoreState()
}
}
}
#endif
setAllOmronComWrite(runtimeState->allOmronComWrite, false);
setAllOmronStop(runtimeState->allOmronStop, false);
setAllOmronComWrite(runtimeState->allOmronComWrite, false);
L_INFO("Omron Stop state restored: %d", runtimeState->allOmronStop);
L_INFO("Slave state restored: %d", runtimeState->isSlave);
L_INFO("Omron Com Write state restored: %d", runtimeState->allOmronComWrite);
#endif
for (const auto &state : runtimeState->loadedManagedComponents)
{
Component *comp = this->byId(state.id);
@ -72,10 +75,6 @@ short PHApp::restoreState()
}
}
runtimeState->loadedManagedComponents.clear();
L_INFO("Omron Stop state restored: %d", runtimeState->allOmronStop);
L_INFO("Slave state restored: %d", runtimeState->isSlave);
L_INFO("Omron Com Write state restored: %d", runtimeState->allOmronComWrite);
return E_OK;
#else
return E_OK;

View File

@ -753,6 +753,7 @@ short PHApp::registerWebSocketHandlers(RESTServer *instance)
client->text(responseStr); });
#endif
#ifdef ENABLE_AMPERAGE_BUDGET_MANAGER
// Binary inspector for AmperageBudgetManager
instance->registerWsCommandHandler("get_amp_state", [this](AsyncWebSocketClient *client, JsonVariant &json)
{
@ -787,6 +788,9 @@ short PHApp::registerWebSocketHandlers(RESTServer *instance)
} });
#endif
#endif
#ifdef ENABLE_RS485
instance->registerWsCommandHandler("get_pending_ops", [this](AsyncWebSocketClient *client, JsonVariant &json)
{
RS485* rs485 = static_cast<RS485*>(this->byId(COMPONENT_KEY_RS485));
@ -904,6 +908,7 @@ short PHApp::registerWebSocketHandlers(RESTServer *instance)
String responseStr;
serializeJson(responseDoc, responseStr);
client->text(responseStr); });
#endif
return E_OK;
}

62
src/config-4-min.h Normal file
View File

@ -0,0 +1,62 @@
#ifndef CONFIG_4_MIN_H
#define CONFIG_4_MIN_H
/**
* Minimal configuration for ESP32-P4 bring-up.
* Disables most peripherals and logic to isolate issues.
*/
// --- Disable Features ---
#define DISABLE_MODBUS_TCP
#define DISABLE_RS485
#define DISABLE_RS485_DEVICES
// Disable Drivers/Components
#undef ENABLE_OMRON_E5
#undef ENABLE_SAKO_VFD
#undef ENABLE_DELTA_VFD
#undef ENABLE_HY_VFD
#undef ENABLE_LOADCELL_0
#undef ENABLE_LOADCELL_1
#undef ENABLE_SOLENOID_0
#undef ENABLE_SOLENOID_1
#undef ENABLE_PRESS_CYLINDER
#undef ENABLE_JOYSTICK
#undef ENABLE_OPERATOR_SWITCH
#undef ENABLE_RELAYS
#undef ENABLE_STATUS
#undef ENABLE_FEEDBACK_3C
#undef ENABLE_FEEDBACK_BUZZER
#undef ENABLE_PID
#undef ENABLE_PROFILE_TEMPERATURE
#undef ENABLE_PROFILE_PRESSURE
#undef ENABLE_PROFILE_SIGNAL_PLOT
#undef ENABLE_MB_SCRIPT
#undef ENABLE_SETTINGS
#undef ENABLE_MODBUS_MIRROR
#undef ENABLE_EXTRUDER
#undef ENABLE_PLUNGER
#undef ENABLE_SETTINGS
#undef ENABLE_AMPERAGE_BUDGET_MANAGER
#undef PROFILE_SIGNAL_PLOT_COUNT
#undef PROFILE_TEMPERATURE_COUNT
#undef PROFILE_PRESSURE_COUNT
#undef NUM_OMRON_DEVICES
#define NUM_OMRON_DEVICES 0
#define PROFILE_PRESSURE_COUNT 0
#define PROFILE_TEMPERATURE_COUNT 0
#define PROFILE_SIGNAL_PLOT_COUNT 0
// Disable Profiler for now to reduce overhead
// #undef ENABLE_PROFILER
// --- Drivers Override ---
// (Ensure these are definitely off if undef isn't enough due to logic order)
// You might need to check how these are used. If #ifdef ENABLE_X is used, #undef is fine.
// Override Baud Rate to match P4 monitor_speed
#undef SERIAL_BAUD_RATE
#define SERIAL_BAUD_RATE 115200
#endif // CONFIG_4_MIN_H

View File

@ -2,7 +2,7 @@
#define CONFIG_USER_H
#define ENABLE_OMRON_E5
#define NUM_OMRON_DEVICES 4
#define NUM_OMRON_DEVICES 8
#define ENABLE_AMPERAGE_BUDGET_MANAGER
#define ENABLE_JOYSTICK
@ -26,4 +26,4 @@
#undef HMI_NAME
#define HMI_NAME "cassandra"
#endif // CONFIG_USER_H
#endif // CONFIG_USER_H

View File

@ -23,100 +23,113 @@
*/
// WiFi and Network Features
#if (defined(ENABLE_WEBSERVER) || defined(ENABLE_REST_SERVER) || defined(ENABLE_WEBSOCKET) || defined(ENABLE_MODBUS_TCP)) && !defined(ENABLE_WIFI)
#error "Network features (WebServer, REST, WebSocket, ModbusTCP) require ENABLE_WIFI to be defined."
#if (defined(ENABLE_WEBSERVER) || defined(ENABLE_REST_SERVER) || \
defined(ENABLE_WEBSOCKET) || defined(ENABLE_MODBUS_TCP)) && \
!defined(ENABLE_WIFI)
#error \
"Network features (WebServer, REST, WebSocket, ModbusTCP) require ENABLE_WIFI to be defined."
#endif
#ifdef ENABLE_LOGGING_TARGET_WEBSOCKET
#if !defined(ENABLE_LOGGER)
#error "ENABLE_LOGGING_TARGET_WEBSOCKET requires ENABLE_LOGGER."
#endif
#if !defined(ENABLE_WEBSOCKET)
#error "ENABLE_LOGGING_TARGET_WEBSOCKET requires ENABLE_WEBSOCKET."
#endif
#if !defined(ENABLE_LOGGER)
#error "ENABLE_LOGGING_TARGET_WEBSOCKET requires ENABLE_LOGGER."
#endif
#if !defined(ENABLE_WEBSOCKET)
#error "ENABLE_LOGGING_TARGET_WEBSOCKET requires ENABLE_WEBSOCKET."
#endif
#endif
#ifdef ENABLE_LOGGING_TARGET_FILE
#if !defined(ENABLE_LOGGER)
#error "ENABLE_LOGGING_TARGET_FILE requires ENABLE_LOGGER."
#endif
#if !defined(ENABLE_LITTLEFS)
#error "ENABLE_LOGGING_TARGET_FILE requires ENABLE_LITTLEFS."
#endif
#if !defined(ENABLE_LOGGER)
#error "ENABLE_LOGGING_TARGET_FILE requires ENABLE_LOGGER."
#endif
#if !defined(ENABLE_LITTLEFS)
#error "ENABLE_LOGGING_TARGET_FILE requires ENABLE_LITTLEFS."
#endif
#endif
// RS485 and dependant components
#if (defined(ENABLE_OMRON_E5) || defined(ENABLE_SAKO_VFD)) && !defined(ENABLE_RS485)
#error "Omron E5 and SAKO VFD components require ENABLE_RS485."
#if (defined(ENABLE_OMRON_E5) || defined(ENABLE_SAKO_VFD)) && \
!defined(ENABLE_RS485)
#error "Omron E5 and SAKO VFD components require ENABLE_RS485."
#endif
// High-level component dependencies
#ifdef ENABLE_EXTRUDER
#if !defined(ENABLE_SAKO_VFD)
#error "ENABLE_EXTRUDER requires ENABLE_SAKO_VFD."
#endif
#if !defined(ENABLE_SAKO_VFD)
#error "ENABLE_EXTRUDER requires ENABLE_SAKO_VFD."
#endif
#endif
#ifdef ENABLE_PLUNGER
#if !defined(ENABLE_SAKO_VFD) && !defined(ENABLE_DELTA_VFD)
#error "ENABLE_PLUNGER requires ENABLE_SAKO_VFD or ENABLE_DELTA_VFD."
#endif
#if !defined(ENABLE_JOYSTICK)
#warning "ENABLE_PLUNGER is typically used with ENABLE_JOYSTICK for manual control."
#endif
#if !defined(MB_ANALOG_0) || !defined(MB_ANALOG_1)
#error "ENABLE_PLUNGER requires MB_ANALOG_0 and MB_ANALOG_1 for position feedback."
#endif
#if !defined(ENABLE_DELTA_VFD)
#error "ENABLE_PLUNGER requires ENABLE_DELTA_VFD."
#endif
#if !defined(ENABLE_JOYSTICK)
#warning \
"ENABLE_PLUNGER is typically used with ENABLE_JOYSTICK for manual control."
#endif
#if !defined(MB_ANALOG_0) || !defined(MB_ANALOG_1)
#error \
"ENABLE_PLUNGER requires MB_ANALOG_0 and MB_ANALOG_1 for position feedback."
#endif
#endif
#ifdef ENABLE_PRESS_CYLINDER
#if !defined(ENABLE_SOLENOID_0)
#error "ENABLE_PRESS_CYLINDER requires ENABLE_SOLENOID_0."
#endif
#if !defined(ENABLE_LOADCELL)
// #warning "ENABLE_PRESS_CYLINDER is typically used with ENABLE_LOADCELL for force feedback."
#endif
#if !defined(ENABLE_SOLENOID_0)
#error "ENABLE_PRESS_CYLINDER requires ENABLE_SOLENOID_0."
#endif
#if !defined(ENABLE_LOADCELL)
// #warning "ENABLE_PRESS_CYLINDER is typically used with ENABLE_LOADCELL for
// force feedback."
#endif
#endif
// Profile dependencies
#if defined(ENABLE_PROFILE_TEMPERATURE) && !defined(ENABLE_OMRON_E5)
#error "ENABLE_PROFILE_TEMPERATURE requires ENABLE_OMRON_E5 to control heaters."
#error "ENABLE_PROFILE_TEMPERATURE requires ENABLE_OMRON_E5 to control heaters."
#endif
#if (defined(ENABLE_PROFILE_TEMPERATURE) || defined(ENABLE_PROFILE_SIGNAL_PLOT)) && !defined(ENABLE_LITTLEFS)
#error "Temperature and Signal Profiles require LittleFS (ENABLE_LITTLEFS) to be enabled for storing plot data."
#if (defined(ENABLE_PROFILE_TEMPERATURE) || \
defined(ENABLE_PROFILE_SIGNAL_PLOT)) && \
!defined(ENABLE_LITTLEFS)
#error \
"Temperature and Signal Profiles require LittleFS (ENABLE_LITTLEFS) to be enabled for storing plot data."
#endif
#ifdef ENABLE_AMPERAGE_BUDGET_MANAGER
#if !defined(ENABLE_OMRON_E5)
#error "ENABLE_AMPERAGE_BUDGET_MANAGER requires ENABLE_OMRON_E5."
#endif
#if !defined(ENABLE_OMRON_E5)
#error "ENABLE_AMPERAGE_BUDGET_MANAGER requires ENABLE_OMRON_E5."
#endif
#endif
// Platform-specific features
#ifdef ENABLE_OPERATOR_SWITCH
#if !defined(PIN_OPERATOR_SWITCH_STOP) || !defined(PIN_OPERATOR_SWITCH_CYCLE)
#error "ENABLE_OPERATOR_SWITCH requires PIN_OPERATOR_SWITCH_STOP and PIN_OPERATOR_SWITCH_CYCLE to be defined (typically for ESP32 platform)."
#endif
#if !defined(PIN_OPERATOR_SWITCH_STOP) || !defined(PIN_OPERATOR_SWITCH_CYCLE)
#error \
"ENABLE_OPERATOR_SWITCH requires PIN_OPERATOR_SWITCH_STOP and PIN_OPERATOR_SWITCH_CYCLE to be defined (typically for ESP32 platform)."
#endif
#endif
#ifdef ENABLE_FEEDBACK_3C
#if !defined(GPIO_PIN_CH4) || !defined(GPIO_PIN_CH5) || !defined(GPIO_PIN_CH6)
#error "ENABLE_FEEDBACK_3C requires GPIO_PIN_CH4, GPIO_PIN_CH5, and GPIO_PIN_CH6 to be defined (typically for ESP32 platform)."
#endif
#if !defined(GPIO_PIN_CH4) || !defined(GPIO_PIN_CH5) || !defined(GPIO_PIN_CH6)
#error \
"ENABLE_FEEDBACK_3C requires GPIO_PIN_CH4, GPIO_PIN_CH5, and GPIO_PIN_CH6 to be defined (typically for ESP32 platform)."
#endif
#endif
#ifdef ENABLE_FEEDBACK_BUZZER
#if !defined(GPIO_PIN_CH3)
#error "ENABLE_FEEDBACK_BUZZER requires GPIO_PIN_CH3 to be defined (typically for ESP32 platform)."
#endif
#if !defined(GPIO_PIN_CH3)
#error \
"ENABLE_FEEDBACK_BUZZER requires GPIO_PIN_CH3 to be defined (typically for ESP32 platform)."
#endif
#endif
#ifdef ENABLE_SOLENOID_0
#if !defined(PIN_SOLENOID_0)
#error "ENABLE_SOLENOID_0 requires PIN_SOLENOID_0 to be defined (typically for ESP32 platform)."
#endif
#if !defined(PIN_SOLENOID_0)
#error \
"ENABLE_SOLENOID_0 requires PIN_SOLENOID_0 to be defined (typically for ESP32 platform)."
#endif
#endif
/** @} */ // end of config_validation group

View File

@ -3,6 +3,7 @@
#include <Arduino.h>
#include <stdint.h>
#include "config_adv.h"
///////////////////////////////////////////////////////////////////////////////////////////////////
@ -28,8 +29,7 @@
//
// Component IDs
//
typedef enum COMPONENT_KEY
{
typedef enum COMPONENT_KEY {
COMPONENT_KEY_LOGGER = 10,
COMPONENT_KEY_SETTINGS = 11,
COMPONENT_KEY_RUNTIME_STATE = 250,
@ -250,7 +250,7 @@ using namespace machinecontrol;
// Motor
// #define ENABLE_SAKO_VFD
#define MB_SAKO_VFD_SLAVE_ID 20
// #define MB_SAKO_VFD_SLAVE_ID 30
#define MB_SAKO_VFD_READ_INTERVAL 100
// #define ENABLE_DELTA_VFD
@ -337,14 +337,26 @@ using namespace machinecontrol;
#define ENABLE_WEBSERVER_WIFI_SETTINGS
#define HMI_NAME "cassandra"
///////////////////////////////////////////
// Test only
#define MB_SAKO_VFD_SLAVE_ID 30
#define ENABLE_SAKO_VFD
// #define ENABLE_EXTRUDER
#define ENABLE_DELTA_VFD
#define ENABLE_PLUNGER
///////////////////////////////////////////////////////////////////////////////////////////////////
//
// Configs (in this order!)
//
#include "config-extern.h" // External config settings - PlatformIO config
#include "config-network.h" // Network config settings
#include "config-user.h" // User config settings - Overrides
#include "config-validate.h" // Validate config settings (cheap compiler checks)
#include "config-network.h" // Network config settings
#ifdef ENABLE_P4_MIN
#include "config-4-min.h"
#endif
#include "app-logger.h"

View File

@ -1,5 +1,5 @@
#ifndef VERSION_H
#define VERSION_H
#define VERSION "0.9.0|piq-last|06711e05bf741268fe2feb829263a10b70050385"
#define VERSION "0.9.0|piq-last|fb402903d3aae592d0cc9f96d8ee5ef5570c4630"
#define PACKAGE_URL "https://polymech.info/en/resources/cassandra/"
#endif