LogLevel Fix and ramp range fix
This commit is contained in:
parent
660fa5f1c7
commit
3cf3c72f31
@ -58,10 +58,10 @@
|
|||||||
[
|
[
|
||||||
{
|
{
|
||||||
"en": true,
|
"en": true,
|
||||||
"relay-index": 0,
|
"relay-index": 1,
|
||||||
"button-index": 0,
|
"button-index": 0,
|
||||||
"min": 1.0,
|
"min": 1.0,
|
||||||
"max": 100.0,
|
"max": 90.0,
|
||||||
"step": 1.5,
|
"step": 1.5,
|
||||||
"rate": 30.0,
|
"rate": 30.0,
|
||||||
"skip-count": 5,
|
"skip-count": 5,
|
||||||
@ -69,10 +69,10 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"en": true,
|
"en": true,
|
||||||
"relay-index": 1,
|
"relay-index": 2,
|
||||||
"button-index": 1,
|
"button-index": 1,
|
||||||
"min": 1.0,
|
"min": 1.0,
|
||||||
"max": 100.0,
|
"max": 90.0,
|
||||||
"step": 1.5,
|
"step": 1.5,
|
||||||
"rate": 30.0,
|
"rate": 30.0,
|
||||||
"skip-count": 5,
|
"skip-count": 5,
|
||||||
@ -134,9 +134,24 @@
|
|||||||
"tx433": {
|
"tx433": {
|
||||||
"en": "true"
|
"en": "true"
|
||||||
},
|
},
|
||||||
"ble":{
|
"fire-animation": {
|
||||||
"en": true,
|
"speed": 60,
|
||||||
"name": "Ata_Lights",
|
"cooling": 66,
|
||||||
"core": 1
|
"sparking": 62,
|
||||||
|
"brightness": 240
|
||||||
|
},
|
||||||
|
"comets-animation": {
|
||||||
|
"speed": 80,
|
||||||
|
"size-factor": 0.2,
|
||||||
|
"count": 3,
|
||||||
|
"cycles": 2,
|
||||||
|
"min-fade": 16,
|
||||||
|
"max-fade": 192
|
||||||
|
},
|
||||||
|
"snakes-animation": {
|
||||||
|
"speed": 80,
|
||||||
|
"cycles": 2,
|
||||||
|
"multiplier": 6
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -130,10 +130,5 @@
|
|||||||
},
|
},
|
||||||
"tx433": {
|
"tx433": {
|
||||||
"en": "true"
|
"en": "true"
|
||||||
},
|
|
||||||
"ble":{
|
|
||||||
"en": true,
|
|
||||||
"name": "Ata_Lights",
|
|
||||||
"core": 1
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -60,7 +60,7 @@
|
|||||||
"relay-index": 0,
|
"relay-index": 0,
|
||||||
"button-index": 0,
|
"button-index": 0,
|
||||||
"min": 1.0,
|
"min": 1.0,
|
||||||
"max": 100.0,
|
"max": 90.0,
|
||||||
"step": 1.5,
|
"step": 1.5,
|
||||||
"rate": 30.0,
|
"rate": 30.0,
|
||||||
"skip-count": 5,
|
"skip-count": 5,
|
||||||
@ -71,7 +71,7 @@
|
|||||||
"relay-index": 1,
|
"relay-index": 1,
|
||||||
"button-index": 1,
|
"button-index": 1,
|
||||||
"min": 1.0,
|
"min": 1.0,
|
||||||
"max": 100.0,
|
"max": 90.0,
|
||||||
"step": 1.5,
|
"step": 1.5,
|
||||||
"rate": 30.0,
|
"rate": 30.0,
|
||||||
"skip-count": 5,
|
"skip-count": 5,
|
||||||
@ -132,10 +132,5 @@
|
|||||||
},
|
},
|
||||||
"tx433": {
|
"tx433": {
|
||||||
"en": "true"
|
"en": "true"
|
||||||
},
|
|
||||||
"ble":{
|
|
||||||
"en": true,
|
|
||||||
"name": "Ata_Lights",
|
|
||||||
"core": 1
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -135,10 +135,5 @@
|
|||||||
},
|
},
|
||||||
"tx433": {
|
"tx433": {
|
||||||
"en": "true"
|
"en": "true"
|
||||||
},
|
|
||||||
"ble":{
|
|
||||||
"en": true,
|
|
||||||
"name": "Ata_Lights",
|
|
||||||
"core": 1
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -129,10 +129,5 @@
|
|||||||
},
|
},
|
||||||
"tx433": {
|
"tx433": {
|
||||||
"en": "true"
|
"en": "true"
|
||||||
},
|
|
||||||
"ble":{
|
|
||||||
"en": true,
|
|
||||||
"name": "Ata_Lights",
|
|
||||||
"core": 1
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -130,10 +130,5 @@
|
|||||||
},
|
},
|
||||||
"tx433": {
|
"tx433": {
|
||||||
"en": "true"
|
"en": "true"
|
||||||
},
|
|
||||||
"ble":{
|
|
||||||
"en": true,
|
|
||||||
"name": "Ata_Lights",
|
|
||||||
"core": 1
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -61,7 +61,7 @@
|
|||||||
"relay-index": 0,
|
"relay-index": 0,
|
||||||
"button-index": 0,
|
"button-index": 0,
|
||||||
"min": 1.0,
|
"min": 1.0,
|
||||||
"max": 100.0,
|
"max": 90.0,
|
||||||
"step": 1.5,
|
"step": 1.5,
|
||||||
"rate": 30.0,
|
"rate": 30.0,
|
||||||
"skip-count": 5,
|
"skip-count": 5,
|
||||||
@ -72,7 +72,7 @@
|
|||||||
"relay-index": 1,
|
"relay-index": 1,
|
||||||
"button-index": 1,
|
"button-index": 1,
|
||||||
"min": 1.0,
|
"min": 1.0,
|
||||||
"max": 100.0,
|
"max": 90.0,
|
||||||
"step": 1.5,
|
"step": 1.5,
|
||||||
"rate": 30.0,
|
"rate": 30.0,
|
||||||
"skip-count": 5,
|
"skip-count": 5,
|
||||||
@ -131,10 +131,5 @@
|
|||||||
},
|
},
|
||||||
"tx433": {
|
"tx433": {
|
||||||
"en": "true"
|
"en": "true"
|
||||||
},
|
|
||||||
"ble":{
|
|
||||||
"en": true,
|
|
||||||
"name": "Ata_Lights",
|
|
||||||
"core": 1
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -130,10 +130,5 @@
|
|||||||
},
|
},
|
||||||
"tx433": {
|
"tx433": {
|
||||||
"en": "true"
|
"en": "true"
|
||||||
},
|
|
||||||
"ble":{
|
|
||||||
"en": true,
|
|
||||||
"name": "Ata_Lights",
|
|
||||||
"core": 1
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -130,10 +130,5 @@
|
|||||||
},
|
},
|
||||||
"tx433": {
|
"tx433": {
|
||||||
"en": "true"
|
"en": "true"
|
||||||
},
|
|
||||||
"ble":{
|
|
||||||
"en": true,
|
|
||||||
"name": "Ata_Lights",
|
|
||||||
"core": 1
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -131,11 +131,6 @@
|
|||||||
},
|
},
|
||||||
"tx433": {
|
"tx433": {
|
||||||
"en": "true"
|
"en": "true"
|
||||||
},
|
|
||||||
"ble":{
|
|
||||||
"en": true,
|
|
||||||
"name": "FlashStik",
|
|
||||||
"core": 1
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -129,10 +129,5 @@
|
|||||||
},
|
},
|
||||||
"tx433": {
|
"tx433": {
|
||||||
"en": false
|
"en": false
|
||||||
},
|
|
||||||
"ble":{
|
|
||||||
"en": true,
|
|
||||||
"name": "Ata_Lights",
|
|
||||||
"core": 1
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -131,25 +131,6 @@
|
|||||||
"tx433": {
|
"tx433": {
|
||||||
"en": "true"
|
"en": "true"
|
||||||
},
|
},
|
||||||
"ble":{
|
|
||||||
"en": true,
|
|
||||||
"name": "Ata_Lights",
|
|
||||||
"core": 1
|
|
||||||
},
|
|
||||||
"wifi-client":{
|
|
||||||
"en": true,
|
|
||||||
"mdns-name": "atadev",
|
|
||||||
"ssid": "padillaguest",
|
|
||||||
"pass": "padillaguest"
|
|
||||||
},
|
|
||||||
"wifi-ap":{
|
|
||||||
"ssid": "ATA_AP",
|
|
||||||
"append-id": true,
|
|
||||||
"pass": "12345678",
|
|
||||||
"ip": [192,168,10.1],
|
|
||||||
"gateway": [192,168,10,200],
|
|
||||||
"subnet": [255,255,255,0]
|
|
||||||
},
|
|
||||||
"animation1":{
|
"animation1":{
|
||||||
"white-max-time": 30,
|
"white-max-time": 30,
|
||||||
"white-min": 20,
|
"white-min": 20,
|
||||||
|
|||||||
@ -4,7 +4,7 @@
|
|||||||
<title>Edit file</title>
|
<title>Edit file</title>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<link href="/css/global-style.css" rel="stylesheet">
|
<!--<link href="/css/global-style.css" rel="stylesheet">-->
|
||||||
<link href="/css/nav.css" rel="stylesheet">
|
<link href="/css/nav.css" rel="stylesheet">
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
@ -168,7 +168,7 @@
|
|||||||
|
|
||||||
<!-- Stretchy editor space -->
|
<!-- Stretchy editor space -->
|
||||||
<div class="editor-area">
|
<div class="editor-area">
|
||||||
<textarea name="edit-textarea" id="edit-textarea" wrap="off" placeholder="File contents will appear here..."></textarea>
|
<textarea name="edit-textarea" id="edit-textarea" wrap="off" placeholder="File contents is empty..."></textarea>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
@ -5,7 +5,7 @@
|
|||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<link href="/css/global-style.css" rel="stylesheet">
|
<link href="/css/global-style.css" rel="stylesheet">
|
||||||
<link href="/css/nav.css" rel="stylesheet">
|
<link href="css/nav.css" rel="stylesheet">
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
#file-row:nth-child(odd) {
|
#file-row:nth-child(odd) {
|
||||||
|
|||||||
@ -4,7 +4,7 @@
|
|||||||
<title>File Manager</title>
|
<title>File Manager</title>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<link href="/css/global-style.css" rel="stylesheet">
|
<!--<link href="/css/global-style.css" rel="stylesheet">-->
|
||||||
<link href="/css/nav.css" rel="stylesheet">
|
<link href="/css/nav.css" rel="stylesheet">
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
@ -66,6 +66,7 @@
|
|||||||
"cinttypes": "cpp",
|
"cinttypes": "cpp",
|
||||||
"typeinfo": "cpp"
|
"typeinfo": "cpp"
|
||||||
},
|
},
|
||||||
"liveServer.settings.multiRootWorkspaceName": "esp32s3_atabooth_8mb"
|
"liveServer.settings.multiRootWorkspaceName": "esp32s3_atabooth_8mb",
|
||||||
|
"liveServer.settings.port": 5501
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -16,8 +16,38 @@
|
|||||||
|
|
||||||
#define CYCLES_PER_DIRECTION 2
|
#define CYCLES_PER_DIRECTION 2
|
||||||
|
|
||||||
void Animation_Init(void);
|
#define FIRE_COOLING 55
|
||||||
|
#define FIRE_SPARKING 120
|
||||||
|
#define FIRE_brightness 240
|
||||||
|
|
||||||
|
struct ANIM_FIRE {
|
||||||
|
int speed;
|
||||||
|
uint8_t cooling = FIRE_COOLING; // How much does the fire cool as it rises. Less cooling = taller flames. Default 55, suggested range 20-100
|
||||||
|
uint8_t sparking = FIRE_SPARKING; // What chance (out of 255) is there that a new spark will be lit. Higher chance = more roaring fire. Default 120, suggested range 50-200
|
||||||
|
uint8_t brightness = FIRE_brightness; // Overall brightness of the fire effect. Default 240, suggested range 50-255
|
||||||
|
};
|
||||||
|
extern ANIM_FIRE fireSettings;
|
||||||
|
|
||||||
|
struct ANIM_COMET {
|
||||||
|
int speed;
|
||||||
|
int minFade;
|
||||||
|
int maxFade;
|
||||||
|
float sizeFactor;
|
||||||
|
int cycles;
|
||||||
|
int count;
|
||||||
|
};
|
||||||
|
extern ANIM_COMET cometSettings;
|
||||||
|
|
||||||
|
struct ANIM_SNAKES{
|
||||||
|
int speed;
|
||||||
|
int cycles;
|
||||||
|
int multiplier;
|
||||||
|
};
|
||||||
|
extern ANIM_SNAKES snakeSettings;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void Animation_Init(void);
|
||||||
void Animation_Loop(bool volatile& loop_active_flag, int speed, std::function<int()> callback);
|
void Animation_Loop(bool volatile& loop_active_flag, int speed, std::function<int()> callback);
|
||||||
void Animation_Loop_Limited(bool volatile& loop_active_flag, int speed, TickType_t duration, std::function<int()> callback);
|
void Animation_Loop_Limited(bool volatile& loop_active_flag, int speed, TickType_t duration, std::function<int()> callback);
|
||||||
void Animation_Loop_Cycles(bool volatile& loop_active_flag, int speed, uint32_t loop_cycles, std::function<int()> callback);
|
void Animation_Loop_Cycles(bool volatile& loop_active_flag, int speed, uint32_t loop_cycles, std::function<int()> callback);
|
||||||
@ -36,7 +66,7 @@ void Anim_Comets(bool volatile& activeFlag, CRGB* leds, int size, const COLOR_PA
|
|||||||
//void Anim_Comet_Rainbow(bool volatile& activeFlag, CRGB* leds, int size, int speed);
|
//void Anim_Comet_Rainbow(bool volatile& activeFlag, CRGB* leds, int size, int speed);
|
||||||
|
|
||||||
void Anim_TimedFill(bool volatile& activeFlag, CRGB* leds, int size, CRGB col1, CRGB col2, int totalDurationMs, int shift);
|
void Anim_TimedFill(bool volatile& activeFlag, CRGB* leds, int size, CRGB col1, CRGB col2, int totalDurationMs, int shift);
|
||||||
void Anim_TimedFill_Flash(bool volatile& activeFlag, CRGB* leds, int size, PWM_Output* pwmOut, PWM_OUT_SETTINGS* pwmSettings, int pwmOutDelay, int flashTimeout, CRGB baseCol, CRGB fillCol, int totalDurationMs, int shift = 0);
|
void Anim_TimedFill_Flash(bool volatile& activeFlag, CRGB* leds, int size, PWM_Output* pwmOut, RAMP_LIGHT_SETTINGS* pwmSettings, int pwmOutDelay, int flashTimeout, CRGB baseCol, CRGB fillCol, int totalDurationMs, int shift = 0);
|
||||||
|
|
||||||
void Anim_ColorBreath(bool volatile& activeFlag, CRGB* leds, int size, const COLOR_PACK& colors, uint32_t timeMs, int speed);
|
void Anim_ColorBreath(bool volatile& activeFlag, CRGB* leds, int size, const COLOR_PACK& colors, uint32_t timeMs, int speed);
|
||||||
|
|
||||||
|
|||||||
@ -17,6 +17,7 @@ board_build.partitions = partitions_8mb_ota_2mb_ee.cvs
|
|||||||
monitor_speed = 115200
|
monitor_speed = 115200
|
||||||
monitor_filters = esp32_exception_decoder
|
monitor_filters = esp32_exception_decoder
|
||||||
board_build.sdkconfig_defaults = sdkconfig.defaults
|
board_build.sdkconfig_defaults = sdkconfig.defaults
|
||||||
|
|
||||||
lib_deps =
|
lib_deps =
|
||||||
bblanchon/ArduinoJson
|
bblanchon/ArduinoJson
|
||||||
makuna/NeoPixelBus @ ^2.8.3
|
makuna/NeoPixelBus @ ^2.8.3
|
||||||
@ -33,8 +34,9 @@ lib_deps =
|
|||||||
build_flags =
|
build_flags =
|
||||||
-mfix-esp32-psram-cache-issue
|
-mfix-esp32-psram-cache-issue
|
||||||
-D CONFIG_LOG_DYNAMIC_LEVEL_CONTROL=1
|
-D CONFIG_LOG_DYNAMIC_LEVEL_CONTROL=1
|
||||||
#-D CORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_VERBOSE
|
-D LOG_LOCAL_LEVEL=5
|
||||||
-D CORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_INFO
|
-D CORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_INFO
|
||||||
|
#-D CORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_INFO
|
||||||
-D CONFIG_ARDUHAL_LOG_COLORS=1
|
-D CONFIG_ARDUHAL_LOG_COLORS=1
|
||||||
#-Os
|
#-Os
|
||||||
#-ffunction-sections
|
#-ffunction-sections
|
||||||
|
|||||||
@ -25,7 +25,10 @@ TaskHandle_t Ramp_Front_Light_Task_Handle;
|
|||||||
LEDSTRIP_SETTINGS ledSettings[2];
|
LEDSTRIP_SETTINGS ledSettings[2];
|
||||||
volatile bool AnimationLooping = false;
|
volatile bool AnimationLooping = false;
|
||||||
ANIM_EVENT prevAnimEvent = {0};
|
ANIM_EVENT prevAnimEvent = {0};
|
||||||
QueueHandle_t animationQueue = xQueueCreate( 4, sizeof( ANIM_EVENT ) );
|
//QueueHandle_t animationQueue = xQueueCreate( 4, sizeof( ANIM_EVENT ) );
|
||||||
|
|
||||||
|
static QueueHandle_t animationQueue = NULL;
|
||||||
|
static SemaphoreHandle_t fastledMutex = NULL;
|
||||||
|
|
||||||
bool upgradeMode = false;
|
bool upgradeMode = false;
|
||||||
|
|
||||||
@ -36,7 +39,6 @@ bool upgradeMode = false;
|
|||||||
//bool fillAnimationActive = false;
|
//bool fillAnimationActive = false;
|
||||||
|
|
||||||
void RGB_Lights_Set_Animation(int animIndex, uint8_t red, uint8_t grn, uint8_t blu){
|
void RGB_Lights_Set_Animation(int animIndex, uint8_t red, uint8_t grn, uint8_t blu){
|
||||||
|
|
||||||
// Trigger to exit curring looping animation
|
// Trigger to exit curring looping animation
|
||||||
if(AnimationLooping){
|
if(AnimationLooping){
|
||||||
AnimationLooping = false;
|
AnimationLooping = false;
|
||||||
@ -72,6 +74,21 @@ void Lights_Set_White(uint8_t val){
|
|||||||
|
|
||||||
|
|
||||||
void Init_RGB_Lights_Task(bool upgrade){
|
void Init_RGB_Lights_Task(bool upgrade){
|
||||||
|
// create queue & mutex here and check
|
||||||
|
if (animationQueue == NULL) {
|
||||||
|
animationQueue = xQueueCreate(4, sizeof(ANIM_EVENT));
|
||||||
|
if (animationQueue == NULL) {
|
||||||
|
ESP_LOGE(tag, "Failed to create animationQueue");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// validate ledSettings[] fields before allocating
|
||||||
|
if (ledSettings[0].size <= 0) {
|
||||||
|
ESP_LOGE(tag, "Invalid ledSettings[0].size");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
upgradeMode = upgrade;
|
upgradeMode = upgrade;
|
||||||
ledSettings[0].leds = new CRGB[ledSettings[0].size];
|
ledSettings[0].leds = new CRGB[ledSettings[0].size];
|
||||||
Init_RGB_Strip(ledSettings[0].leds, ledSettings[0].pin, ledSettings[0].size, ledSettings[0].rgbOrder, ledSettings[0].chip, ledSettings[0].bright);
|
Init_RGB_Strip(ledSettings[0].leds, ledSettings[0].pin, ledSettings[0].size, ledSettings[0].rgbOrder, ledSettings[0].chip, ledSettings[0].bright);
|
||||||
@ -87,131 +104,6 @@ void Init_RGB_Lights_Task(bool upgrade){
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
void Init_Ramp_Front_Light_Task(void){
|
|
||||||
// Check if pwmOutputs[0] is available before creating the task
|
|
||||||
if(pwmOutputs[0] == nullptr) {
|
|
||||||
ESP_LOGE(tag, "Cannot create Ramp Front Light Task: pwmOutputs[0] is not initialized");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create task with moderate stack size - 2KB should be sufficient
|
|
||||||
BaseType_t result = xTaskCreatePinnedToCore(Ramp_Front_Light_Control_Task, "Ramp_Front_Light_Task", 1024*2, NULL, 1, &Ramp_Front_Light_Task_Handle, (FASTLED_CORE ? 1 : 0));
|
|
||||||
|
|
||||||
if(result != pdPASS) {
|
|
||||||
ESP_LOGE(tag, "Failed to create Ramp Front Light Task, error: %d", result);
|
|
||||||
Ramp_Front_Light_Task_Handle = NULL;
|
|
||||||
} else {
|
|
||||||
ESP_LOGI(tag, "Ramp Front Light Task Created...");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
#define RAMP_INTERVAL 25
|
|
||||||
#define FRONTLIGHT_TIMEOUT 20000
|
|
||||||
int startDelay = 0;
|
|
||||||
int rampTime = 0;
|
|
||||||
bool rampRestart = false;
|
|
||||||
float FrontLightMin = 0.0;
|
|
||||||
|
|
||||||
void Ramp_Front_Light_Control_Task(void *parameters)
|
|
||||||
{
|
|
||||||
float currPwmValue = 0.0;
|
|
||||||
float outValue = 0.0;
|
|
||||||
int timeCounter = 0;
|
|
||||||
|
|
||||||
while(1) {
|
|
||||||
|
|
||||||
if(rampRestart == false){
|
|
||||||
vTaskSuspend(NULL); // Wait to be triggered
|
|
||||||
}
|
|
||||||
rampRestart = false; // Clear the flag immediately
|
|
||||||
|
|
||||||
// Safety check: Ensure pwmOutputs[0] is initialized
|
|
||||||
if(pwmOutputs[0] == nullptr) {
|
|
||||||
ESP_LOGE(tag, "pwmOutputs[0] is null, cannot control front light");
|
|
||||||
rampRestart = false;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Wait for start delay to finish
|
|
||||||
while(!rampRestart && fillAnimationActive && startDelay > 0){
|
|
||||||
vTaskDelay(10 / portTICK_PERIOD_MS);
|
|
||||||
startDelay -= 10;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(rampRestart){
|
|
||||||
continue; // Restart if requested during delay
|
|
||||||
}
|
|
||||||
|
|
||||||
//currPwmValue = pwmOutputs[0]->getDuty(); // Get current PWM value
|
|
||||||
currPwmValue = FrontLightMin; // Always start from min value
|
|
||||||
pwmOutputs[0]->setOutput(currPwmValue); // Ensure starting point is set
|
|
||||||
|
|
||||||
// Ramp Up the Front Light linearly
|
|
||||||
timeCounter = 0; // Reset timer for ramp up
|
|
||||||
int rampMs = rampTime;
|
|
||||||
while(!rampRestart && fillAnimationActive && rampMs > 0){
|
|
||||||
timeCounter += RAMP_INTERVAL;
|
|
||||||
outValue = map(timeCounter, 0, rampTime, currPwmValue, 100);
|
|
||||||
pwmOutputs[0]->setOutput(outValue);
|
|
||||||
vTaskDelay(RAMP_INTERVAL / portTICK_PERIOD_MS);
|
|
||||||
rampMs -= RAMP_INTERVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(rampRestart){
|
|
||||||
continue; // Restart the ramp up if requested
|
|
||||||
}
|
|
||||||
|
|
||||||
// Max Wait fill animation to end or timeout
|
|
||||||
int frontLightTimeout = FRONTLIGHT_TIMEOUT;
|
|
||||||
while(!rampRestart && fillAnimationActive && frontLightTimeout > 0){
|
|
||||||
vTaskDelay(10 / portTICK_PERIOD_MS);
|
|
||||||
frontLightTimeout -= 10;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(rampRestart){
|
|
||||||
pwmOutputs[0]->setOutput(0); // Ensure it's fully off
|
|
||||||
continue; // Restart the ramp up if requested
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ramp Down the Front Light linearly
|
|
||||||
timeCounter = 0; // Reset timer for ramp down
|
|
||||||
rampMs = rampTime;
|
|
||||||
while(!rampRestart && fillAnimationActive && rampMs > 0){
|
|
||||||
timeCounter += RAMP_INTERVAL;
|
|
||||||
outValue = map(timeCounter, 0, rampTime, 100 , currPwmValue);
|
|
||||||
pwmOutputs[0]->setOutput(outValue);
|
|
||||||
vTaskDelay(RAMP_INTERVAL / portTICK_PERIOD_MS);
|
|
||||||
rampMs -= RAMP_INTERVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cycle completed - ensure clean final state
|
|
||||||
if(!rampRestart){
|
|
||||||
pwmOutputs[0]->setOutput(FrontLightMin); // Ensure final state is minimum
|
|
||||||
fillAnimationActive = false; // Clear animation flag
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Start_RampUp_Front_Light(int _rampTime, int _startDelay)
|
|
||||||
{
|
|
||||||
// Check if the task exists before trying to control it
|
|
||||||
if(Ramp_Front_Light_Task_Handle == NULL) {
|
|
||||||
ESP_LOGW(tag, "Cannot start front light ramp: task not created");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
rampTime = _rampTime;
|
|
||||||
startDelay = _startDelay;
|
|
||||||
fillAnimationActive = true;
|
|
||||||
rampRestart = true;
|
|
||||||
vTaskResume(Ramp_Front_Light_Task_Handle);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
void Animation_Loop_Exit(void){
|
void Animation_Loop_Exit(void){
|
||||||
if( Animation_Task_Handle ){
|
if( Animation_Task_Handle ){
|
||||||
xTaskNotifyGive( Animation_Task_Handle );
|
xTaskNotifyGive( Animation_Task_Handle );
|
||||||
@ -509,11 +401,11 @@ void RGB_Lights_Control_Task(void *parameters){
|
|||||||
ESP_LOGD(tag, "New Animation Event: Index: %d", AnimEvent.AnimationIndex);
|
ESP_LOGD(tag, "New Animation Event: Index: %d", AnimEvent.AnimationIndex);
|
||||||
switch (AnimEvent.AnimationIndex) {
|
switch (AnimEvent.AnimationIndex) {
|
||||||
|
|
||||||
case -3: // Set Shift
|
case -3:{ // Set Shift
|
||||||
if (AnimEvent.data.data[0] >= 0 && AnimEvent.data.data[0] < ledSettings[0].size) {
|
if (AnimEvent.data.data[0] >= 0 && AnimEvent.data.data[0] < ledSettings[0].size) {
|
||||||
fill_solid(ledSettings[0].leds, ledSettings[0].size, CRGB::Black);
|
fill_solid(ledSettings[0].leds, ledSettings[0].size, CRGB::Black);
|
||||||
ledSettings[0].shift = AnimEvent.data.data[0];
|
ledSettings[0].shift = AnimEvent.data.data[0];
|
||||||
vTaskDelay(25 / portTICK_PERIOD_MS);
|
vTaskDelay(pdMS_TO_TICKS(25));
|
||||||
setPixel1(ledSettings[0], 0, CRGB::White * FastLED.getBrightness() / 255);
|
setPixel1(ledSettings[0], 0, CRGB::White * FastLED.getBrightness() / 255);
|
||||||
FastLED.show();
|
FastLED.show();
|
||||||
ESP_LOGD(tag, "Set Shift: %d", ledSettings[0].shift);
|
ESP_LOGD(tag, "Set Shift: %d", ledSettings[0].shift);
|
||||||
@ -521,37 +413,54 @@ void RGB_Lights_Control_Task(void *parameters){
|
|||||||
ESP_LOGW(tag, "Pixel index out of range: %d", AnimEvent.data.data[0]);
|
ESP_LOGW(tag, "Pixel index out of range: %d", AnimEvent.data.data[0]);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case -2: // Fill Static Color
|
}
|
||||||
|
case -2:{ // Fill Static Color
|
||||||
fill_solid(ledSettings[0].leds, ledSettings[0].size, CRGB(AnimEvent.data.red, AnimEvent.data.grn, AnimEvent.data.blu));
|
fill_solid(ledSettings[0].leds, ledSettings[0].size, CRGB(AnimEvent.data.red, AnimEvent.data.grn, AnimEvent.data.blu));
|
||||||
FastLED.show();
|
FastLED.show();
|
||||||
ESP_LOGD(tag, "Static Color");
|
ESP_LOGD(tag, "Static Color");
|
||||||
break;
|
break;
|
||||||
case -1:
|
}
|
||||||
|
case -1:{
|
||||||
FastLED.clear();
|
FastLED.clear();
|
||||||
FastLED.show();
|
FastLED.show();
|
||||||
ESP_LOGD(tag, "LEDs Off");
|
ESP_LOGD(tag, "LEDs Off");
|
||||||
break;
|
break;
|
||||||
case 0:
|
}
|
||||||
|
case 0:{
|
||||||
fill_solid(ledSettings[0].leds, ledSettings[0].size, CRGB::Black);
|
fill_solid(ledSettings[0].leds, ledSettings[0].size, CRGB::Black);
|
||||||
FastLED.show();
|
FastLED.show();
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case 1 ... 5: { // Timed Fill Animations
|
case 1 ... 5: { // Timed Fill Animations
|
||||||
int timeDuration = AnimEvent.AnimationIndex * 1000 - 400;
|
float tempMax = -1;
|
||||||
|
if(AnimEvent.AnimationIndex == 1 && sys_settings.rampLightSettings[0].max > 70.0) {
|
||||||
|
tempMax = sys_settings.rampLightSettings[0].max; // preserve user setting if higher than 70
|
||||||
|
sys_settings.rampLightSettings[0].max = 70.0;
|
||||||
|
}
|
||||||
|
int timeDuration = (AnimEvent.AnimationIndex * 1000) - 100;
|
||||||
int whiteDelay = timeDuration - 1000;
|
int whiteDelay = timeDuration - 1000;
|
||||||
if (whiteDelay < 800) whiteDelay = 800; // minimum 8 seconds
|
if (whiteDelay < 0) whiteDelay = 0;
|
||||||
Anim_TimedFill_Flash(AnimationLooping, ledSettings[0].leds, ledSettings[0].size, pwmOutputs[0], &sys_settings.pwmOutSettings[0], whiteDelay, 20000, CRGB::Black, CRGB::White, timeDuration, ledSettings[0].shift);
|
Anim_TimedFill_Flash(AnimationLooping, ledSettings[0].leds, ledSettings[0].size, pwmOutputs[sys_settings.rampLightSettings[0].pwmOutIndex], &sys_settings.rampLightSettings[0], whiteDelay, 20000, CRGB::Black, CRGB(CRGB::White).nscale8(180), timeDuration, ledSettings[0].shift);
|
||||||
|
|
||||||
|
// restore ramp light max if it was changed
|
||||||
|
if(tempMax > 0){
|
||||||
|
sys_settings.rampLightSettings[0].max = tempMax; // restore user setting
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 6:
|
case 6:{
|
||||||
// RGB White and Dedicated White all on with timeout and brightness reduction
|
// RGB White and Dedicated White all on with timeout and brightness reduction
|
||||||
Anim_SolidWhite(AnimationLooping, ledSettings[0].leds, pwmOutputs[0], ledSettings[0].size, 240, 30000);
|
Anim_SolidWhite(AnimationLooping, ledSettings[0].leds, pwmOutputs[sys_settings.rampLightSettings[0].pwmOutIndex], ledSettings[0].size, 240, 30000);
|
||||||
break;
|
break;
|
||||||
case 7:
|
}
|
||||||
|
case 7:{
|
||||||
Anim_Rainbow(AnimationLooping, ledSettings[0].leds, ledSettings[0].size, 60);
|
Anim_Rainbow(AnimationLooping, ledSettings[0].leds, ledSettings[0].size, 60);
|
||||||
break;
|
break;
|
||||||
case 8 ... 12:
|
}
|
||||||
|
case 8 ... 12:{
|
||||||
Anim_GradientRotate(AnimationLooping, ledSettings[0].leds, ledSettings[0].size, gradient_colorPack[AnimEvent.AnimationIndex - 8], 80);
|
Anim_GradientRotate(AnimationLooping, ledSettings[0].leds, ledSettings[0].size, gradient_colorPack[AnimEvent.AnimationIndex - 8], 80);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case 13 ... 17: { // Fire Animations
|
case 13 ... 17: { // Fire Animations
|
||||||
COLOR_PACK fp = fireColorPacks[AnimEvent.AnimationIndex - 13]; // copy const pack to mutable
|
COLOR_PACK fp = fireColorPacks[AnimEvent.AnimationIndex - 13]; // copy const pack to mutable
|
||||||
CRGBPalette16 firePalette;
|
CRGBPalette16 firePalette;
|
||||||
@ -559,72 +468,91 @@ void RGB_Lights_Control_Task(void *parameters){
|
|||||||
Anim_Fire(AnimationLooping, ledSettings[0].leds, ledSettings[0].size, 60, firePalette, ledSettings[0].shift);
|
Anim_Fire(AnimationLooping, ledSettings[0].leds, ledSettings[0].size, 60, firePalette, ledSettings[0].shift);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 18 ... 20: // Sparkle/Twinkle
|
case 18 ... 20:{ // Sparkle/Twinkle
|
||||||
Anim_Sparkle(AnimationLooping, ledSettings[0].leds, ledSettings[0].size, tripple_colorPacks[0], 40, 20);
|
Anim_Sparkle(AnimationLooping, ledSettings[0].leds, ledSettings[0].size, tripple_colorPacks[0], 40, 20);
|
||||||
break;
|
break;
|
||||||
case 21:
|
}
|
||||||
|
case 21: {
|
||||||
Anim_ColorBreath(AnimationLooping, ledSettings[0].leds, ledSettings[0].size, colorPack_RAINBOW, 7000, 90);
|
Anim_ColorBreath(AnimationLooping, ledSettings[0].leds, ledSettings[0].size, colorPack_RAINBOW, 7000, 90);
|
||||||
break;
|
break;
|
||||||
case 22: // Rain Animation
|
}
|
||||||
|
case 22:{ // Rain Animation
|
||||||
Anim_Morph(AnimationLooping, ledSettings[0].leds, ledSettings[0].size, colorPack_RAINBOW, 20, 40);
|
Anim_Morph(AnimationLooping, ledSettings[0].leds, ledSettings[0].size, colorPack_RAINBOW, 20, 40);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// Comets
|
// Comets
|
||||||
case 23:
|
case 23: {
|
||||||
Anim_Comets(AnimationLooping, ledSettings[0].leds, ledSettings[0].size, colorPack_RAINBOW, 40, 85, RANDOM_DECAY, 1);
|
Anim_Comets(AnimationLooping, ledSettings[0].leds, ledSettings[0].size, colorPack_RAINBOW, 40, 85, RANDOM_DECAY, 1);
|
||||||
break;
|
break;
|
||||||
case 24 ... 31:
|
}
|
||||||
|
case 24 ... 31:{
|
||||||
Anim_Comets(AnimationLooping, ledSettings[0].leds, ledSettings[0].size, single_colorPacks[AnimEvent.AnimationIndex - 24], 40, 85, RANDOM_DECAY, 6);
|
Anim_Comets(AnimationLooping, ledSettings[0].leds, ledSettings[0].size, single_colorPacks[AnimEvent.AnimationIndex - 24], 40, 85, RANDOM_DECAY, 6);
|
||||||
break;
|
break;
|
||||||
case 32 ... 40:
|
}
|
||||||
|
case 32 ... 40:{
|
||||||
Anim_Comets(AnimationLooping, ledSettings[0].leds, ledSettings[0].size, double_colorPacks[AnimEvent.AnimationIndex - 32], 40, 85, RANDOM_DECAY, 3);
|
Anim_Comets(AnimationLooping, ledSettings[0].leds, ledSettings[0].size, double_colorPacks[AnimEvent.AnimationIndex - 32], 40, 85, RANDOM_DECAY, 3);
|
||||||
break;
|
break;
|
||||||
case 41 ... 49:
|
}
|
||||||
|
case 41 ... 49:{
|
||||||
Anim_Comets(AnimationLooping, ledSettings[0].leds, ledSettings[0].size, tripple_colorPacks[AnimEvent.AnimationIndex - 41], 40, 85, RANDOM_DECAY, 2);
|
Anim_Comets(AnimationLooping, ledSettings[0].leds, ledSettings[0].size, tripple_colorPacks[AnimEvent.AnimationIndex - 41], 40, 85, RANDOM_DECAY, 2);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// Snakes
|
// Snakes
|
||||||
case 50:
|
case 50: {
|
||||||
Anim_Snakes(AnimationLooping, ledSettings[0].leds, ledSettings[0].size, colorPack_RAINBOW, 50);
|
Anim_Snakes(AnimationLooping, ledSettings[0].leds, ledSettings[0].size, colorPack_RAINBOW, 50);
|
||||||
break;
|
break;
|
||||||
case 51 ... 58:
|
}
|
||||||
|
case 51 ... 58: {
|
||||||
Anim_Snakes(AnimationLooping, ledSettings[0].leds, ledSettings[0].size, single_colorPacks[AnimEvent.AnimationIndex - 51], 60, 6);
|
Anim_Snakes(AnimationLooping, ledSettings[0].leds, ledSettings[0].size, single_colorPacks[AnimEvent.AnimationIndex - 51], 60, 6);
|
||||||
break;
|
break;
|
||||||
case 59 ... 67:
|
}
|
||||||
|
case 59 ... 67: {
|
||||||
Anim_Snakes(AnimationLooping, ledSettings[0].leds, ledSettings[0].size, double_colorPacks[AnimEvent.AnimationIndex - 59], 60, 3);
|
Anim_Snakes(AnimationLooping, ledSettings[0].leds, ledSettings[0].size, double_colorPacks[AnimEvent.AnimationIndex - 59], 60, 3);
|
||||||
break;
|
break;
|
||||||
case 68 ... 76:
|
}
|
||||||
|
case 68 ... 76: {
|
||||||
Anim_Snakes(AnimationLooping, ledSettings[0].leds, ledSettings[0].size, tripple_colorPacks[AnimEvent.AnimationIndex - 68], 60, 2);
|
Anim_Snakes(AnimationLooping, ledSettings[0].leds, ledSettings[0].size, tripple_colorPacks[AnimEvent.AnimationIndex - 68], 60, 2);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// Sectors
|
// Sectors
|
||||||
case 77:
|
case 77: {
|
||||||
Anim_Color_Sectors(AnimationLooping, ledSettings[0].leds, ledSettings[0].size, colorPack_RAINBOW, NO_GAPS, 1, 40, 90);
|
Anim_Color_Sectors(AnimationLooping, ledSettings[0].leds, ledSettings[0].size, colorPack_RAINBOW, NO_GAPS, 1, 40, 90);
|
||||||
break;
|
break;
|
||||||
case 78 ... 86:
|
}
|
||||||
|
case 78 ... 86: {
|
||||||
Anim_Color_Sectors(AnimationLooping, ledSettings[0].leds, ledSettings[0].size, double_colorPacks[AnimEvent.AnimationIndex - 78], NO_GAPS, 3, 40, 90);
|
Anim_Color_Sectors(AnimationLooping, ledSettings[0].leds, ledSettings[0].size, double_colorPacks[AnimEvent.AnimationIndex - 78], NO_GAPS, 3, 40, 90);
|
||||||
break;
|
break;
|
||||||
case 87 ... 95:
|
}
|
||||||
|
case 87 ... 95: {
|
||||||
Anim_Color_Sectors(AnimationLooping, ledSettings[0].leds, ledSettings[0].size, tripple_colorPacks[AnimEvent.AnimationIndex - 87], NO_GAPS, 2, 40, 90);
|
Anim_Color_Sectors(AnimationLooping, ledSettings[0].leds, ledSettings[0].size, tripple_colorPacks[AnimEvent.AnimationIndex - 87], NO_GAPS, 2, 40, 90);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// Dashes
|
// Dashes
|
||||||
case 96:
|
case 96:{
|
||||||
Anim_Color_Sectors(AnimationLooping, ledSettings[0].leds, ledSettings[0].size, colorPack_RAINBOW, WITH_GAPS, 1, 40, 90);
|
Anim_Color_Sectors(AnimationLooping, ledSettings[0].leds, ledSettings[0].size, colorPack_RAINBOW, WITH_GAPS, 1, 40, 90);
|
||||||
break;
|
break;
|
||||||
case 97 ... 104:
|
}
|
||||||
|
case 97 ... 104:{
|
||||||
Anim_Color_Sectors(AnimationLooping, ledSettings[0].leds, ledSettings[0].size, single_colorPacks[AnimEvent.AnimationIndex - 97], WITH_GAPS, 6, 40, 90);
|
Anim_Color_Sectors(AnimationLooping, ledSettings[0].leds, ledSettings[0].size, single_colorPacks[AnimEvent.AnimationIndex - 97], WITH_GAPS, 6, 40, 90);
|
||||||
break;
|
break;
|
||||||
case 105 ... 113:
|
}
|
||||||
|
case 105 ... 113:{
|
||||||
Anim_Color_Sectors(AnimationLooping, ledSettings[0].leds, ledSettings[0].size, double_colorPacks[AnimEvent.AnimationIndex - 105], WITH_GAPS, 3, 40, 90);
|
Anim_Color_Sectors(AnimationLooping, ledSettings[0].leds, ledSettings[0].size, double_colorPacks[AnimEvent.AnimationIndex - 105], WITH_GAPS, 3, 40, 90);
|
||||||
break;
|
break;
|
||||||
case 114 ... 122:
|
}
|
||||||
|
case 114 ... 122:{
|
||||||
Anim_Color_Sectors(AnimationLooping, ledSettings[0].leds, ledSettings[0].size, tripple_colorPacks[AnimEvent.AnimationIndex - 114], WITH_GAPS, 2, 40, 90);
|
Anim_Color_Sectors(AnimationLooping, ledSettings[0].leds, ledSettings[0].size, tripple_colorPacks[AnimEvent.AnimationIndex - 114], WITH_GAPS, 2, 40, 90);
|
||||||
break;
|
break;
|
||||||
default:
|
}
|
||||||
|
default:{
|
||||||
ESP_LOGW(tag, "Loop default");
|
ESP_LOGW(tag, "Loop default");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
AnimationLooping = false;
|
AnimationLooping = false;
|
||||||
prevAnimEvent = AnimEvent;
|
prevAnimEvent = AnimEvent;
|
||||||
@ -643,7 +571,7 @@ void RGB_Lights_Control_Task(void *parameters){
|
|||||||
ledSettings[0].shift = AnimEvent.data.data[0];
|
ledSettings[0].shift = AnimEvent.data.data[0];
|
||||||
|
|
||||||
ESP_LOGD(tag, "Set Shift: %d", ledSettings[0].shift);
|
ESP_LOGD(tag, "Set Shift: %d", ledSettings[0].shift);
|
||||||
vTaskDelay(25 / portTICK_PERIOD_MS);
|
vTaskDelay(pdMS_TO_TICKS(25));
|
||||||
setPixel1(ledSettings[0], 0, CRGB::White);
|
setPixel1(ledSettings[0], 0, CRGB::White);
|
||||||
|
|
||||||
FastLED.show();
|
FastLED.show();
|
||||||
@ -666,15 +594,25 @@ void RGB_Lights_Control_Task(void *parameters){
|
|||||||
FastLED.show();
|
FastLED.show();
|
||||||
break;
|
break;
|
||||||
case 1 ... 5: { // Timed Fill Animations
|
case 1 ... 5: { // Timed Fill Animations
|
||||||
int timeDuration = AnimEvent.AnimationIndex * 1000 - 400;
|
float tempMax = -1;
|
||||||
|
if(AnimEvent.AnimationIndex == 1 && sys_settings.rampLightSettings[0].max > 70.0) {
|
||||||
|
tempMax = sys_settings.rampLightSettings[0].max; // preserve user setting if higher than 70
|
||||||
|
sys_settings.rampLightSettings[0].max = 70.0;
|
||||||
|
}
|
||||||
|
int timeDuration = (AnimEvent.AnimationIndex * 1000) - 100;
|
||||||
int whiteDelay = timeDuration - 1000;
|
int whiteDelay = timeDuration - 1000;
|
||||||
if (whiteDelay < 800) whiteDelay = 800; // minimum 8 seconds
|
if (whiteDelay < 0) whiteDelay = 0;
|
||||||
Anim_TimedFill_Flash(AnimationLooping, ledSettings[0].leds, ledSettings[0].size, pwmOutputs[0], &sys_settings.pwmOutSettings[0], whiteDelay, 10000, CRGB::Black, CRGB::White, timeDuration, ledSettings[0].shift);
|
Anim_TimedFill_Flash(AnimationLooping, ledSettings[0].leds, ledSettings[0].size, pwmOutputs[sys_settings.rampLightSettings[0].pwmOutIndex], &sys_settings.rampLightSettings[0], whiteDelay, 20000, CRGB::Black, CRGB(CRGB::White).nscale8(180), timeDuration, ledSettings[0].shift);
|
||||||
|
|
||||||
|
// restore ramp light max if it was changed
|
||||||
|
if(tempMax > 0){
|
||||||
|
sys_settings.rampLightSettings[0].max = tempMax; // restore user setting
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 6:
|
case 6:
|
||||||
// RGB White and Dedicated White all on with timeout and brightness reduction
|
// RGB White and Dedicated White all on with timeout and brightness reduction
|
||||||
Anim_SolidWhite(AnimationLooping, ledSettings[0].leds, pwmOutputs[0], ledSettings[0].size, 240, 30000);
|
Anim_SolidWhite(AnimationLooping, ledSettings[0].leds, pwmOutputs[sys_settings.rampLightSettings[0].pwmOutIndex], ledSettings[0].size, 240, 30000);
|
||||||
break;
|
break;
|
||||||
case 7:
|
case 7:
|
||||||
Anim_Rainbow(AnimationLooping, ledSettings[0].leds, ledSettings[0].size, 60);
|
Anim_Rainbow(AnimationLooping, ledSettings[0].leds, ledSettings[0].size, 60);
|
||||||
@ -766,7 +704,6 @@ void RGB_Lights_Control_Task(void *parameters){
|
|||||||
|
|
||||||
|
|
||||||
void SetAndSaveUserSettings(USER_SETTINGS &userSettings) {
|
void SetAndSaveUserSettings(USER_SETTINGS &userSettings) {
|
||||||
|
|
||||||
// Apply the settings to sys_settings
|
// Apply the settings to sys_settings
|
||||||
sys_settings.limitedMode = userSettings.limitedMode;
|
sys_settings.limitedMode = userSettings.limitedMode;
|
||||||
|
|
||||||
|
|||||||
@ -14,12 +14,15 @@
|
|||||||
|
|
||||||
static const char* tag = "anims";
|
static const char* tag = "anims";
|
||||||
|
|
||||||
typedef struct{
|
//typedef struct{
|
||||||
float minSpeed;
|
// float minSpeed;
|
||||||
float maxSpeed;
|
// float maxSpeed;
|
||||||
int rampCycles;
|
// int rampCycles;
|
||||||
}SPEED_PROPERTIES;
|
//}SPEED_PROPERTIES;
|
||||||
|
|
||||||
|
ANIM_FIRE fireSettings; // = { FIRE_COOLING, FIRE_SPARKING, FIRE_brightness };
|
||||||
|
ANIM_COMET cometSettings; // = { 30, 20, 0.2f, 4, 1 }; // Use 0 instead of 0.2 for integer field
|
||||||
|
ANIM_SNAKES snakeSettings; // = { 30, 4, 1 };
|
||||||
|
|
||||||
void Animation_Init(void){
|
void Animation_Init(void){
|
||||||
// Create Palettes
|
// Create Palettes
|
||||||
@ -482,9 +485,6 @@ void Anim_Rainbow(bool volatile& activeFlag, CRGB* leds, int size, int speed){
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Fire parameters (adjustable)
|
// Fire parameters (adjustable)
|
||||||
const uint8_t FIRE_COOLING = 66;
|
|
||||||
const uint8_t FIRE_SPARKING = 55;
|
|
||||||
const uint8_t FIRE_brightness = 240;
|
|
||||||
|
|
||||||
void Anim_Fire(bool volatile& activeFlag, CRGB* leds, int size, int speed, const CRGBPalette16& firePalette, int shift = 0) {
|
void Anim_Fire(bool volatile& activeFlag, CRGB* leds, int size, int speed, const CRGBPalette16& firePalette, int shift = 0) {
|
||||||
if (!leds || size <= 0) return;
|
if (!leds || size <= 0) return;
|
||||||
@ -504,7 +504,7 @@ void Anim_Fire(bool volatile& activeFlag, CRGB* leds, int size, int speed, const
|
|||||||
Animation_Loop(activeFlag, speed, [&]() -> int {
|
Animation_Loop(activeFlag, speed, [&]() -> int {
|
||||||
// Random cooling
|
// Random cooling
|
||||||
for(int i = 0; i < halfSize; i++) {
|
for(int i = 0; i < halfSize; i++) {
|
||||||
heat[i] = qsub8(heat[i], random8(0, ((FIRE_COOLING * 10) / halfSize) + 2));
|
heat[i] = qsub8(heat[i], random8(0, ((fireSettings.cooling * 10) / halfSize) + 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Heat rises and diffuses
|
// Heat rises and diffuses
|
||||||
@ -513,7 +513,7 @@ void Anim_Fire(bool volatile& activeFlag, CRGB* leds, int size, int speed, const
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Randomly ignite new sparks at bottom
|
// Randomly ignite new sparks at bottom
|
||||||
if(random8() < FIRE_SPARKING) {
|
if(random8() < fireSettings.sparking) {
|
||||||
// ensure y is in-bounds for small strips
|
// ensure y is in-bounds for small strips
|
||||||
y = min<int>(random8(7), halfSize - 1);
|
y = min<int>(random8(7), halfSize - 1);
|
||||||
heat[y] = qadd8(heat[y], random8(160, 240));
|
heat[y] = qadd8(heat[y], random8(160, 240));
|
||||||
@ -522,7 +522,7 @@ void Anim_Fire(bool volatile& activeFlag, CRGB* leds, int size, int speed, const
|
|||||||
// Map heat to colors with mirroring and shifting
|
// Map heat to colors with mirroring and shifting
|
||||||
for(int j = 0; j < halfSize; j++) {
|
for(int j = 0; j < halfSize; j++) {
|
||||||
colorindex = scale8(heat[j], 240);
|
colorindex = scale8(heat[j], 240);
|
||||||
color = ColorFromPalette(firePalette, colorindex, FIRE_brightness, LINEARBLEND);
|
color = ColorFromPalette(firePalette, colorindex, fireSettings.brightness, LINEARBLEND);
|
||||||
|
|
||||||
// Apply shift and wrap around
|
// Apply shift and wrap around
|
||||||
pos1 = (j + shift + size) % size;
|
pos1 = (j + shift + size) % size;
|
||||||
@ -639,8 +639,9 @@ void Anim_Color_Sectors(bool volatile& activeFlag, CRGB* leds, int size, const C
|
|||||||
/********************************************************************************
|
/********************************************************************************
|
||||||
* Comets Animation
|
* Comets Animation
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
#define COMET_SIZE_FACTOR 0.2
|
#define COMET_SIZE_FACTOR 0.2
|
||||||
#define COMET_FADE_FACTOR1 32 /* longer tail */
|
#define COMET_FADE_FACTOR1 16 /* longer tail */
|
||||||
#define COMET_FADE_FACTOR2 192 /* shorter tail */
|
#define COMET_FADE_FACTOR2 192 /* shorter tail */
|
||||||
//#define COMET_FADE_FACTOR COMET_FADE_FACTOR2
|
//#define COMET_FADE_FACTOR COMET_FADE_FACTOR2
|
||||||
#define MAX_COMETS 8 // Maximum number of comets supported
|
#define MAX_COMETS 8 // Maximum number of comets supported
|
||||||
@ -927,7 +928,7 @@ void Anim_TimedFill(bool volatile& activeFlag, CRGB* leds, int size, CRGB baseCo
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Anim_TimedFill_Flash(bool volatile& activeFlag, CRGB* leds, int size, PWM_Output* pwmOut, PWM_OUT_SETTINGS* pwmSettings, int pwmOutDelay, int flashTimeout, CRGB baseCol, CRGB fillCol, int totalDurationMs, int shift)
|
void Anim_TimedFill_Flash(bool volatile& activeFlag, CRGB* leds, int size, PWM_Output* pwmOut, RAMP_LIGHT_SETTINGS* pwmSettings, int pwmOutDelay, int flashTimeout, CRGB baseCol, CRGB fillCol, int totalDurationMs, int shift)
|
||||||
{
|
{
|
||||||
if (!leds || size <= 1 || totalDurationMs <= 0 || !pwmOut || !pwmSettings) return;
|
if (!leds || size <= 1 || totalDurationMs <= 0 || !pwmOut || !pwmSettings) return;
|
||||||
|
|
||||||
@ -996,6 +997,7 @@ void Anim_TimedFill_Flash(bool volatile& activeFlag, CRGB* leds, int size, PWM_O
|
|||||||
pwmOut->setOutput(pwmValue);
|
pwmOut->setOutput(pwmValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Phase 2: Animation complete, start flash timeout
|
// Phase 2: Animation complete, start flash timeout
|
||||||
else if (!flashTimeoutStarted) {
|
else if (!flashTimeoutStarted) {
|
||||||
flashTimeoutStarted = true;
|
flashTimeoutStarted = true;
|
||||||
@ -1214,12 +1216,13 @@ void Anim_TheaterChase(bool volatile& activeFlag, CRGB* leds, int size, const CO
|
|||||||
|
|
||||||
|
|
||||||
#define SNAKE_CYCLES_PER_ROTATION 4
|
#define SNAKE_CYCLES_PER_ROTATION 4
|
||||||
|
#define MAX_SNAKES 32
|
||||||
|
|
||||||
void Anim_Snakes(bool volatile& activeFlag, CRGB* leds, int size, const COLOR_PACK& colorPack, int speed , int multiplier) {
|
void Anim_Snakes(bool volatile& activeFlag, CRGB* leds, int size, const COLOR_PACK& colorPack, int speed , int multiplier) {
|
||||||
if (!leds || size <= 0 || colorPack.size <= 0 || multiplier <= 0) return;
|
if (!leds || size <= 0 || colorPack.size <= 0 || multiplier <= 0) return;
|
||||||
|
|
||||||
// Determine number of snakes (colors * multiplier), cap to a safe maximum
|
// Determine number of snakes (colors * multiplier), cap to a safe maximum
|
||||||
const int USER_NUM = colorPack.size * multiplier;
|
const int USER_NUM = colorPack.size * multiplier;
|
||||||
const int MAX_SNAKES = 32;
|
|
||||||
int numSnakes = USER_NUM;
|
int numSnakes = USER_NUM;
|
||||||
if (numSnakes > MAX_SNAKES) numSnakes = MAX_SNAKES;
|
if (numSnakes > MAX_SNAKES) numSnakes = MAX_SNAKES;
|
||||||
if (numSnakes <= 0) return;
|
if (numSnakes <= 0) return;
|
||||||
@ -1369,7 +1372,7 @@ void Anim_Birds(bool volatile& activeFlag, CRGB* leds, int size, const COLOR_PAC
|
|||||||
|
|
||||||
// Determine number of snakes (colors * multiplier), cap to a safe maximum
|
// Determine number of snakes (colors * multiplier), cap to a safe maximum
|
||||||
const int USER_NUM = colorPack.size * multiplier;
|
const int USER_NUM = colorPack.size * multiplier;
|
||||||
const int MAX_SNAKES = 32;
|
//const int MAX_SNAKES = 32;
|
||||||
int numSnakes = USER_NUM;
|
int numSnakes = USER_NUM;
|
||||||
if (numSnakes > MAX_SNAKES) numSnakes = MAX_SNAKES;
|
if (numSnakes > MAX_SNAKES) numSnakes = MAX_SNAKES;
|
||||||
if (numSnakes <= 0) return;
|
if (numSnakes <= 0) return;
|
||||||
|
|||||||
@ -909,7 +909,7 @@ void startFirmwareUpdateTask(AsyncEventSource* evProg) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Create task with higher priority (3) and optimized stack size
|
// Create task with higher priority (3) and optimized stack size
|
||||||
xTaskCreate(firmwareUpdateTask, "FirmwareUpdate", 1024*6, NULL, 3, &Update_Task_Handle);
|
xTaskCreate(firmwareUpdateTask, "FirmwareUpdate", 1024*8, NULL, 3, &Update_Task_Handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
void firmwareUpdateTask(void* parameter) {
|
void firmwareUpdateTask(void* parameter) {
|
||||||
|
|||||||
@ -70,7 +70,6 @@ void PWM_Output::setOutput(float duty){
|
|||||||
this->currDuty = duty;
|
this->currDuty = duty;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PWM_Output::setFreq(uint32_t fq){
|
void PWM_Output::setFreq(uint32_t fq){
|
||||||
uint32_t newFreq;
|
uint32_t newFreq;
|
||||||
if(this->freq != fq){
|
if(this->freq != fq){
|
||||||
|
|||||||
@ -14,7 +14,6 @@ RAMP_LIGHT::RAMP_LIGHT(OneButton* button, PWM_Output* pwmOutput, float min, floa
|
|||||||
button->attachLongPressStop([](void* context) { static_cast<RAMP_LIGHT*>(context)->longPressStop(); }, this);
|
button->attachLongPressStop([](void* context) { static_cast<RAMP_LIGHT*>(context)->longPressStop(); }, this);
|
||||||
button->attachDuringLongPress([](void* context) { static_cast<RAMP_LIGHT*>(context)->duringLongPress(); }, this);
|
button->attachDuringLongPress([](void* context) { static_cast<RAMP_LIGHT*>(context)->duringLongPress(); }, this);
|
||||||
|
|
||||||
|
|
||||||
if(min < 0.0) this->min = 0.0;
|
if(min < 0.0) this->min = 0.0;
|
||||||
if(max > 100.0) this->max = 100.0;
|
if(max > 100.0) this->max = 100.0;
|
||||||
if(this->max < this->min) this->max = this->min;
|
if(this->max < this->min) this->max = this->min;
|
||||||
|
|||||||
@ -53,10 +53,9 @@ void printTaskInfo(TaskStatus_t taskStatus) {
|
|||||||
uint32_t ulTotalRunTime = taskStatus.ulRunTimeCounter;
|
uint32_t ulTotalRunTime = taskStatus.ulRunTimeCounter;
|
||||||
uint32_t ulStatsAsPercentage = (ulTotalRunTime * 100) / ulTotalRunTime; // Total runtime equals 100%
|
uint32_t ulStatsAsPercentage = (ulTotalRunTime * 100) / ulTotalRunTime; // Total runtime equals 100%
|
||||||
|
|
||||||
ESP_LOGI(tag, "TaskInfo: %s\t%u\t%u\t%u\t%u%%",
|
ESP_LOGI(tag, "TaskInfo: %s\t%u\t%u\t%u%%",
|
||||||
taskStatus.pcTaskName,
|
taskStatus.pcTaskName,
|
||||||
taskStatus.uxCurrentPriority,
|
taskStatus.uxCurrentPriority,
|
||||||
taskStatus.xCoreID,
|
|
||||||
configMINIMAL_STACK_SIZE - taskStatus.usStackHighWaterMark,
|
configMINIMAL_STACK_SIZE - taskStatus.usStackHighWaterMark,
|
||||||
ulStatsAsPercentage);
|
ulStatsAsPercentage);
|
||||||
}
|
}
|
||||||
|
|||||||
149
src/main.cpp
149
src/main.cpp
@ -70,19 +70,16 @@ static const char *tag = "main";
|
|||||||
|
|
||||||
// Timer handles for periodic tasks
|
// Timer handles for periodic tasks
|
||||||
TimerHandle_t buttonScanTimer = NULL;
|
TimerHandle_t buttonScanTimer = NULL;
|
||||||
#define buttonScanInterval 10 // ms
|
|
||||||
|
|
||||||
TimerHandle_t temperatureTimer = NULL;
|
TimerHandle_t temperatureTimer = NULL;
|
||||||
TimerHandle_t statusLedTimer = NULL;
|
TimerHandle_t statusLedTimer = NULL;
|
||||||
#define statusLedInterval 500 // ms
|
|
||||||
|
|
||||||
TimerHandle_t upgradeHeartbeatTimer = NULL;
|
TimerHandle_t upgradeHeartbeatTimer = NULL;
|
||||||
#define upgradeHeartbeatInterval 5000 // ms
|
|
||||||
|
|
||||||
TimerHandle_t diagnosticsTimer = NULL;
|
TimerHandle_t diagnosticsTimer = NULL;
|
||||||
#define diagnosticsInterval 60000 // ms
|
|
||||||
|
|
||||||
TimerHandle_t analogInputTimer = NULL;
|
TimerHandle_t analogInputTimer = NULL;
|
||||||
|
|
||||||
|
#define buttonScanInterval 5 // ms
|
||||||
|
#define statusLedInterval 500 // ms
|
||||||
|
#define upgradeHeartbeatInterval 5000 // ms
|
||||||
|
#define diagnosticsInterval 60000 // ms
|
||||||
#define analogInputInterval 3000 // ms
|
#define analogInputInterval 3000 // ms
|
||||||
|
|
||||||
|
|
||||||
@ -91,11 +88,27 @@ void setupLogLevels(esp_log_level_t logLevel);
|
|||||||
|
|
||||||
// Timer callback functions
|
// Timer callback functions
|
||||||
void ButtonScanCallback(TimerHandle_t xTimer) {
|
void ButtonScanCallback(TimerHandle_t xTimer) {
|
||||||
for (int i = 0; i < 3; i++) {
|
static int btnIndex = 0;
|
||||||
if (boardButtons[i] != NULL) {
|
|
||||||
boardButtons[i]->tick();
|
switch(btnIndex){
|
||||||
|
case 0:
|
||||||
|
if (boardButtons[0] != NULL) {
|
||||||
|
boardButtons[0]->tick();
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
if (boardButtons[1] != NULL) {
|
||||||
|
boardButtons[1]->tick();
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
if (boardButtons[2] != NULL) {
|
||||||
|
boardButtons[2]->tick();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
btnIndex = (btnIndex + 1) % 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TemperatureCallback(TimerHandle_t xTimer) {
|
void TemperatureCallback(TimerHandle_t xTimer) {
|
||||||
@ -142,9 +155,8 @@ void checkLEDCChannels()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define Button1Pin 8
|
//#define Button1Pin 8
|
||||||
void setup()
|
void setup(){
|
||||||
{
|
|
||||||
bool UpgradeMode = false;
|
bool UpgradeMode = false;
|
||||||
|
|
||||||
// Serial Port
|
// Serial Port
|
||||||
@ -157,31 +169,41 @@ void setup()
|
|||||||
sys_settings.ledStripSettings[0] = &ledSettings[0];
|
sys_settings.ledStripSettings[0] = &ledSettings[0];
|
||||||
sys_settings.ledStripSettings[1] = &ledSettings[1];
|
sys_settings.ledStripSettings[1] = &ledSettings[1];
|
||||||
|
|
||||||
// Set Logging Levels
|
|
||||||
// esp_log_level_t logLevel = ESP_LOG_INFO;
|
|
||||||
// pinMode(Button1Pin, INPUT); // Button1
|
|
||||||
// if(!digitalRead(Button1Pin)){
|
|
||||||
// logLevel = ESP_LOG_VERBOSE;
|
|
||||||
//}
|
|
||||||
// setupLogLevels(logLevel);
|
|
||||||
setupLogLevels(ESP_LOG_INFO);
|
|
||||||
|
|
||||||
// chip id, mac,
|
|
||||||
print_chip_info();
|
|
||||||
|
|
||||||
// Init LittleFS
|
// Init LittleFS
|
||||||
Init_File_System();
|
Init_File_System();
|
||||||
|
|
||||||
// Print all system files
|
|
||||||
if (digitalRead(sys_settings.boardPins.btn[1]) == LOW){
|
|
||||||
printAllSystemFiles();
|
|
||||||
}
|
|
||||||
|
|
||||||
String board_file_path;
|
String board_file_path;
|
||||||
Get_Board_and_Booth_File_Paths("/system/system.json", board_file_path, booth_file_path);
|
Get_Board_and_Booth_File_Paths("/system/system.json", board_file_path, booth_file_path);
|
||||||
|
|
||||||
// Load Board Pins
|
// Load Board Pins
|
||||||
Load_Board_Pins(sys_settings.boardPins, board_file_path);
|
Load_Board_Pins(sys_settings.boardPins, board_file_path);
|
||||||
|
esp_log_level_t logLevel = ESP_LOG_INFO;
|
||||||
|
if (digitalRead(sys_settings.boardPins.btn[1]) == LOW) {
|
||||||
|
logLevel = ESP_LOG_DEBUG;
|
||||||
|
}
|
||||||
|
|
||||||
|
Serial.print("Log Level: ");
|
||||||
|
Serial.print(logLevel);
|
||||||
|
Serial.print(" (");
|
||||||
|
switch (logLevel) {
|
||||||
|
case ESP_LOG_NONE: Serial.print("NONE"); break;
|
||||||
|
case ESP_LOG_ERROR: Serial.print("1-ERROR"); break;
|
||||||
|
case ESP_LOG_WARN: Serial.print("2-WARN"); break;
|
||||||
|
case ESP_LOG_INFO: Serial.print("3-INFO"); break;
|
||||||
|
case ESP_LOG_DEBUG: Serial.print("4-DEBUG"); break;
|
||||||
|
case ESP_LOG_VERBOSE: Serial.print("5-VERBOSE"); break;
|
||||||
|
default: Serial.print("UNKNOWN"); break;
|
||||||
|
}
|
||||||
|
Serial.println(")");
|
||||||
|
setupLogLevels(logLevel);
|
||||||
|
|
||||||
|
// chip id, mac,
|
||||||
|
print_chip_info();
|
||||||
|
|
||||||
|
// Print all system files
|
||||||
|
if (digitalRead(sys_settings.boardPins.btn[1]) == LOW){
|
||||||
|
printAllSystemFiles();
|
||||||
|
}
|
||||||
|
|
||||||
// Set status pins off
|
// Set status pins off
|
||||||
setStatusPin1(false);
|
setStatusPin1(false);
|
||||||
@ -229,7 +251,7 @@ void setup()
|
|||||||
upgradeHeartbeatTimer = xTimerCreate("UpgradeHeartbeat", pdMS_TO_TICKS(5000), pdTRUE, NULL, UpgradeHeartbeatCallback);
|
upgradeHeartbeatTimer = xTimerCreate("UpgradeHeartbeat", pdMS_TO_TICKS(5000), pdTRUE, NULL, UpgradeHeartbeatCallback);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ESP_LOGI(tag, "Enabling BLE, No Update Service");
|
ESP_LOGW(tag, "Enabling BLE, No Update Service");
|
||||||
Init_BleServer(true, false); // Dont start the Upgrade service
|
Init_BleServer(true, false); // Dont start the Upgrade service
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -259,11 +281,11 @@ void setup()
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Start the timers
|
// Start the timers
|
||||||
//if (buttonScanTimer) xTimerStart(buttonScanTimer, 100);
|
if (buttonScanTimer) xTimerStart(buttonScanTimer, 200);
|
||||||
if (temperatureTimer && sys_settings.tSensorSettings.enabled) xTimerStart(temperatureTimer, 100);
|
if (temperatureTimer && sys_settings.tSensorSettings.enabled) xTimerStart(temperatureTimer, 500);
|
||||||
if (statusLedTimer) xTimerStart(statusLedTimer, 0);
|
if (statusLedTimer) xTimerStart(statusLedTimer, 100);
|
||||||
if (upgradeHeartbeatTimer && UpgradeMode) xTimerStart(upgradeHeartbeatTimer, upgradeHeartbeatInterval);
|
if (upgradeHeartbeatTimer && UpgradeMode) xTimerStart(upgradeHeartbeatTimer, upgradeHeartbeatInterval);
|
||||||
if (analogInputTimer) xTimerStart(analogInputTimer, 0);
|
if (analogInputTimer) xTimerStart(analogInputTimer, 150);
|
||||||
|
|
||||||
#if FREERTOS_DIAGNOSTICS
|
#if FREERTOS_DIAGNOSTICS
|
||||||
if (diagnosticsTimer) xTimerStart(diagnosticsTimer, diagnosticsInterval);
|
if (diagnosticsTimer) xTimerStart(diagnosticsTimer, diagnosticsInterval);
|
||||||
@ -281,61 +303,11 @@ void setup()
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void loop()
|
void loop(){
|
||||||
{
|
|
||||||
// Animation TestMode Timeout (keep in loop as it's event-driven)
|
|
||||||
#if LEDS_ENABLED
|
|
||||||
if (animStatus.EventTestCountdown)
|
|
||||||
{
|
|
||||||
if (--animStatus.EventTestCountdown == 0)
|
|
||||||
{
|
|
||||||
ESP_LOGD(tag, "Test Timeout trigger");
|
|
||||||
PostLastNormalEvent();
|
|
||||||
if (Strip1_Task_Handle)
|
|
||||||
{
|
|
||||||
xTaskNotifyGive(Strip1_Task_Handle);
|
|
||||||
} // trigger exit of animation loop
|
|
||||||
}
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Reboot requested (keep in loop as it's a state-based countdown)
|
|
||||||
#if WIFI_ENABLED
|
|
||||||
if (RebootSystem)
|
|
||||||
{
|
|
||||||
if (--RebootSystem == 0)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < 3; i++)
|
|
||||||
{
|
|
||||||
#if BUZZER_ENABLED
|
|
||||||
Buzzer_Play_Tune(TUNE_LOWEEP); // blocking
|
|
||||||
#endif
|
|
||||||
vTaskDelay(200);
|
|
||||||
}
|
|
||||||
ESP_LOGW(tag, "Restarting...");
|
|
||||||
vTaskDelay(200);
|
|
||||||
ESP.restart();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
for (int i = 0; i < 3; i++) {
|
|
||||||
if (boardButtons[i] != NULL) {
|
|
||||||
boardButtons[i]->tick();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
vTaskDelay(buttonScanInterval);
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Small delay to prevent busy-waiting
|
|
||||||
//vTaskDelay(pdMS_TO_TICKS(100));
|
|
||||||
|
|
||||||
vTaskDelay(portMAX_DELAY);
|
vTaskDelay(portMAX_DELAY);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setupLogLevels(esp_log_level_t logLevel)
|
void setupLogLevels(esp_log_level_t logLevel){
|
||||||
{
|
|
||||||
// Options: ESP_LOG_ERROR,ESP_LOG_WARN,ESP_LOG_INFO,ESP_LOG_DEBUG,ESP_LOG_VERBOSE
|
// Options: ESP_LOG_ERROR,ESP_LOG_WARN,ESP_LOG_INFO,ESP_LOG_DEBUG,ESP_LOG_VERBOSE
|
||||||
esp_log_level_set("*", logLevel);
|
esp_log_level_set("*", logLevel);
|
||||||
esp_log_level_set("fs", logLevel);
|
esp_log_level_set("fs", logLevel);
|
||||||
@ -353,6 +325,7 @@ void setupLogLevels(esp_log_level_t logLevel)
|
|||||||
esp_log_level_set("oled", logLevel);
|
esp_log_level_set("oled", logLevel);
|
||||||
esp_log_level_set("trx433", logLevel);
|
esp_log_level_set("trx433", logLevel);
|
||||||
esp_log_level_set("tsensor", logLevel);
|
esp_log_level_set("tsensor", logLevel);
|
||||||
|
esp_log_level_set("my_device", logLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -81,24 +81,33 @@ bool Load_Board_Pins(BOARD_PINS &boardPins, const String &path) {
|
|||||||
auto clampPin = [](int v) { return isValidGpio(v) ? v : -1; };
|
auto clampPin = [](int v) { return isValidGpio(v) ? v : -1; };
|
||||||
boardPins.rgb1 = clampPin(boardPins.rgb1);
|
boardPins.rgb1 = clampPin(boardPins.rgb1);
|
||||||
boardPins.rgb2 = clampPin(boardPins.rgb2);
|
boardPins.rgb2 = clampPin(boardPins.rgb2);
|
||||||
|
|
||||||
for (int i = 0; i < 3; i++)
|
for (int i = 0; i < 3; i++)
|
||||||
boardPins.btn[i] = clampPin(boardPins.btn[i]);
|
boardPins.btn[i] = clampPin(boardPins.btn[i]);
|
||||||
|
|
||||||
boardPins.buzzer = clampPin(boardPins.buzzer);
|
boardPins.buzzer = clampPin(boardPins.buzzer);
|
||||||
|
|
||||||
for (int i = 0; i < 5; i++)
|
for (int i = 0; i < 5; i++)
|
||||||
boardPins.touch[i] = clampPin(boardPins.touch[i]);
|
boardPins.touch[i] = clampPin(boardPins.touch[i]);
|
||||||
|
|
||||||
boardPins.shield = clampPin(boardPins.shield);
|
boardPins.shield = clampPin(boardPins.shield);
|
||||||
|
|
||||||
for (int i = 0; i < 4; i++)
|
for (int i = 0; i < 4; i++)
|
||||||
boardPins.relay[i] = clampPin(boardPins.relay[i]);
|
boardPins.relay[i] = clampPin(boardPins.relay[i]);
|
||||||
|
|
||||||
for (int i = 0; i < 2; i++)
|
for (int i = 0; i < 2; i++)
|
||||||
boardPins.stat[i] = clampPin(boardPins.stat[i]);
|
boardPins.stat[i] = clampPin(boardPins.stat[i]);
|
||||||
|
|
||||||
boardPins.adc1 = clampPin(boardPins.adc1);
|
boardPins.adc1 = clampPin(boardPins.adc1);
|
||||||
boardPins.oled_dc = clampPin(boardPins.oled_dc);
|
boardPins.oled_dc = clampPin(boardPins.oled_dc);
|
||||||
boardPins.oled_rst = clampPin(boardPins.oled_rst);
|
boardPins.oled_rst = clampPin(boardPins.oled_rst);
|
||||||
boardPins.oled_mosi = clampPin(boardPins.oled_mosi);
|
boardPins.oled_mosi = clampPin(boardPins.oled_mosi);
|
||||||
boardPins.oled_sck = clampPin(boardPins.oled_sck);
|
boardPins.oled_sck = clampPin(boardPins.oled_sck);
|
||||||
boardPins.oled_cs = clampPin(boardPins.oled_cs);
|
boardPins.oled_cs = clampPin(boardPins.oled_cs);
|
||||||
|
|
||||||
for (int i = 0; i < 2; i++)
|
for (int i = 0; i < 2; i++)
|
||||||
boardPins.ext[i] = clampPin(boardPins.ext[i]);
|
boardPins.ext[i] = clampPin(boardPins.ext[i]);
|
||||||
|
|
||||||
boardPins.rf433tx = clampPin(boardPins.rf433tx);
|
boardPins.rf433tx = clampPin(boardPins.rf433tx);
|
||||||
boardPins.rf433rx = clampPin(boardPins.rf433rx);
|
boardPins.rf433rx = clampPin(boardPins.rf433rx);
|
||||||
|
|
||||||
@ -107,40 +116,17 @@ bool Load_Board_Pins(BOARD_PINS &boardPins, const String &path) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Init_Board_Basic(BOARD_PINS &boardPins) {
|
void Init_Board_Basic(BOARD_PINS &boardPins) {
|
||||||
|
if (boardPins.stat[0] >= 0) { pinMode(boardPins.stat[0], OUTPUT); }
|
||||||
if (boardPins.stat[0] >= 0) {
|
if (boardPins.stat[1] >= 0) { pinMode(boardPins.stat[1], OUTPUT); }
|
||||||
pinMode(boardPins.stat[0], OUTPUT);
|
if (boardPins.btn[0] >= 0) { pinMode(boardPins.btn[0], INPUT_PULLUP); }
|
||||||
}
|
if (boardPins.btn[1] >= 0) { pinMode(boardPins.btn[1], INPUT_PULLUP); }
|
||||||
if (boardPins.stat[1] >= 0) {
|
if (boardPins.btn[2] >= 0) { pinMode(boardPins.btn[2], INPUT); }
|
||||||
pinMode(boardPins.stat[1], OUTPUT);
|
if (boardPins.rgb1 >= 0) { pinMode(boardPins.rgb1, OUTPUT); }
|
||||||
}
|
if (boardPins.rgb2 >= 0) { pinMode(boardPins.rgb2, OUTPUT); }
|
||||||
if (boardPins.btn[0] >= 0) {
|
if (boardPins.relay[0] >= 0) { pinMode(boardPins.relay[0], OUTPUT); }
|
||||||
pinMode(boardPins.btn[0], INPUT_PULLUP);
|
if (boardPins.relay[1] >= 0) { pinMode(boardPins.relay[1], OUTPUT); }
|
||||||
}
|
if (boardPins.relay[2] >= 0) { pinMode(boardPins.relay[2], OUTPUT); }
|
||||||
if (boardPins.btn[1] >= 0) {
|
if (boardPins.relay[3] >= 0) { pinMode(boardPins.relay[3], OUTPUT); }
|
||||||
pinMode(boardPins.btn[1], INPUT_PULLUP);
|
|
||||||
}
|
|
||||||
if (boardPins.btn[2] >= 0) {
|
|
||||||
pinMode(boardPins.btn[2], INPUT);
|
|
||||||
}
|
|
||||||
if (boardPins.rgb1 >= 0) {
|
|
||||||
pinMode(boardPins.rgb1, OUTPUT);
|
|
||||||
}
|
|
||||||
if (boardPins.rgb2 >= 0) {
|
|
||||||
pinMode(boardPins.rgb2, OUTPUT);
|
|
||||||
}
|
|
||||||
if (boardPins.relay[0] >= 0) {
|
|
||||||
pinMode(boardPins.relay[0], OUTPUT);
|
|
||||||
}
|
|
||||||
if (boardPins.relay[1] >= 0) {
|
|
||||||
pinMode(boardPins.relay[1], OUTPUT);
|
|
||||||
}
|
|
||||||
if (boardPins.relay[2] >= 0) {
|
|
||||||
pinMode(boardPins.relay[2], OUTPUT);
|
|
||||||
}
|
|
||||||
if (boardPins.relay[3] >= 0) {
|
|
||||||
pinMode(boardPins.relay[3], OUTPUT);
|
|
||||||
}
|
|
||||||
|
|
||||||
ESP_LOGI(tag, "Board pins initialized...");
|
ESP_LOGI(tag, "Board pins initialized...");
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,57 +9,20 @@ OneButton *boardButtons[3] = { nullptr, nullptr, nullptr };
|
|||||||
|
|
||||||
void Init_ButtonEvents(int8_t (&pin)[3]){
|
void Init_ButtonEvents(int8_t (&pin)[3]){
|
||||||
// Initialize buttons if pins are valid and not already initialized
|
// Initialize buttons if pins are valid and not already initialized
|
||||||
if (pin[0] >= 0) {
|
for (int i = 0; i < 3; ++i) {
|
||||||
if (boardButtons[0] == nullptr) {
|
if (pin[i] >= 0) {
|
||||||
boardButtons[0] = new OneButton(pin[0], true, true);
|
if (boardButtons[i] == nullptr) {
|
||||||
ESP_LOGI(tag, "Button1 Events, pin=%d", pin[0]);
|
// For button 3 (index 2), set pullup to false, others true
|
||||||
|
bool pullup = (i == 2) ? false : true;
|
||||||
|
boardButtons[i] = new OneButton(pin[i], true, pullup);
|
||||||
|
ESP_LOGI(tag, "Button%d Events, pin=%d", i + 1, pin[i]);
|
||||||
} else {
|
} else {
|
||||||
ESP_LOGW(tag, "Button1 already initialized (pin=%d)", pin[0]);
|
ESP_LOGW(tag, "Button%d already initialized (pin=%d)", i + 1, pin[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (pin[1] >= 0) {
|
|
||||||
if (boardButtons[1] == nullptr) {
|
|
||||||
boardButtons[1] = new OneButton(pin[1], true, true);
|
|
||||||
ESP_LOGI(tag, "Button2 Events, pin=%d", pin[1]);
|
|
||||||
} else {
|
|
||||||
ESP_LOGW(tag, "Button2 already initialized (pin=%d)", pin[1]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (pin[2] >= 0) {
|
|
||||||
if (boardButtons[2] == nullptr) {
|
|
||||||
boardButtons[2] = new OneButton(pin[2], true, false);
|
|
||||||
ESP_LOGI(tag, "Button3 Events, pin=%d", pin[2]);
|
|
||||||
} else {
|
|
||||||
ESP_LOGW(tag, "Button3 already initialized (pin=%d)", pin[2]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
if(boardButtons[0] != NULL){
|
|
||||||
//boardButtons[0]->setDebounceTicks(DEBOUCE_TIME); // just below the update period to guarantee 1 sample delay
|
|
||||||
boardButtons[0]->attachClick(btn1_click);
|
|
||||||
boardButtons[0]->attachDoubleClick(btn1_doubleClick);
|
|
||||||
boardButtons[0]->attachLongPressStart(btn1_LongPressStart);
|
|
||||||
boardButtons[0]->attachLongPressStop(btn1_LongPressStop);
|
|
||||||
boardButtons[0]->attachDuringLongPress(btn1_DuringLongPress);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
ESP_LOGD(tag, "Button1 Not Initialized");
|
|
||||||
}
|
|
||||||
|
|
||||||
if(boardButtons[1] != NULL){
|
|
||||||
//boardButtons[1]->setDebounceTicks(DEBOUCE_TIME);
|
|
||||||
boardButtons[1]->attachClick(btn2_click);
|
|
||||||
boardButtons[1]->attachDoubleClick(btn2_doubleClick);
|
|
||||||
boardButtons[1]->attachLongPressStart(btn2_LongPressStart);
|
|
||||||
boardButtons[1]->attachLongPressStop(btn2_LongPressStop);
|
|
||||||
boardButtons[1]->attachDuringLongPress(btn2_DuringLongPress);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
ESP_LOGD(tag, "Button2 Not Initialized");
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
if(boardButtons[2] != NULL){
|
if(boardButtons[2] != NULL){
|
||||||
//boardButtons[2]->setDebounceTicks(DEBOUCE_TIME);
|
//boardButtons[2]->setDebounceTicks(DEBOUCE_TIME);
|
||||||
boardButtons[2]->attachClick(btn3_click);
|
boardButtons[2]->attachClick(btn3_click);
|
||||||
@ -72,17 +35,10 @@ void Init_ButtonEvents(int8_t (&pin)[3]){
|
|||||||
else {
|
else {
|
||||||
ESP_LOGW(tag, "Button3 Not Initialized");
|
ESP_LOGW(tag, "Button3 Not Initialized");
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Update_Buttons() {
|
|
||||||
for (int i = 0; i < 3; ++i) {
|
|
||||||
if (boardButtons[i] != nullptr) {
|
|
||||||
boardButtons[i]->tick();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void btn1_click() {
|
void btn1_click() {
|
||||||
//IncrementEventIndex();
|
//IncrementEventIndex();
|
||||||
//Pulse_LED_Status(150);
|
//Pulse_LED_Status(150);
|
||||||
@ -112,7 +68,7 @@ void btn2_click() {
|
|||||||
//Pulse_LED_Status(150);
|
//Pulse_LED_Status(150);
|
||||||
//Buzzer_Beep(150);
|
//Buzzer_Beep(150);
|
||||||
// send packet
|
// send packet
|
||||||
sendUpdateMessage("testing....", false, -1);
|
//sendUpdateMessage("testing....", false, -1);
|
||||||
ESP_LOGD(tag, "btn2 1x");
|
ESP_LOGD(tag, "btn2 1x");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -141,7 +97,7 @@ void btn3_click() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void btn3_doubleClick() {
|
void btn3_doubleClick() {
|
||||||
bleUpgrade_send_message("Hello....3");
|
//bleUpgrade_send_message("Hello....3");
|
||||||
ESP_LOGD(tag, "btn3 2x");
|
ESP_LOGD(tag, "btn3 2x");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -18,6 +18,7 @@
|
|||||||
#include <esp_system.h>
|
#include <esp_system.h>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include "Animations.h"
|
||||||
|
|
||||||
static const char *tag = "my_device";
|
static const char *tag = "my_device";
|
||||||
|
|
||||||
@ -33,8 +34,6 @@ float prevPowerVin = 0.0;
|
|||||||
float PowerVin = 0.0;
|
float PowerVin = 0.0;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// TODO Restore original setOutput code..
|
|
||||||
#define RELAY_RES 10
|
#define RELAY_RES 10
|
||||||
void Init_PWM_Outputs(int8_t (&pin)[4], PWM_OUT_SETTINGS (&pwmSettings)[4]) {
|
void Init_PWM_Outputs(int8_t (&pin)[4], PWM_OUT_SETTINGS (&pwmSettings)[4]) {
|
||||||
// Delete any existing objects to avoid leaks on re-init
|
// Delete any existing objects to avoid leaks on re-init
|
||||||
@ -51,36 +50,28 @@ void Init_PWM_Outputs(int8_t (&pin)[4], PWM_OUT_SETTINGS (&pwmSettings)[4]) {
|
|||||||
ESP_LOGE(tag, "No available LEDC channel for PWM Output%d", i);
|
ESP_LOGE(tag, "No available LEDC channel for PWM Output%d", i);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
pwmOutputs[i] = new PWM_Output(pin[i], chIndex, RELAY_RES, pwmSettings[i].freq,
|
pwmOutputs[i] = new PWM_Output(pin[i], chIndex, RELAY_RES, pwmSettings[i].freq, pwmSettings[i].max, false);
|
||||||
pwmSettings[i].max, false);
|
|
||||||
if (pwmOutputs[i]) {
|
if (pwmOutputs[i]) {
|
||||||
pwmOutputs[i]->setOutput(pwmSettings[i].def);
|
pwmOutputs[i]->setOutput(pwmSettings[i].def);
|
||||||
} else {
|
} else {
|
||||||
ESP_LOGE(tag, "Allocation failed for PWM Output%d", i);
|
ESP_LOGE(tag, "Allocation failed for PWM Output%d", i);
|
||||||
}
|
}
|
||||||
// pwmOutputs[i]->setOutput(5.0);
|
// pwmOutputs[i]->setOutput(5.0);
|
||||||
ESP_LOGI(tag, "PWM Output%d: Pin=%d, Freq=%d, ch=%d", i, pin[i], pwmSettings[i].freq,
|
ESP_LOGI(tag, "PWM Output%d: Pin=%d, Freq=%d, ch=%d", i, pin[i], pwmSettings[i].freq, chIndex);
|
||||||
chIndex);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Init_Ramp_Lights(RAMP_LIGHT_SETTINGS (&settings)[2], OneButton *(&btn)[3], PWM_Output *(&pwm)[4]) {
|
void Init_Ramp_Lights(RAMP_LIGHT_SETTINGS (&settings)[2], OneButton *(&btn)[3], PWM_Output *(&pwm)[4]) {
|
||||||
if (settings[0].enabled) {
|
RAMP_LIGHT **rampLights[2] = { &rampLight1, &rampLight2 };
|
||||||
if (rampLight1) { delete rampLight1; rampLight1 = nullptr; }
|
for (int i = 0; i < 2; ++i) {
|
||||||
rampLight1 = new RAMP_LIGHT(btn[settings[0].btnIndex], pwm[settings[0].pwmOutIndex], settings[0].min, settings[0].max, settings[0].step);
|
if (settings[i].enabled) {
|
||||||
if (rampLight1)
|
if (*(rampLights[i])) { delete *(rampLights[i]); *(rampLights[i]) = nullptr; }
|
||||||
ESP_LOGD(tag, "RampLight%d: btn=%d, pwmIndex=%d, min=%f, max=%f, step=%f", 1, settings[0].btnIndex, settings[0].pwmOutIndex, settings[0].min, settings[0].max, settings[0].step);
|
*(rampLights[i]) = new RAMP_LIGHT(btn[settings[i].btnIndex], pwm[settings[i].pwmOutIndex], settings[i].min, settings[i].max, settings[i].step);
|
||||||
|
if (*(rampLights[i]))
|
||||||
|
ESP_LOGI(tag, "RampLight%d: btn=%d, pwmIndex=%d, min=%f, max=%f, step=%f", i + 1, settings[i].btnIndex, settings[i].pwmOutIndex, settings[i].min, settings[i].max, settings[i].step);
|
||||||
else
|
else
|
||||||
ESP_LOGE(tag, "Failed to allocate RampLight1");
|
ESP_LOGE(tag, "Failed to allocate RampLight%d", i + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (settings[1].enabled) {
|
|
||||||
if (rampLight2) { delete rampLight2; rampLight2 = nullptr; }
|
|
||||||
rampLight2 = new RAMP_LIGHT(btn[settings[1].btnIndex], pwm[settings[1].pwmOutIndex], settings[1].min, settings[1].max, settings[1].step);
|
|
||||||
if (rampLight2)
|
|
||||||
ESP_LOGD(tag, "RampLight%d: btn=%d, pwmIndex=%d, min=%f, max=%f, step=%f", 2, settings[1].btnIndex, settings[1].pwmOutIndex, settings[1].min, settings[1].max, settings[1].step);
|
|
||||||
else
|
|
||||||
ESP_LOGE(tag, "Failed to allocate RampLight2");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -146,14 +137,10 @@ void Load_Booth_Settings(SYS_SETTINGS &sys, const String &boothPath) {
|
|||||||
sizeof(sys_settings.pwmOutSettings) / sizeof(sys_settings.pwmOutSettings[0]))
|
sizeof(sys_settings.pwmOutSettings) / sizeof(sys_settings.pwmOutSettings[0]))
|
||||||
break;
|
break;
|
||||||
sys_settings.pwmOutSettings[pwmIndex].enabled = jsonConstrainBool(tag, obj, "en", true);
|
sys_settings.pwmOutSettings[pwmIndex].enabled = jsonConstrainBool(tag, obj, "en", true);
|
||||||
sys_settings.pwmOutSettings[pwmIndex].freq =
|
sys_settings.pwmOutSettings[pwmIndex].freq = jsonConstrain<int>(tag, obj, "freq", 100, 5000, 250);
|
||||||
jsonConstrain<int>(tag, obj, "freq", 100, 5000, 250);
|
sys_settings.pwmOutSettings[pwmIndex].min = jsonConstrain<float>(tag, obj, "min", 0.0, 95.0, 0.0);
|
||||||
sys_settings.pwmOutSettings[pwmIndex].min =
|
sys_settings.pwmOutSettings[pwmIndex].max = jsonConstrain<float>(tag, obj, "max", 5.0, 100.0, 100.0);
|
||||||
jsonConstrain<float>(tag, obj, "min", 0.0, 95.0, 0.0);
|
sys_settings.pwmOutSettings[pwmIndex].def = jsonConstrain<float>(tag, obj, "default", 0.0, 100.0, 0.0);
|
||||||
sys_settings.pwmOutSettings[pwmIndex].max =
|
|
||||||
jsonConstrain<float>(tag, obj, "max", 5.0, 100.0, 100.0);
|
|
||||||
sys_settings.pwmOutSettings[pwmIndex].def =
|
|
||||||
jsonConstrain<float>(tag, obj, "default", 0.0, 100.0, 0.0);
|
|
||||||
sys_settings.pwmOutSettings[pwmIndex].deltaRate = 1.0;
|
sys_settings.pwmOutSettings[pwmIndex].deltaRate = 1.0;
|
||||||
// sys_settings.pwmOutSettings[pwmIndex]. = jsonConstrainBool(tag, obj, "vision", true);
|
// sys_settings.pwmOutSettings[pwmIndex]. = jsonConstrainBool(tag, obj, "vision", true);
|
||||||
pwmIndex++;
|
pwmIndex++;
|
||||||
@ -171,20 +158,13 @@ void Load_Booth_Settings(SYS_SETTINGS &sys, const String &boothPath) {
|
|||||||
if (rampIndex >=
|
if (rampIndex >=
|
||||||
sizeof(sys_settings.rampLightSettings) / sizeof(sys_settings.rampLightSettings[0]))
|
sizeof(sys_settings.rampLightSettings) / sizeof(sys_settings.rampLightSettings[0]))
|
||||||
break;
|
break;
|
||||||
sys_settings.rampLightSettings[rampIndex].enabled =
|
sys_settings.rampLightSettings[rampIndex].enabled = jsonConstrainBool(tag, obj, "en", true);
|
||||||
jsonConstrainBool(tag, obj, "en", true);
|
sys_settings.rampLightSettings[rampIndex].vision = jsonConstrainBool(tag, obj, "vision", true);
|
||||||
sys_settings.rampLightSettings[rampIndex].vision =
|
sys_settings.rampLightSettings[rampIndex].pwmOutIndex = jsonConstrain<int>(tag, obj, "relay-index", 0, 3, 0);
|
||||||
jsonConstrainBool(tag, obj, "vision", true);
|
sys_settings.rampLightSettings[rampIndex].btnIndex = jsonConstrain<int>(tag, obj, "button-index", 0, 2, 0);
|
||||||
sys_settings.rampLightSettings[rampIndex].pwmOutIndex =
|
sys_settings.rampLightSettings[rampIndex].min = jsonConstrain<float>(tag, obj, "min", 0.0, 95.0, 0.0);
|
||||||
jsonConstrain<int>(tag, obj, "relay-index", 0, 1, 0);
|
sys_settings.rampLightSettings[rampIndex].max = jsonConstrain<float>(tag, obj, "max", 5.0, 100.0, 100.0);
|
||||||
sys_settings.rampLightSettings[rampIndex].btnIndex =
|
sys_settings.rampLightSettings[rampIndex].step = jsonConstrain<float>(tag, obj, "step", 0.1, 10.0, 1.5);
|
||||||
jsonConstrain<int>(tag, obj, "button-index", 0, 1, 0);
|
|
||||||
sys_settings.rampLightSettings[rampIndex].min =
|
|
||||||
jsonConstrain<float>(tag, obj, "min", 0.0, 95.0, 0.0);
|
|
||||||
sys_settings.rampLightSettings[rampIndex].max =
|
|
||||||
jsonConstrain<float>(tag, obj, "max", 5.0, 100.0, 100.0);
|
|
||||||
sys_settings.rampLightSettings[rampIndex].step =
|
|
||||||
jsonConstrain<float>(tag, obj, "step", 0.1, 10.0, 1.5);
|
|
||||||
rampIndex++;
|
rampIndex++;
|
||||||
}
|
}
|
||||||
ESP_LOGI(tag, "Loaded Ramp Lights settings...");
|
ESP_LOGI(tag, "Loaded Ramp Lights settings...");
|
||||||
@ -196,20 +176,13 @@ void Load_Booth_Settings(SYS_SETTINGS &sys, const String &boothPath) {
|
|||||||
JsonObject sensorJson = doc["t-sensor"];
|
JsonObject sensorJson = doc["t-sensor"];
|
||||||
if (!sensorJson.isNull()) {
|
if (!sensorJson.isNull()) {
|
||||||
sys_settings.tSensorSettings.enabled = jsonConstrainBool(tag, sensorJson, "en", true);
|
sys_settings.tSensorSettings.enabled = jsonConstrainBool(tag, sensorJson, "en", true);
|
||||||
sys_settings.tSensorSettings.pwmIndex =
|
sys_settings.tSensorSettings.pwmIndex = jsonConstrain<int>(tag, sensorJson, "relay", 0, 3, 3);
|
||||||
jsonConstrain<int>(tag, sensorJson, "relay", 0, 3, 3);
|
sys_settings.tSensorSettings.setpoint1 = jsonConstrain<float>(tag, sensorJson, "sp1", 50.0, 100.0, 80.0);
|
||||||
sys_settings.tSensorSettings.setpoint1 =
|
sys_settings.tSensorSettings.setpoint2 = jsonConstrain<float>(tag, sensorJson, "sp2", 60.0, 110.0, 90.0);
|
||||||
jsonConstrain<float>(tag, sensorJson, "sp1", 50.0, 100.0, 80.0);
|
sys_settings.tSensorSettings.fanPower1 = jsonConstrain<float>(tag, sensorJson, "fan-pwr1", 0.0, 100.0, 50.0);
|
||||||
sys_settings.tSensorSettings.setpoint2 =
|
sys_settings.tSensorSettings.fanPower2 = jsonConstrain<float>(tag, sensorJson, "fan-pwr2", 50.0, 100.0, 50.0);
|
||||||
jsonConstrain<float>(tag, sensorJson, "sp2", 60.0, 110.0, 90.0);
|
sys_settings.tSensorSettings.hyst = jsonConstrain<float>(tag, sensorJson, "hyst", 1.0, 10.0, 1.0);
|
||||||
sys_settings.tSensorSettings.fanPower1 =
|
sys_settings.tSensorSettings.intervalMs = jsonConstrain<int>(tag, sensorJson, "interval", 1000, 30000, 5000);
|
||||||
jsonConstrain<float>(tag, sensorJson, "fan-pwr1", 0.0, 100.0, 50.0);
|
|
||||||
sys_settings.tSensorSettings.fanPower2 =
|
|
||||||
jsonConstrain<float>(tag, sensorJson, "fan-pwr2", 50.0, 100.0, 50.0);
|
|
||||||
sys_settings.tSensorSettings.hyst =
|
|
||||||
jsonConstrain<float>(tag, sensorJson, "hyst", 1.0, 10.0, 1.0);
|
|
||||||
sys_settings.tSensorSettings.intervalMs =
|
|
||||||
jsonConstrain<int>(tag, sensorJson, "interval", 1000, 30000, 5000);
|
|
||||||
ESP_LOGI(tag, "Loaded TSensor settings...");
|
ESP_LOGI(tag, "Loaded TSensor settings...");
|
||||||
ESP_LOGI(tag, " SP1: %F, SP2 %F, Hyst: %F", sys_settings.tSensorSettings.setpoint1,
|
ESP_LOGI(tag, " SP1: %F, SP2 %F, Hyst: %F", sys_settings.tSensorSettings.setpoint1,
|
||||||
sys_settings.tSensorSettings.setpoint2, sys_settings.tSensorSettings.hyst);
|
sys_settings.tSensorSettings.setpoint2, sys_settings.tSensorSettings.hyst);
|
||||||
@ -225,24 +198,16 @@ void Load_Booth_Settings(SYS_SETTINGS &sys, const String &boothPath) {
|
|||||||
if (stripIndex >= 2)
|
if (stripIndex >= 2)
|
||||||
break;
|
break;
|
||||||
if (sys_settings.ledStripSettings[stripIndex]) {
|
if (sys_settings.ledStripSettings[stripIndex]) {
|
||||||
sys_settings.ledStripSettings[stripIndex]->enabled =
|
sys_settings.ledStripSettings[stripIndex]->enabled = jsonConstrainBool(tag, obj, "en", true);
|
||||||
jsonConstrainBool(tag, obj, "en", true);
|
sys_settings.ledStripSettings[stripIndex]->size = jsonConstrain<int>(tag, obj, "size", 1, 250, 25);
|
||||||
sys_settings.ledStripSettings[stripIndex]->size =
|
sys_settings.ledStripSettings[stripIndex]->chip = jsonConstrainString(tag, obj, "chip", "WS2812B");
|
||||||
jsonConstrain<int>(tag, obj, "size", 1, 250, 25);
|
sys_settings.ledStripSettings[stripIndex]->rgbOrder = jsonConstrainString(tag, obj, "rgb-order", "WS2812B");
|
||||||
sys_settings.ledStripSettings[stripIndex]->chip =
|
sys_settings.ledStripSettings[stripIndex]->shift = jsonConstrain<int>(tag, obj, "shift", -250, 250, 0);
|
||||||
jsonConstrainString(tag, obj, "chip", "WS2812B");
|
sys_settings.ledStripSettings[stripIndex]->offset = jsonConstrain<int>(tag, obj, "offset", -250, 250, 0);
|
||||||
sys_settings.ledStripSettings[stripIndex]->rgbOrder =
|
sys_settings.ledStripSettings[stripIndex]->bright = jsonConstrain<int>(tag, obj, "bright", 5, 255, 200);
|
||||||
jsonConstrainString(tag, obj, "rgb-order", "WS2812B");
|
|
||||||
sys_settings.ledStripSettings[stripIndex]->shift =
|
|
||||||
jsonConstrain<int>(tag, obj, "shift", -250, 250, 0);
|
|
||||||
sys_settings.ledStripSettings[stripIndex]->offset =
|
|
||||||
jsonConstrain<int>(tag, obj, "offset", -250, 250, 0);
|
|
||||||
sys_settings.ledStripSettings[stripIndex]->bright =
|
|
||||||
jsonConstrain<int>(tag, obj, "bright", 5, 255, 200);
|
|
||||||
sys_settings.ledStripSettings[stripIndex]->powerDiv = 0;
|
sys_settings.ledStripSettings[stripIndex]->powerDiv = 0;
|
||||||
sys_settings.ledStripSettings[stripIndex]->i2sCh = 0;
|
sys_settings.ledStripSettings[stripIndex]->i2sCh = 0;
|
||||||
sys_settings.ledStripSettings[stripIndex]->core =
|
sys_settings.ledStripSettings[stripIndex]->core = jsonConstrain<int>(tag, obj, "core", 0, 1, 0);
|
||||||
jsonConstrain<int>(tag, obj, "core", 0, 1, 0);
|
|
||||||
} else {
|
} else {
|
||||||
ESP_LOGW(tag, "ledStripSettings[%d] is null, skipping config", stripIndex);
|
ESP_LOGW(tag, "ledStripSettings[%d] is null, skipping config", stripIndex);
|
||||||
}
|
}
|
||||||
@ -256,27 +221,40 @@ void Load_Booth_Settings(SYS_SETTINGS &sys, const String &boothPath) {
|
|||||||
ESP_LOGE(tag, "Error!, %s key: strips not found..");
|
ESP_LOGE(tag, "Error!, %s key: strips not found..");
|
||||||
}
|
}
|
||||||
|
|
||||||
// ********** BLE ***********
|
// Load Animation settings
|
||||||
JsonObject bleJson = doc["ble"];
|
JsonObject fireAnimJson = doc["fire-animation"];
|
||||||
if (!bleJson.isNull()) {
|
if (!fireAnimJson.isNull()) {
|
||||||
sys_settings.bleSettings.enabled = jsonConstrainBool(tag, bleJson, "en", true);
|
fireSettings.speed = jsonConstrain<int>(tag, fireAnimJson, "speed", 10, 100, 50);
|
||||||
sys_settings.bleSettings.name = jsonConstrainString(tag, bleJson, "name", "ATA_LIGHTS");
|
fireSettings.cooling = jsonConstrain<int>(tag, fireAnimJson, "cooling", 0, 255, 65);
|
||||||
|
fireSettings.sparking = jsonConstrain<int>(tag, fireAnimJson, "sparking", 0, 255, 62);
|
||||||
ESP_LOGI(tag, "Loaded BLE settings...");
|
fireSettings.brightness = jsonConstrain<int>(tag, fireAnimJson, "brightness", 0, 255, 240);
|
||||||
|
ESP_LOGI(tag, "Loaded Animation settings...");
|
||||||
} else {
|
} else {
|
||||||
ESP_LOGE(tag, "Error!, %s key: ble not found..", boothPath);
|
ESP_LOGE(tag, "Error!, %s key: animation not found..", boothPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ********** RF Remote***********
|
JsonObject cometsAnimJson = doc["comets-animation"];
|
||||||
/*
|
if (!cometsAnimJson.isNull()) {
|
||||||
JsonObject rfJson = doc["wifi-ap"];
|
cometSettings.speed = jsonConstrain<int>(tag, cometsAnimJson, "speed", 10, 100, 50);
|
||||||
if(!rfJson.isNull()){
|
cometSettings.minFade = jsonConstrain<int>(tag, cometsAnimJson, "min-fade", 0, 255, 66);
|
||||||
//sys_settings.rampLights[0].enabled = jsonConstrainBool(tag, wifiApJson, "en", true);
|
cometSettings.maxFade = jsonConstrain<int>(tag, cometsAnimJson, "max-fade", 0, 255, 55);
|
||||||
ESP_LOGI(tag, "Loaded RF Remote settings...");
|
cometSettings.sizeFactor = jsonConstrain<float>(tag, cometsAnimJson, "size-factor", 0.0f, 1.0f, 0.2f);
|
||||||
|
cometSettings.cycles = jsonConstrain<int>(tag, cometsAnimJson, "cycles", 1, 10, 4);
|
||||||
|
cometSettings.count = jsonConstrain<int>(tag, cometsAnimJson, "count", 1, 10, 1);
|
||||||
|
ESP_LOGI(tag, "Loaded Comet Animation settings...");
|
||||||
} else {
|
} else {
|
||||||
ESP_LOGE(tag, "Error!, %s key: wifi-ap not found..", boothPath);
|
ESP_LOGE(tag, "Error!, %s key: comets-animation not found..", boothPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
JsonObject snakesAnimJson = doc["snakes-animation"];
|
||||||
|
if (!snakesAnimJson.isNull()) {
|
||||||
|
snakeSettings.speed = jsonConstrain<int>(tag, snakesAnimJson, "speed", 10, 100, 50);
|
||||||
|
snakeSettings.cycles = jsonConstrain<int>(tag, snakesAnimJson, "cycles", 1, 10, 4);
|
||||||
|
snakeSettings.multiplier = jsonConstrain<int>(tag, snakesAnimJson, "multiplier", 1, 10, 6);
|
||||||
|
ESP_LOGI(tag, "Loaded Snake Animation settings...");
|
||||||
|
} else {
|
||||||
|
ESP_LOGE(tag, "Error!, %s key: snakes-animation not found..", boothPath);
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Init_ADC(void) {
|
void Init_ADC(void) {
|
||||||
@ -289,15 +267,23 @@ void Init_ADC(void) {
|
|||||||
|
|
||||||
// Enable ADC calibration
|
// Enable ADC calibration
|
||||||
esp_adc_cal_characteristics_t adc_chars;
|
esp_adc_cal_characteristics_t adc_chars;
|
||||||
esp_adc_cal_characterize(ADC_UNIT_1, ADC_ATTEN_DB_11, ADC_WIDTH_BIT_12, 0, &adc_chars);
|
const uint32_t default_vref = 1100; // mV
|
||||||
|
esp_adc_cal_value_t used = esp_adc_cal_characterize(ADC_UNIT_1, ADC_ATTEN_DB_12, ADC_WIDTH_BIT_12, default_vref, &adc_chars);
|
||||||
|
|
||||||
// Check calibration success
|
switch (used) {
|
||||||
if (esp_adc_cal_check_efuse(ESP_ADC_CAL_VAL_EFUSE_TP) == ESP_OK) {
|
case ESP_ADC_CAL_VAL_EFUSE_TP_FIT:
|
||||||
ESP_LOGI(tag, "ADC calibration: Using Two Point values from eFuse");
|
ESP_LOGI(tag, "ADC calibrated using eFuse Two-Point + Fit coefficients (TP_FIT)");
|
||||||
} else if (esp_adc_cal_check_efuse(ESP_ADC_CAL_VAL_EFUSE_VREF) == ESP_OK) {
|
break;
|
||||||
ESP_LOGI(tag, "ADC calibration: Using reference voltage from eFuse");
|
case ESP_ADC_CAL_VAL_EFUSE_TP:
|
||||||
} else {
|
ESP_LOGI(tag, "ADC calibrated using eFuse Two-Point values (TP)");
|
||||||
ESP_LOGW(tag, "ADC calibration: Using default reference voltage");
|
break;
|
||||||
|
case ESP_ADC_CAL_VAL_EFUSE_VREF:
|
||||||
|
ESP_LOGI(tag, "ADC calibrated using eFuse Vref");
|
||||||
|
break;
|
||||||
|
case ESP_ADC_CAL_VAL_DEFAULT_VREF:
|
||||||
|
default:
|
||||||
|
ESP_LOGW(tag, "ADC using default Vref (no eFuse calibration available)");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -320,7 +306,7 @@ float readBoardInputVoltage(void) {
|
|||||||
// Convert raw ADC to voltage using calibration
|
// Convert raw ADC to voltage using calibration
|
||||||
uint32_t voltage_mv;
|
uint32_t voltage_mv;
|
||||||
esp_adc_cal_characteristics_t adc_chars;
|
esp_adc_cal_characteristics_t adc_chars;
|
||||||
esp_adc_cal_characterize(ADC_UNIT_1, ADC_ATTEN_DB_11, ADC_WIDTH_BIT_12, 1100, &adc_chars);
|
esp_adc_cal_characterize(ADC_UNIT_1, ADC_ATTEN_DB_12, ADC_WIDTH_BIT_12, 1100, &adc_chars);
|
||||||
voltage_mv = esp_adc_cal_raw_to_voltage(reading, &adc_chars);
|
voltage_mv = esp_adc_cal_raw_to_voltage(reading, &adc_chars);
|
||||||
|
|
||||||
// Voltage divider: R1 = 10k (series to input), R2 = 470 (to ground). Measurement is across R2.
|
// Voltage divider: R1 = 10k (series to input), R2 = 470 (to ground). Measurement is across R2.
|
||||||
|
|||||||
@ -12,7 +12,7 @@ TI_TMP102_Compatible *tSensor = nullptr;
|
|||||||
void Init_TSensor(uint8_t addr, TSENSOR_SETTINGS *tsettings) {
|
void Init_TSensor(uint8_t addr, TSENSOR_SETTINGS *tsettings) {
|
||||||
|
|
||||||
if(tsettings != nullptr) {
|
if(tsettings != nullptr) {
|
||||||
t_settings = tsettings; // Store pointer reference
|
t_settings = tsettings; // Store pointer reference```
|
||||||
ESP_LOGI(tag, "TSensor settings loaded: SP1=%.1f, SP2=%.1f, FP1=%.1f, FP2=%.1f, Hyst=%.1f",
|
ESP_LOGI(tag, "TSensor settings loaded: SP1=%.1f, SP2=%.1f, FP1=%.1f, FP2=%.1f, Hyst=%.1f",
|
||||||
t_settings->setpoint1, t_settings->setpoint2,
|
t_settings->setpoint1, t_settings->setpoint2,
|
||||||
t_settings->fanPower1, t_settings->fanPower2, t_settings->hyst);
|
t_settings->fanPower1, t_settings->fanPower2, t_settings->hyst);
|
||||||
|
|||||||
212
src/my_wifi.cpp
212
src/my_wifi.cpp
@ -806,8 +806,129 @@ void Setup_WebServer_Handlers(AsyncWebServer &server) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleFilesUpload_OnBody(AsyncWebServerRequest *request, String filename, size_t index,
|
// Hardened upload body handler: better path sanitization, robust write loop,
|
||||||
uint8_t *data, size_t len, bool final) {
|
// safe temp-path handling, and stricter size checks.
|
||||||
|
void handleFilesUpload_OnBody(AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final) {
|
||||||
|
static const size_t MAX_UPLOAD_SIZE = 1024 * 512; // 512KB limit
|
||||||
|
|
||||||
|
// Optional: require auth for uploads
|
||||||
|
// if (!request->authenticate(http_username, http_password)) {
|
||||||
|
// return request->requestAuthentication();
|
||||||
|
// }
|
||||||
|
|
||||||
|
// Use only the basename of the provided filename to avoid client-supplied path components
|
||||||
|
int lastSlash = max(filename.lastIndexOf('/'), filename.lastIndexOf('\\'));
|
||||||
|
String safeFilename = (lastSlash >= 0) ? filename.substring(lastSlash + 1) : filename;
|
||||||
|
if (safeFilename.length() == 0) {
|
||||||
|
ESP_LOGE(tag, "Empty filename provided");
|
||||||
|
request->send(400, "text/plain", "Invalid filename");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (index == 0) {
|
||||||
|
// Initial upload chunk: validate dir param
|
||||||
|
if (!request->hasParam("dir-path", true, false)) {
|
||||||
|
ESP_LOGE(tag, "Missing dir-path parameter");
|
||||||
|
request->send(400, "text/plain", "Missing dir-path");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
AsyncWebParameter *p = request->getParam("dir-path", true, false);
|
||||||
|
String dir = p->value();
|
||||||
|
|
||||||
|
// Basic sanitize of dir param
|
||||||
|
if (dir.indexOf("..") >= 0) {
|
||||||
|
ESP_LOGW(tag, "Rejected upload with unsafe dir-path: %s", dir.c_str());
|
||||||
|
request->send(400, "text/plain", "Invalid upload path");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Ensure leading slash and collapse duplicate slashes
|
||||||
|
if (!dir.startsWith("/")) dir = "/" + dir;
|
||||||
|
while (dir.indexOf("//") >= 0) dir.replace("//", "/");
|
||||||
|
|
||||||
|
// OPTIONAL: constrain to a base directory (uncomment to enforce)
|
||||||
|
// const String allowedPrefix = "/www";
|
||||||
|
// if (!dir.startsWith(allowedPrefix)) {
|
||||||
|
// ESP_LOGW(tag, "Rejected upload outside allowed dir: %s", dir.c_str());
|
||||||
|
// request->send(400, "text/plain", "Invalid upload directory");
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
|
||||||
|
String path = dir;
|
||||||
|
if (!path.endsWith("/")) path += "/";
|
||||||
|
path += safeFilename;
|
||||||
|
|
||||||
|
// Final sanitize
|
||||||
|
if (path.indexOf("..") >= 0) {
|
||||||
|
ESP_LOGW(tag, "Rejected upload with unsafe path after combine: %s", path.c_str());
|
||||||
|
request->send(400, "text/plain", "Invalid upload path");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
while (path.indexOf("//") >= 0) path.replace("//", "/");
|
||||||
|
|
||||||
|
ESP_LOGI(tag, "Starting upload: %s", path.c_str());
|
||||||
|
|
||||||
|
// Open file for writing (truncate)
|
||||||
|
request->_tempFile = LittleFS.open(path, "w");
|
||||||
|
if (!request->_tempFile) {
|
||||||
|
ESP_LOGE(tag, "Failed to create file: %s", path.c_str());
|
||||||
|
request->send(500, "text/plain", "Failed to create file");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we have no file handle, abort
|
||||||
|
if (!request->_tempFile) {
|
||||||
|
ESP_LOGE(tag, "No temp file available for upload chunk");
|
||||||
|
request->send(500, "text/plain", "Internal error");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bounds check: protect against overflow and enforce max size
|
||||||
|
if (index > MAX_UPLOAD_SIZE || len > MAX_UPLOAD_SIZE || index + len > MAX_UPLOAD_SIZE) {
|
||||||
|
// Capture filename before closing
|
||||||
|
String tmpName = request->_tempFile.name();
|
||||||
|
request->_tempFile.close();
|
||||||
|
LittleFS.remove(tmpName);
|
||||||
|
ESP_LOGE(tag, "Upload too large or out of bounds: index=%u len=%u", (unsigned)index, (unsigned)len);
|
||||||
|
request->send(413, "text/plain", "File too large");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write chunk (handle partial writes)
|
||||||
|
if (len > 0) {
|
||||||
|
size_t toWrite = len;
|
||||||
|
size_t writtenTotal = 0;
|
||||||
|
const uint8_t *bufPtr = data;
|
||||||
|
|
||||||
|
while (toWrite > 0) {
|
||||||
|
size_t written = request->_tempFile.write(bufPtr + writtenTotal, toWrite);
|
||||||
|
if (written == 0) {
|
||||||
|
// Attempt to flush/close and remove the file
|
||||||
|
String tmpName = request->_tempFile.name();
|
||||||
|
request->_tempFile.close();
|
||||||
|
LittleFS.remove(tmpName);
|
||||||
|
ESP_LOGE(tag, "Write failed after %u/%u bytes", (unsigned)writtenTotal, (unsigned)len);
|
||||||
|
request->send(500, "text/plain", "Write failed");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
writtenTotal += written;
|
||||||
|
toWrite -= written;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (final) {
|
||||||
|
// Capture path/name for logging and for safe removal if needed
|
||||||
|
String finalName = request->_tempFile.name();
|
||||||
|
|
||||||
|
request->_tempFile.close();
|
||||||
|
|
||||||
|
// Log final size if possible (index + len)
|
||||||
|
ESP_LOGI(tag, "Upload complete: %s, %u bytes", safeFilename.c_str(), (unsigned)(index + len));
|
||||||
|
request->redirect("/files");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
void handleFilesUpload_OnBody(AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final) {
|
||||||
static const size_t MAX_UPLOAD_SIZE = 1024 * 512; // 512KB limit
|
static const size_t MAX_UPLOAD_SIZE = 1024 * 512; // 512KB limit
|
||||||
|
|
||||||
if (!index) {
|
if (!index) {
|
||||||
@ -863,10 +984,10 @@ void handleFilesUpload_OnBody(AsyncWebServerRequest *request, String filename, s
|
|||||||
request->redirect("/files");
|
request->redirect("/files");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
// Send html file with template processing {{VAR}}
|
// Send html file with template processing {{VAR}}
|
||||||
bool sendHtmlFile(const char *filePath, AsyncWebServerRequest *request,
|
bool sendHtmlFile(const char *filePath, AsyncWebServerRequest *request, String (*callback)(const String &)) {
|
||||||
String (*callback)(const String &)) {
|
|
||||||
const char *htmlFile = readFile(LittleFS, filePath);
|
const char *htmlFile = readFile(LittleFS, filePath);
|
||||||
if (!htmlFile) {
|
if (!htmlFile) {
|
||||||
ESP_LOGE(tag, "Failed to read file: %s", filePath);
|
ESP_LOGE(tag, "Failed to read file: %s", filePath);
|
||||||
@ -877,7 +998,7 @@ bool sendHtmlFile(const char *filePath, AsyncWebServerRequest *request,
|
|||||||
String processedData = varReplace(htmlFile, callback);
|
String processedData = varReplace(htmlFile, callback);
|
||||||
delete[] htmlFile; // Clean up allocated memory
|
delete[] htmlFile; // Clean up allocated memory
|
||||||
|
|
||||||
ESP_LOGI(tag, "Sent file: %s", filePath);
|
ESP_LOGD(tag, "Sent file: %s", filePath);
|
||||||
request->send(200, "text/html", processedData);
|
request->send(200, "text/html", processedData);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -1104,6 +1225,86 @@ void onWiFiEvent(WiFiEvent_t event) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Wifi_Start_MDNS(void) {
|
||||||
|
// Validate mDnsName and build a safe fallback if needed
|
||||||
|
String name = mDnsName;
|
||||||
|
// Trim whitespace
|
||||||
|
name.trim();
|
||||||
|
// Fallback generation helper
|
||||||
|
auto make_fallback = [&]() -> String {
|
||||||
|
char macSuffix[5] = {0};
|
||||||
|
uint8_t mac[6];
|
||||||
|
WiFi.softAPmacAddress(mac);
|
||||||
|
// take last two bytes as hex
|
||||||
|
snprintf(macSuffix, sizeof(macSuffix), "%02X%02X", mac[4], mac[5]);
|
||||||
|
String fh = "ata-" + String(macSuffix);
|
||||||
|
return fh;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (name.length() == 0) {
|
||||||
|
ESP_LOGW(tag, "mDnsName empty, generating fallback");
|
||||||
|
name = make_fallback();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Trim to 63 chars
|
||||||
|
if (name.length() > 63) {
|
||||||
|
name = name.substring(0, 63);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Replace invalid characters with '-'
|
||||||
|
for (size_t i = 0; i < name.length(); ++i) {
|
||||||
|
char c = name[i];
|
||||||
|
if (!((c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') || c == '-')) {
|
||||||
|
name[i] = '-';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Prevent leading/trailing hyphen
|
||||||
|
if (name.startsWith("-")) name.remove(0, 1);
|
||||||
|
if (name.endsWith("-")) name.remove(name.length() - 1, 1);
|
||||||
|
if (name.length() == 0) {
|
||||||
|
name = make_fallback();
|
||||||
|
}
|
||||||
|
|
||||||
|
ESP_LOGI(tag, "Starting mDNS responder with name: %s", name.c_str());
|
||||||
|
|
||||||
|
// Ensure we have WiFi up when starting MDNS in STA mode
|
||||||
|
if (WiFi.getMode() == WIFI_MODE_STA || WiFi.getMode() == WIFI_MODE_APSTA) {
|
||||||
|
if (WiFi.localIP() == INADDR_NONE || WiFi.localIP().toString() == "0.0.0.0") {
|
||||||
|
ESP_LOGW(tag, "No IP yet; MDNS may fail until network is up");
|
||||||
|
// still attempt, but it's usually better to call this after station got IP
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to (re)start MDNS. If MDNS is already started we restart it to ensure name matches.
|
||||||
|
// MDNS.end is safe to call even if not started.
|
||||||
|
MDNS.end();
|
||||||
|
|
||||||
|
const int maxRetries = 2;
|
||||||
|
bool started = false;
|
||||||
|
for (int attempt = 0; attempt <= maxRetries && !started; ++attempt) {
|
||||||
|
if (MDNS.begin(name.c_str())) {
|
||||||
|
started = true;
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
ESP_LOGW(tag, "MDNS.begin() failed on attempt %d/%d", attempt + 1, maxRetries + 1);
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(200));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!started) {
|
||||||
|
ESP_LOGE(tag, "Failed to start mDNS responder for %s", name.c_str());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Optionally advertise the HTTP service so discovery tools can find it
|
||||||
|
MDNS.addService("http", "tcp", 80);
|
||||||
|
|
||||||
|
ESP_LOGI(tag, "mDNS responder started. Access via http://%s.local (may take a moment to appear)", name.c_str());
|
||||||
|
|
||||||
|
// Save the potentially-sanitized name back to global so other code can use it
|
||||||
|
mDnsName = name;
|
||||||
|
}
|
||||||
|
/*
|
||||||
void Wifi_Start_MDNS(void) {
|
void Wifi_Start_MDNS(void) {
|
||||||
ESP_LOGV(tag, "Initializing MDNS: %s", mDnsName.c_str());
|
ESP_LOGV(tag, "Initializing MDNS: %s", mDnsName.c_str());
|
||||||
if (!MDNS.begin(mDnsName.c_str())) {
|
if (!MDNS.begin(mDnsName.c_str())) {
|
||||||
@ -1112,6 +1313,7 @@ void Wifi_Start_MDNS(void) {
|
|||||||
ESP_LOGV(tag, "You can access device via http://%s.local", mDnsName);
|
ESP_LOGV(tag, "You can access device via http://%s.local", mDnsName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
bool writeFile(fs::FS &fs, const char *path, const char *message) {
|
bool writeFile(fs::FS &fs, const char *path, const char *message) {
|
||||||
// Validate inputs
|
// Validate inputs
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user