added improved the 'animation' transition between New Connection and running connection
This commit is contained in:
@@ -122,12 +122,20 @@ unsigned long lastPacketTime = 0;
|
|||||||
const unsigned long watchdogTimeout = 5000; // 5 seconds
|
const unsigned long watchdogTimeout = 5000; // 5 seconds
|
||||||
unsigned long lastFadeTime = 0;
|
unsigned long lastFadeTime = 0;
|
||||||
|
|
||||||
|
// -------------------------------
|
||||||
|
// Animation tuning
|
||||||
|
// -------------------------------
|
||||||
|
const float FADE_IN_FACTOR = 0.999f; // boot-up 0 → 100%
|
||||||
|
const float FADE_OUT_FACTOR = 0.999f; // watchdog 100% → 0
|
||||||
|
const unsigned long FADE_INTERVAL = 1; // ms between fade steps
|
||||||
|
|
||||||
// -------------------------------
|
// -------------------------------
|
||||||
// Connection state machine
|
// Connection state machine
|
||||||
// -------------------------------
|
// -------------------------------
|
||||||
enum ConnectionState {
|
enum ConnectionState {
|
||||||
STATE_DISCONNECTED, // fade to zero
|
STATE_DISCONNECTED, // fade to zero
|
||||||
STATE_CONNECTING, // fade in 0 → 100%
|
STATE_CONNECTING, // fade in 0 → 100%
|
||||||
|
STATE_WAIT_FOR_FIRST_PACKET, // hold at 100%, wait for first UDP
|
||||||
STATE_CONNECTED // normal UDP-driven slew
|
STATE_CONNECTED // normal UDP-driven slew
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -543,8 +551,8 @@ void loop() {
|
|||||||
|
|
||||||
if (idx == NUM_CHANNELS) {
|
if (idx == NUM_CHANNELS) {
|
||||||
|
|
||||||
// First valid packet after being disconnected → start CONNECTING
|
|
||||||
if (connectionState == STATE_DISCONNECTED) {
|
if (connectionState == STATE_DISCONNECTED) {
|
||||||
|
// First valid packet after being disconnected → start CONNECTING
|
||||||
Serial.println("STATE CHANGE: DISCONNECTED → CONNECTING (UDP connection established)");
|
Serial.println("STATE CHANGE: DISCONNECTED → CONNECTING (UDP connection established)");
|
||||||
connectionState = STATE_CONNECTING;
|
connectionState = STATE_CONNECTING;
|
||||||
|
|
||||||
@@ -562,6 +570,38 @@ void loop() {
|
|||||||
// Ignore UDP values during fade-in, just keep watchdog alive
|
// Ignore UDP values during fade-in, just keep watchdog alive
|
||||||
lastPacketTime = millis();
|
lastPacketTime = millis();
|
||||||
}
|
}
|
||||||
|
else if (connectionState == STATE_WAIT_FOR_FIRST_PACKET) {
|
||||||
|
// First real packet after fade-in completes
|
||||||
|
Serial.println("STATE CHANGE: WAIT_FOR_FIRST_PACKET → CONNECTED (first UDP packet received)");
|
||||||
|
|
||||||
|
for (int ch = 0; ch < NUM_CHANNELS; ch++) {
|
||||||
|
if (!overrideActive[ch]) {
|
||||||
|
targetDuty[ch] = values[ch];
|
||||||
|
slewStartDuty[ch] = currentDuty[ch]; // currently ~100%
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
slewStartTime = millis();
|
||||||
|
lastPacketTime = millis();
|
||||||
|
connectionState = STATE_CONNECTED;
|
||||||
|
|
||||||
|
// Debug output
|
||||||
|
Serial.println("Received UDP packet (first after fade-in):");
|
||||||
|
for (int i = 0; i < NUM_CHANNELS; i++) {
|
||||||
|
Serial.print(" CH");
|
||||||
|
Serial.print(i);
|
||||||
|
Serial.print(" (");
|
||||||
|
Serial.print(channelLabels[i]);
|
||||||
|
Serial.print("): ");
|
||||||
|
Serial.print(values[i], 2);
|
||||||
|
if (channelUnits[i][0] != '\0') {
|
||||||
|
Serial.print(" ");
|
||||||
|
Serial.print(channelUnits[i]);
|
||||||
|
}
|
||||||
|
Serial.println();
|
||||||
|
}
|
||||||
|
Serial.println();
|
||||||
|
}
|
||||||
else if (connectionState == STATE_CONNECTED) {
|
else if (connectionState == STATE_CONNECTED) {
|
||||||
// Normal UDP-driven update
|
// Normal UDP-driven update
|
||||||
for (int ch = 0; ch < NUM_CHANNELS; ch++) {
|
for (int ch = 0; ch < NUM_CHANNELS; ch++) {
|
||||||
@@ -631,10 +671,7 @@ void loop() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Fade-in animation: 0 → 100% on all non-override channels
|
// Fade-in animation: 0 → 100% on all non-override channels
|
||||||
const unsigned long fadeInterval = 1;
|
if (now - lastFadeTime >= FADE_INTERVAL) {
|
||||||
const float fadeInFactor = 0.999f; // fast at start, slow near 100%
|
|
||||||
|
|
||||||
if (now - lastFadeTime >= fadeInterval) {
|
|
||||||
lastFadeTime = now;
|
lastFadeTime = now;
|
||||||
|
|
||||||
bool allReached = true;
|
bool allReached = true;
|
||||||
@@ -644,7 +681,7 @@ void loop() {
|
|||||||
float cd = currentDuty[ch];
|
float cd = currentDuty[ch];
|
||||||
|
|
||||||
// Exponential approach to 100%
|
// Exponential approach to 100%
|
||||||
cd = cd * fadeInFactor + 100.0f * (1.0f - fadeInFactor);
|
cd = cd * FADE_IN_FACTOR + 100.0f * (1.0f - FADE_IN_FACTOR);
|
||||||
currentDuty[ch] = cd;
|
currentDuty[ch] = cd;
|
||||||
|
|
||||||
float calibratedDuty = applyCalibration(ch, cd);
|
float calibratedDuty = applyCalibration(ch, cd);
|
||||||
@@ -659,30 +696,27 @@ void loop() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (allReached) {
|
if (allReached) {
|
||||||
Serial.println("STATE CHANGE: CONNECTING → CONNECTED (fade-in complete)");
|
Serial.println("STATE CHANGE: CONNECTING → STATE_WAIT_FOR_FIRST_PACKET (fade-in complete)");
|
||||||
// Initialize slew baseline from currentDuty
|
connectionState = STATE_WAIT_FOR_FIRST_PACKET;
|
||||||
for (int ch = 0; ch < NUM_CHANNELS; ch++) {
|
|
||||||
slewStartDuty[ch] = currentDuty[ch];
|
|
||||||
}
|
|
||||||
slewStartTime = millis();
|
|
||||||
connectionState = STATE_CONNECTED;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
case STATE_WAIT_FOR_FIRST_PACKET: {
|
||||||
|
// Hold at ~100%, do nothing until first UDP packet arrives
|
||||||
|
// (handled in UDP parsing above)
|
||||||
|
} break;
|
||||||
|
|
||||||
case STATE_DISCONNECTED: {
|
case STATE_DISCONNECTED: {
|
||||||
// Watchdog fade-to-zero (always active in this state)
|
// Watchdog fade-to-zero (always active in this state)
|
||||||
const unsigned long fadeInterval = 1;
|
if (now - lastFadeTime >= FADE_INTERVAL) {
|
||||||
|
|
||||||
if (now - lastFadeTime >= fadeInterval) {
|
|
||||||
lastFadeTime = now;
|
lastFadeTime = now;
|
||||||
|
|
||||||
for (int ch = 0; ch < NUM_CHANNELS; ch++) {
|
for (int ch = 0; ch < NUM_CHANNELS; ch++) {
|
||||||
|
|
||||||
if (currentDuty[ch] > 0.0f) {
|
if (currentDuty[ch] > 0.0f) {
|
||||||
|
|
||||||
const float fadeFactor = 0.999f;
|
currentDuty[ch] *= FADE_OUT_FACTOR;
|
||||||
currentDuty[ch] *= fadeFactor;
|
|
||||||
|
|
||||||
if (currentDuty[ch] < 0.01f)
|
if (currentDuty[ch] < 0.01f)
|
||||||
currentDuty[ch] = 0.0f;
|
currentDuty[ch] = 0.0f;
|
||||||
|
|||||||
Reference in New Issue
Block a user