Struggling to Parse accelerometer data

I’ve been trying to get the sparkfun accelerometer kx132 to sense motion and use that motion to trigger continuous scanning using the m6e rfid module then print everything over serial.

Ive gotten the M6e portion down and i keep thinking the accelerometer portion will work but im not doing something right.

any suggestions?

#include <Wire.h>

#include <SoftwareSerial.h>

#include “SparkFun_UHF_RFID_Reader.h” // RFID reader library

#include “SparkFun_KX13X.h” // KX13X library for the accelerometer

#include “SparkFun_Qwiic_KX13X.h” // KX13X library for the accelerometer

SoftwareSerial softSerial(2, 3); // RX, TX pins for SoftwareSerial

RFID nano; // Create an instance of the RFID reader

SparkFun_KX132 kxAccel; // Create an instance of the KX132 accelerometer

// Constants for configuration

const long BAUD_RATE_NANO = 38400;

const long BAUD_RATE_SERIAL = 115200;

const byte SERIAL_TIMEOUT_MS = 250; // Timeout for serial communication

const int READ_POWER = 500; // 5.00 dBm read power

const byte EPC_BYTE_OFFSET = 31; // Offset for EPC bytes in response

const float MOTION_THRESHOLD = 0.2; // Threshold for considering motion detected, in ‘g’

// Scanning and motion state control

bool isScanning = false;

unsigned long lastMotionDetectedTime = millis(); // Initialize to start of program

// Function declarations

boolean setupNano(long baudRate);

void printTagDetails();

void checkForMotion();

void setup() {

Serial.begin(BAUD_RATE_SERIAL);

while (!Serial) delay(10); // Wait for the serial port to come online

softSerial.begin(BAUD_RATE_NANO);

if (!setupNano(BAUD_RATE_NANO)) {

Serial.println(F(“Module failed to respond. Please check wiring.”));

return; // Exit setup on failure

}

Wire.begin(); // Initialize I2C for the accelerometer

if (!kxAccel.begin()) {

Serial.println(“KX132 not detected. Please check wiring. Freezing…”);

while (1); // Infinite loop to halt further execution

}

kxAccel.setRange(SFE_KX132_RANGE2G); // Set accelerometer range

kxAccel.setOutputDataRate(KX132_ODR_25HZ); // Set data rate

Serial.println(“Setup complete. Send ‘Motion’ to detect motion or ‘Stop’ to end.”);

}

void loop() {

checkForMotion();

if (Serial.available() > 0) {

String command = Serial.readStringUntil(‘\n’);

command.trim(); // Remove any whitespace

if (command.equalsIgnoreCase(“Motion”) && !isScanning) {

lastMotionDetectedTime = millis(); // Reset motion detection timer

isScanning = true;

Serial.println(F(“Manual motion trigger. Scanning started.”));

} else if (command.equalsIgnoreCase(“stop”)) {

isScanning = false;

Serial.println(F(“Scanning stopped.”));

}

}

if (isScanning && nano.check()) {

if (nano.parseResponse() == RESPONSE_IS_TAGFOUND) {

printTagDetails();

}

}

}

void checkForMotion() {

rawOutputData rawData; // Struct to hold raw accelerometer data

if (myAccel.getRawAccelData(&rawData)) {

// Calculate magnitude of acceleration vector and subtract 1G for gravity’s effect

float magnitude = sqrt(pow(rawData.xData, 2) + pow(rawData.yData, 2) + pow(rawData.zData, 2)) / 16384.0 - 1.0; // Assuming 16384 is scale for 1G in 2G range

if (magnitude > MOTION_THRESHOLD) {

lastMotionDetectedTime = millis(); // Update last motion detected time

if (!isScanning) {

isScanning = true;

Serial.println(F(“Motion detected. Scanning started.”));

// Add code to start RFID scanning

}

} else if (isScanning && (millis() - lastMotionDetectedTime > 900000)) { // 15 minutes with no motion

isScanning = false;

Serial.println(F(“No motion detected for 15 minutes. Scanning stopped.”));

// Add code to stop RFID scanning

}

}

}

boolean setupNano(long baudRate) {

nano.begin(softSerial); // Start communication via software serial

while (!softSerial.isListening()); // Wait for port to open

// Clear buffer from any noise or messages

while (softSerial.available()) softSerial.read();

nano.getVersion();

if (nano.msg[0] == ERROR_WRONG_OPCODE_RESPONSE) {

nano.stopReading();

Serial.println(F(“Module continuously reading. Asking it to stop…”));

delay(1500); // Allow time for the module to stop reading

} else {

softSerial.begin(BAUD_RATE_SERIAL);

nano.setBaud(baudRate);

softSerial.begin(baudRate); // Switch software serial to new baud rate

delay(SERIAL_TIMEOUT_MS);

}

// Verify connection

nano.getVersion();

if (nano.msg[0] != ALL_GOOD) return false; // Connection issue

nano.setTagProtocol(); // Set protocol to GEN2

nano.setAntennaPort(); // Set antenna ports

return true; // Ready to proceed

}

void printTagDetails() {

int rssi = nano.getTagRSSI(); // RSSI

long freq = nano.getTagFreq(); // Frequency

long timeStamp = nano.getTagTimestamp(); // Timestamp

byte tagEPCBytes = nano.getTagEPCBytes(); // EPC bytes count

Serial.print(F("RSSI: “)); Serial.print(rssi); Serial.print(F(”, "));

Serial.print(F("Freq: ")); Serial.print(freq); Serial.print(F("Hz, "));

Serial.print(F("Time: “)); Serial.print(timeStamp); Serial.print(F(”, "));

Serial.print(F("EPC: "));

for (byte i = 0; i < tagEPCBytes; i++) {

if (nano.msg[EPC_BYTE_OFFSET + i] < 0x10) Serial.print(F(“0”));

Serial.print(nano.msg[EPC_BYTE_OFFSET + i], HEX); Serial.print(F(" "));

}

Serial.println();

}

You forgot to describe the actual problem.

My approach would be to write a short program that just reads the accelerometer data, detects “motion” and reports that on the serial monitor. The code below is overly complicated and only half correct:

float magnitude = sqrt(pow(rawData.xData, 2) + pow(rawData.yData, 2) + pow(rawData.zData, 2)) / 16384.0 - 1.0; // Assuming 16384 is scale for 1G in 2G range

if (magnitude > MOTION_THRESHOLD) {

(1) there is no need to convert to g values. Just use the raw data, drop the square root and set the threshold in (raw units)^2.

(2) motion can result in a total acceleration of less than 1 g, if the acceleration due to external forces counters the acceleration due to gravity. In free fall, the total acceleration is close to zero.