feat: Implement motion sway effects and enhance face sliding based on roll angle
This commit is contained in:
@@ -81,6 +81,23 @@ static uint8_t luxToContrast(float lux) {
|
|||||||
return (uint8_t)value;
|
return (uint8_t)value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int8_t motionSwayOffsetX(unsigned long nowMs) {
|
||||||
|
// 8-step loop for a clear side-to-side motion while the accelerometer reports movement.
|
||||||
|
static const int8_t kSway[] = {-8, -4, 0, 4, 8, 4, 0, -4};
|
||||||
|
const size_t steps = sizeof(kSway) / sizeof(kSway[0]);
|
||||||
|
size_t idx = (nowMs / 90UL) % steps;
|
||||||
|
return kSway[idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
static int8_t rollToFaceSlideX(float rollDeg) {
|
||||||
|
// Map tilt to a larger screen slide so the face visibly shifts toward the tilted side.
|
||||||
|
float clamped = clampFloat(rollDeg, -35.0f, 35.0f);
|
||||||
|
int v = (int)lroundf((clamped / 35.0f) * 24.0f); // -24..+24 px
|
||||||
|
if (v < -24) v = -24;
|
||||||
|
if (v > 24) v = 24;
|
||||||
|
return (int8_t)v;
|
||||||
|
}
|
||||||
|
|
||||||
static void initRestartButton() {
|
static void initRestartButton() {
|
||||||
pinMode(PIN_RESTART_BUTTON, INPUT_PULLUP);
|
pinMode(PIN_RESTART_BUTTON, INPUT_PULLUP);
|
||||||
bool raw = digitalRead(PIN_RESTART_BUTTON);
|
bool raw = digitalRead(PIN_RESTART_BUTTON);
|
||||||
@@ -332,11 +349,13 @@ void App::loop() {
|
|||||||
motion.loop();
|
motion.loop();
|
||||||
if (motion.available()) {
|
if (motion.available()) {
|
||||||
face.setTiltEffects(0, 0); // disable old motion-based eye deformation
|
face.setTiltEffects(0, 0); // disable old motion-based eye deformation
|
||||||
face.setFaceSlideX(motion.eyeOffsetX()); // roll -> slide whole face left/right
|
int8_t slideX = rollToFaceSlideX(motion.rollDeg()); // stronger roll -> face slide
|
||||||
(void)motion.consumePickupEvent(); // consume pickup events so they don't accumulate
|
(void)motion.consumePickupEvent(); // consume pickup events so they don't accumulate
|
||||||
if (motion.isMoving()) {
|
if (motion.isMoving()) {
|
||||||
motionWakeUntilMs = millis() + MOTION_WAKE_MS;
|
motionWakeUntilMs = millis() + MOTION_WAKE_MS;
|
||||||
|
slideX = motionSwayOffsetX(millis());
|
||||||
}
|
}
|
||||||
|
face.setFaceSlideX(slideX);
|
||||||
} else {
|
} else {
|
||||||
face.setTiltEffects(0, 0);
|
face.setTiltEffects(0, 0);
|
||||||
face.setFaceSlideX(0);
|
face.setFaceSlideX(0);
|
||||||
|
|||||||
@@ -99,6 +99,19 @@ void WebUI::begin(Settings& settings,
|
|||||||
"</div>"
|
"</div>"
|
||||||
"</div>"
|
"</div>"
|
||||||
"<div class='card'>"
|
"<div class='card'>"
|
||||||
|
"<h2><i class='fas fa-wave-square' style='margin-right: 10px;'></i>Sensor Readings</h2>"
|
||||||
|
"<div class='status-grid'>"
|
||||||
|
"<div class='status-item'><div class='status-label'>Soil Moisture</div>"
|
||||||
|
"<div class='status-value'>" + String(moisture.percent()) + "% (" + String(moisture.raw()) + ")</div></div>"
|
||||||
|
"<div class='status-item'><div class='status-label'>Accelerometer</div>"
|
||||||
|
"<div class='status-value'>" + String(motion.available() ? "Detected" : "Not detected") + "</div></div>"
|
||||||
|
"<div class='status-item'><div class='status-label'>Roll</div>"
|
||||||
|
"<div class='status-value'>" + String(motion.rollDeg(), 1) + "°</div></div>"
|
||||||
|
"<div class='status-item'><div class='status-label'>Pitch</div>"
|
||||||
|
"<div class='status-value'>" + String(motion.pitchDeg(), 1) + "°</div></div>"
|
||||||
|
"</div>"
|
||||||
|
"</div>"
|
||||||
|
"<div class='card'>"
|
||||||
"<h2><i class='fas fa-wifi' style='margin-right: 10px;'></i>Wi-Fi Settings</h2>"
|
"<h2><i class='fas fa-wifi' style='margin-right: 10px;'></i>Wi-Fi Settings</h2>"
|
||||||
"<form method='POST' action='/wifi' id='wifiForm'>"
|
"<form method='POST' action='/wifi' id='wifiForm'>"
|
||||||
"<label for='ssid'>Network Name (SSID)</label>"
|
"<label for='ssid'>Network Name (SSID)</label>"
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ void FaceRenderer::triggerSurprised(unsigned long durationMs) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void FaceRenderer::setFaceSlideX(int8_t x) {
|
void FaceRenderer::setFaceSlideX(int8_t x) {
|
||||||
_faceSlideTargetX = clampInt(x, -12, 12);
|
_faceSlideTargetX = clampInt(x, -24, 24);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FaceRenderer::begin(Display& display, Settings& settings) {
|
void FaceRenderer::begin(Display& display, Settings& settings) {
|
||||||
|
|||||||
Reference in New Issue
Block a user