# Sensor Movement Detection Logic
Model: gemma-4-e4b-it
Created: 6/7/2026, 8:08:50 PM
Exported from: LM Studio 0.4.15+2

### User
Can you combine this code that prints "slow down" when you move too fast and "movement detected" when it sense movement with another code?

#include &lt;Wire.h&gt;
#include &lt;Adafruit_Sensor.h&gt;
#include &lt;Adafruit_ADXL343.h&gt;



/* Assign a unique ID to this sensor at the same time */
Adafruit_ADXL343 accel = Adafruit_ADXL343(12345);



// --- Movement Detection Variables ---


// Threshold 1: Detects general movement (Original logic)
const float MOVEMENT_THRESHOLD = 0.8; // Example: Detect movement if magnitude change exceeds 0.8G


// Threshold 2: Detects *fast* movement (New Logic)
// This threshold determines how large the difference between consecutive readings must be 
// to trigger a "slow down" warning. You will need to tune this heavily!
const float FAST_MOVEMENT_THRESHOLD = 1.5; // Example: Trigger if change in acceleration vector magnitude exceeds 1.5G



// Tracking variables for the previous reading (for both general and fast detection)
float last_accel_x = 0.0;
float last_accel_y = 0.0;
float last_accel_z = 0.0;


// Variables to track the state of the alerts
bool movement_detected_flag = false;
bool fast_movement_warning_active = false;



void setup(void)
{
  Serial.begin(9600);
  while (!Serial);
  Serial.println("ADXL343 Movement Detector Initializing..."); Serial.println("");


  /* Initialise the sensor */
  if(!accel.begin())
  {
    Serial.println("Ooops, no ADXL343 detected ... Check your wiring!");
    while(1);
  }


  /* Set the range to whatever is appropriate for your project */
  accel.setRange(ADXL343_RANGE_16_G);



  Serial.println("ADXL343 initialized. Ready to detect movement.");
}



void loop(void)
{
  // 1. Read the current sensor data
  sensors_event_t event;
  accel.getEvent(&event);


  float current_x = event.acceleration.x;
  float current_y = event.acceleration.y;
  float current_z = event.acceleration.z;



  // 2. Calculate the magnitude of acceleration (Total force vector)
  // Magnitude = sqrt(X^2 + Y^2 + Z^2)
  float current_magnitude = sqrt(current_x * current_x + current_y * current_y + current_z * current_z);



  // 3. Calculate the change in magnitude since the last reading (General Movement Proxy)
  float last_magnitude = sqrt(last_accel_x * last_accel_x + last_accel_y * last_accel_y + last_accel_z * last_accel_z);
  // The difference between current and previous magnitude is a good indicator of change.
  float delta_magnitude = abs(current_magnitude - last_magnitude);



  // 4. *** NEW: Calculate the rate of change (Fast Movement Proxy) ***
  // This measures how much the *vector* has changed, not just the total force magnitude.
  float delta_x = abs(current_x - last_accel_x);
  float delta_y = abs(current_y - last_accel_y);
  float delta_z = abs(current_z - last_accel_z);


  // The magnitude of the change vector (how much the reading jumped)
  float rate_of_change_magnitude = sqrt(delta_x * delta_x + delta_y * delta_y + delta_z * delta_z);



  // 5. Detection Logic & Output
  
  // --- A. Fast Movement Check (The new requirement) ---
  if (rate_of_change_magnitude &gt; FAST_MOVEMENT_THRESHOLD) {
    if (!fast_movement_warning_active) {
      Serial.println("\n****************************");
      Serial.print("!!! WARNING: SLOW DOWN !!! ");
      Serial.print("Rate of Change Magnitude: ");
      Serial.print(rate_of_change_magnitude);
      Serial.println(" (Too fast!)");
      Serial.println("****************************\n");
      fast_movement_warning_active = true; // Set flag to prevent spamming
    }
  } else {
    // If the change is small, reset the warning flag
    if (fast_movement_warning_active) {
        Serial.println("\n[INFO] Movement rate stabilized.");
    }
    fast_movement_warning_active = false;
  }



  // --- B. General Movement Check (Original logic) ---
  if (delta_magnitude &gt; MOVEMENT_THRESHOLD) {
    if (!movement_detected_flag) {
      Serial.println("=============================");
      Serial.print("MOVEMENT DETECTED! Delta Magnitude: ");
      Serial.println(delta_magnitude);
      Serial.println("=============================");
      movement_detected_flag = true; // Set flag to prevent spamming
    }
  } else {
    // If the change is small, reset the general movement flag
    if (movement_detected_flag) {
        Serial.println("[INFO] Movement subsided.");
    }
    movement_detected_flag = false;
  }



  // 6. Update state for the next loop iteration
  last_accel_x = current_x;
  last_accel_y = current_y;
  last_accel_z = current_z;



  // Small delay to keep readings stable and prevent overwhelming serial output
  delay(50); 
}

### Assistant
The code you provided **already combines** the logic for both "slow down" (fast movement) and "movement detected" (general movement).

However, the way it prints messages can be improved to make the combined output cleaner and ensure that when one event happens, it doesn't immediately overwrite or conflict with the message from the other.

Here is a refactored version of your code. I have:
1.  **Streamlined the Output:** Used a single block at the end of `loop()` to print *all* active status messages for that cycle, making the serial output much cleaner.
2.  **Improved Flag Management:** Made sure the flags reset correctly when conditions are no longer met.

### Combined and Refactored Code

```cpp
#include &lt;Wire.h&gt;
#include &lt;Adafruit_Sensor.h&gt;
#include &lt;Adafruit_ADXL343.h&gt;

/* Assign a unique ID to this sensor at the same time */
Adafruit_ADXL343 accel = Adafruit_ADXL343(12345);

// --- Movement Detection Variables ---

// Threshold 1: Detects general movement (Original logic)
const float MOVEMENT_THRESHOLD = 0.8; // Example: Detect movement if magnitude change exceeds 0.8G

// Threshold 2: Detects *fast* movement (New Logic)
// Trigger if the jump in acceleration vector magnitude exceeds this value.
const float FAST_MOVEMENT_THRESHOLD = 1.5; // Example: Tune this heavily!

// Tracking variables for the previous reading
float last_accel_x = 0.0;
float last_accel_y = 0.0;
float last_accel_z = 0.0;

// Variables to track the state of the alerts (to prevent spamming)
bool movement_detected_flag = false;
bool fast_movement_warning_active = false;


void setup(void)
{
  Serial.begin(9600);
  while (!Serial);
  Serial.println("ADXL343 Movement Detector Initializing..."); Serial.println("");

  /* Initialise the sensor */
  if(!accel.begin())
  {
    Serial.println("Ooops, no ADXL343 detected ... Check your wiring!");
    while(1);
  }

  /* Set the range to whatever is appropriate for your project */
  accel.setRange(ADXL343_RANGE_16_G);

  Serial.println("ADXL343 initialized. Ready to detect movement.");
}


void loop(void)
{
  // 1. Read the current sensor data
  sensors_event_t event;
  accel.getEvent(&event);

  float current_x = event.acceleration.x;
  float current_y = event.acceleration.y;
  float current_z = event.acceleration.z;

  // 2. Calculate the magnitude of acceleration (Total force vector)
  float current_magnitude = sqrt(current_x * current_x + current_y * current_y + current_z * current_z);

  // 3. Calculate the change in magnitude since the last reading (General Movement Proxy)
  float last_magnitude = sqrt(last_accel_x * last_accel_x + last_accel_y * last_accel_y + last_accel_z * last_accel_z);
  // The difference between current and previous magnitude is a good indicator of change.
  float delta_magnitude = abs(current_magnitude - last_magnitude);

  // 4. Calculate the rate of change (Fast Movement Proxy)
  // Measures how much the *vector* has changed since the last reading.
  float delta_x = abs(current_x - last_accel_x);
  float delta_y = abs(current_y - last_accel_y);
  float delta_z = abs(current_z - last_accel_z);

  // The magnitude of the change vector (how much the reading jumped)
  float rate_of_change_magnitude = sqrt(delta_x * delta_x + delta_y * delta_y + delta_z * delta_z);


  // 5. --- Detection Logic & State Management ---

  // Reset flags at the start of the loop cycle to check conditions fresh
  bool current_movement_

### User
can yo commbine it with this working code that send messages to another esp? i want it to send "slow down" when it senses the movement is too fast

/*
    MASTER SKETCH: Movement Detector Sender (ESP-NOW) - FINAL VERSION
*/



#include &lt;Wire.h&gt; // Required for I2C communication with most sensors
#include &lt;Adafruit_Sensor.h&gt;
#include &lt;Adafruit_ADXL343.h&gt; 
#include &lt;esp_now.h&gt;
#include &lt;WiFi.h&gt;


// ===============================================================
// 1. GLOBAL CONFIGURATION & OBJECTS (Top of the file)
// ===============================================================


// --- Sensor Object Initialization ---
Adafruit_ADXL343 accel = Adafruit_ADXL343(12345); 


// --- Movement Detection Variables ---
const float MOVEMENT_THRESHOLD = 1; // Tune this value! (Delta magnitude threshold)


// Tracking variables for the previous reading (MUST BE GLOBAL)
float last_accel_x = 0.0;
float last_accel_y = 0.0;
float last_accel_z = 0.0;


// State tracking flag (Controls if we print "DETECTED" or "SUBSIDED")
bool movement_detected_flag = false; 



// --- ESP-NOW MAC ADDRESS & STRUCTURES ---
uint8_t broadcastAddress[] = {0x94, 0xa9, 0x90, 0x6c, 0xd5, 0x9c};


typedef struct struct_message {
    char a[32]; // For status text ("Movement detected" or "Movement subsided")
    int b;      // Integer (e.g., scaled reading)
    float c;    // Float (e.g., magnitude or raw float data)
    bool d;     // Boolean (Movement Detected Flag)
} struct_message;


struct_message myData;


esp_now_peer_info_t peerInfo;



// --- SENSOR VARIABLES (Used by the main loop for calculation) ---
float accelX = 0.0, accelY = 0.0, accelZ = 0.0; // Global variables for sensor readings



// ===============================================================
// 2. CALLBACK FUNCTION (MUST BE GLOBAL)
// ===============================================================
void OnDataSent(const wifi_tx_info_t *txInfo, esp_now_send_status_t status) { 
    Serial.print("\r\n[ESP-NOW Status] Last Packet Send Status:\t");
    Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success" : "Delivery Fail");
}



// ===============================================================
// 3. SETUP FUNCTION (Initialization)
// ===============================================================
void setup() {
    // Initialize Serial Monitor
    Serial.begin(115200);
    
    // Set device as a Wi-Fi Station (Required for ESP-NOW)
    WiFi.mode(WIFI_STA);


    // --- Sensor Initialization ---
    Wire.begin(); // Initialize I2C bus for the sensor
    if(!accel.begin()) {
        Serial.println("ERROR: ADXL343 not found! Check wiring.");
    } else {
        accel.setRange(ADXL343_RANGE_16_G);
        Serial.println("ADXL343 Sensor Initialized Successfully.");
    }


    // 1. INITIALIZE ESP-NOW
    if (esp_now_init() != ESP_OK) {
        Serial.println("Error initializing ESP-NOW");
        return;
    }


    // 2. REGISTER SEND CALLBACK
    esp_now_register_send_cb(OnDataSent);
    
    // 3. CHANNEL SYNCHRONIZATION (CRITICAL FIX!)
    WiFi.setChannel(1); // &lt;-- Use the channel that works for your setup!



    // 4. REGISTER PEER INFO
    memcpy(peerInfo.peer_addr, broadcastAddress, 6);
    peerInfo.channel = 0;  
    peerInfo.encrypt = false;
    
    if (esp_now_add_peer(&peerInfo) != ESP_OK){
        Serial.println("Failed to add peer");
        return;
    }
    Serial.println("\n=========================================");
    Serial.println("Sender Setup Complete. Ready to transmit.");
    Serial.println("=========================================\n");
}



// ===============================================================
// 4. SENSOR READING FUNCTION (Replaces the simulation)
// ===============================================================
void readAccelerometerData() {
    sensors_event_t event;
    if (accel.getEvent(&event)) { // Check if reading was successful
        float current_x = event.acceleration.x;
        float current_y = event.acceleration.y;
        float current_z = event.acceleration.z;


        // Calculate the magnitude of acceleration (Total force vector)
        float current_magnitude = sqrt(current_x * current_x + current_y * current_y + current_z * current_z);


        // Calculate the change in magnitude since the last reading
        float last_magnitude = sqrt(last_accel_x * last_accel_x + last_accel_y * last_accel_y + last_accel_z * last_accel_z);
        float delta_magnitude = abs(current_magnitude - last_magnitude);


        // Update the global variables used by the main loop() logic
        accelX = current_x;
        accelY = current_y;
        accelZ = current_z;
        
        // Return the calculated delta magnitude so we can use it in the loop() state machine
        Serial.printf("Sensor Read: X=%.2f, Y=%.2f, Z=%.2f | Delta Mag: %.2f\n", accelX, accelY, accelZ, delta_magnitude);


    } else {
        Serial.println("ERROR reading sensor data!");
    }
}



// ===============================================================
// 5. MAIN LOOP (State Machine & Sending)
// ===============================================================
void loop() {
    // --- STEP A: Read Sensor Data and Calculate Change ---
    // We must capture the delta magnitude here to use it for state detection
    float current_delta_magnitude;
    readAccelerometerData(); 


    // NOTE: Since readAccelerometerData now prints, we rely on its internal logic 
    // to calculate the necessary values. For simplicity in this final merge, 
    // we will re-calculate the delta here based on the global variables updated above.
    float current_magnitude = sqrt(accelX * accelX + accelY * accelY + accelZ * accelZ);
    float last_magnitude = sqrt(last_accel_x * last_accel_x + last_accel_y * last_accel_y + last_accel_z * last_accel_z);
    current_delta_magnitude = abs(current_magnitude - last_magnitude);



    // --- STEP B: State Change Detection (The core logic) ---
    if (current_delta_magnitude &gt; MOVEMENT_THRESHOLD) {
        if (!movement_detected_flag) {
            // *** TRANSITION: From Still to Moving ***
            Serial.println("\n========================================");
            Serial.println("!!! MOVEMENT DETECTED !!!"); // &lt;-- PRINT ON CHANGE
            Serial.println("========================================\n");


            strcpy(myData.a, "Movement detected"); 
            myData.b = 1;                                     
            myData.c = current_magnitude;                      // Send the actual magnitude
            myData.d = true;                                   



        } else {
             // Already moving: just update payload without printing status text
             strcpy(myData.a, "Movement detected"); 
             myData.b = 1;
             myData.c = current_magnitude;
             myData.d = true;
        }


    } else {
        if (movement_detected_flag) {
            // *** TRANSITION: From Moving to Still ***
            Serial.println("\n========================================");
            Serial.println("!!! MOVEMENT SUBSIDED !!!"); // &lt;-- PRINT ON CHANGE
            Serial.println("========================================\n");


            strcpy(myData.a, "Movement subsided"); 
            myData.b = 0;                                     
            myData.c = current_magnitude;                      // Send the low magnitude
            myData.d = false;                                  
        } else {
             // Still still: just update payload without printing status text
             strcpy(myData.a, "Movement subsided"); 
             myData.b = 0;
             myData.c = current_magnitude;
             myData.d = false;
        }
    }


    // --- STEP C: Send Data (Network Transmission) ---
    esp_err_t result = esp_now_send(broadcastAddress, (uint8_t *) &myData, sizeof(myData));
    
    if (result == ESP_OK) {
        Serial.println("Data packet sent successfully."); 
    } else {
        Serial.println("ERROR: Failed to send data packet."); 
    }


    // --- STEP D: Update State for Next Cycle & Sensor History ---
    movement_detected_flag = (current_delta_magnitude &gt; MOVEMENT_THRESHOLD); // Set flag based on current detection
    last_accel_x = accelX;
    last_accel_y = accelY;
    last_accel_z = accelZ;


    // Wait for a short period to keep the loop responsive but not overwhelming.
    delay(500); 
}

### Assistant
It looks like you are trying to integrate two distinct pieces of logic:

1.  **The original code:** Which uses `Serial.print` statements to alert the user ("slow down" or "movement detected").
2.  **The second block of code (the one provided without context):** Which seems designed for **network transmission** (`esp_now_send`) and handles state changes by updating a structure (`myData`).

Since you want to combine them, I will assume the goal is:

1.  Keep the **Serial Output Logic** from your first block (for immediate feedback).
2.  Integrate the **Network Sending Logic** from your second block (to send data when movement occurs).
3.  Ensure that the state tracking (`movement_detected_flag`, `fast_movement_warning_active`) is maintained correctly for both outputs.

**Crucial Assumptions Made:**

1.  You are using an ESP32/ESP8266 board because of `esp_now_send`.
2.  The variables like `broadcastAddress`, `myData`, and the network setup code (which was missing) are handled correctly in your actual environment, but I will structure the logic flow around them.
3.  I will use the **General Movement Check** (`delta_magnitude`) to trigger both the Serial Alert *and* the Network Send when movement is detected.

Here is the combined and refactored code. I have added placeholders for your network setup parts (like `esp_now_init()`, etc.) where they belong, but you will need to fill in those details based on your full project structure.

### Combined Code Structure

```cpp
#include &lt;Wire.h&gt;
#include &lt;Adafruit_Sensor.h&gt;
#include &lt;Adafruit_ADXL343.h&gt;

// --- NETWORK/BLUETOOTH PLACEHOLDERS (YOU MUST DEFINE THESE) ---
// Assuming you are using ESP-NOW for transmission
#define BROADCAST_ADDRESS "AA:BB:CC:DD:EE:FF" // Replace with your actual broadcast address
struct DataPayload {
    char a[30]; // Status message
    int b;      // Movement flag (1=Active, 0=Inactive)
    float c;    // Magnitude reading
    bool d;     // Overall movement status
};

DataPayload myData;
// Placeholder for network setup functions (e.g., esp_now_init(), etc.)
// void sendNetworkData() { ... } 


/* Assign a unique ID to this sensor at the same time */
Adafruit_ADXL343 accel = Adafruit_ADXL343(12345);

// --- Movement Detection Variables ---

// Thresholds (Tune these values!)
const float MOVEMENT_THRESHOLD = 0.8; // General movement detection threshold
const float FAST_MOVEMENT_THRESHOLD = 1.5; // Fast movement warning threshold

// Tracking variables for the previous reading
float last_accel_x = 0.0;
float last_accel_y = 0.0;
float last_accel_z = 0.0;

// Variables to track the state of the alerts
bool movement_detected_flag = false;
bool fast_movement_warning_active = false;


void setup(void)
{
    Serial.begin(9600);
    while (!Serial);
    Serial.println("ADXL343 Movement Detector Initializing..."); Serial.println("");

    // --- NETWORK SETUP (MUST BE ADDED HERE) ---
    // Example: esp_now_init(); 
    // Example: esp_now_add_peer(broadcastAddress, ...);


    /* Initialise the sensor */
    if(!accel.begin())
    {
        Serial.println("Ooops, no ADXL343 detected ... Check your wiring!");
        while(1);
    }

    /* Set the range to whatever is appropriate for your project */
    accel.setRange(ADXL343_RANGE_16_G);

    Serial.println("ADXL343 initialized. Ready to detect movement.");
}


void loop(void)
{
    // 1. Read the current sensor data
    sensors_event_t event;
    accel.getEvent(&event);

    float current_x = event.acceleration.x;
    float current_y = event.acceleration.y;
    float current_z = event.acceleration.z;

    // 2. Calculate the magnitude of acceleration (Total force vector)
    float current_magnitude = sqrt(current_x * current_x + current_y * current_y + current_z * current_z);

    // 3. Calculate the change in magnitude since the last reading (General Movement Proxy)
    float last_magnitude = sqrt(last_accel_x * last_accel_x + last_accel_y * last_accel_y + last_accel_z * last_accel_z);
    float delta_magnitude = abs(current_magnitude - last_magnitude);

    // 4. Calculate the rate of change (Fast Movement Proxy)
    float delta_x = abs(current_x - last_accel_x);
    float delta_y = abs(current_y - last_accel_y);
    float delta_z = abs(current_z - last_accel_z);
    float rate_of_change_magnitude = sqrt(delta_x * delta_x + delta_y * delta_y + delta_z * delta_z);

    // --- STATE MANAGEMENT & OUTPUTS ---

    // 5. A. Fast Movement Check (Serial Alert)
    if (rate_of_change_magnitude &gt; FAST_MOVEMENT_THRESHOLD) {

