Quantcast
Channel: Sensors - Arduino Forum
Viewing all articles
Browse latest Browse all 1072

ADXL345 punch level detection

$
0
0

I have this state machine to detect three levels of punch impacts on a wall-mounted PU-mat (no scientific project), using two thresholds and two yellow and red LEDs (later there will be three thresholds and three LEDs). The trouble is that with a strong impact, the lower threshold is crossed first, hence both LEDs light up, but only the second one should. Is there some method to code for waiting if after thresholdA is crossed thresholdB is also crossed right after, to then light up only the red LED?

How should I solve this issue? Thanks for some ideas.


#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_ADXL345_U.h>

Adafruit_ADXL345_Unified accel = Adafruit_ADXL345_Unified(12345);

const float alphaEMA = 0.3;
const float valueShift = 8.8;
const float thresholdA = 7;
const float thresholdB = 21;

const byte pinLEDY = 12;
const byte pinLEDR = 13;
const int timeLEDOn = 150;

enum State {BELOW_A, ABOVE_A, ABOVE_B};
State systemState = BELOW_A;

// Variables that can change
float ax = 0;
float ay = 0;
float az = 0;
float mAV = 0;
float mAVEMA = 9.81;

unsigned long timeLEDYOn = 0;
unsigned long timeLEDROn = 0;

void setup()
{
  Serial.begin(115200);

  pinMode(pinLEDY, OUTPUT);
  pinMode(pinLEDR, OUTPUT);

  digitalWrite(pinLEDY, LOW);
  digitalWrite(pinLEDR, LOW);

  accel.begin();

  accel.setRange(ADXL345_RANGE_8_G);
  accel.setDataRate(ADXL345_DATARATE_25_HZ); // Sampling rate too high for this purpose?
}

void loop()
{
  unsigned long timeNow = millis();

  sensors_event_t event;
  accel.getEvent(&event);

  ax = event.acceleration.x;
  ay = event.acceleration.y;
  az = event.acceleration.z;

  mAV = abs(sqrt(ax * ax + ay * ay + az * az) - valueShift); // Rectify and base on 0

  mAVEMA = (alphaEMA * mAV) + ((1 - alphaEMA) * mAVEMA);

  Serial.print("mAVEMA:"); Serial.println(mAVEMA);

  switch (systemState)
  {
    case BELOW_A:
      if (mAVEMA > thresholdA && mAVEMA < thresholdB)
      {
        systemState = ABOVE_A;
        timeLEDYOn = timeNow;
        digitalWrite(pinLEDY, HIGH);
      }
      else if (mAVEMA >= thresholdB)
      {
        systemState = ABOVE_B;
        timeLEDROn = timeNow;
        digitalWrite(pinLEDY, LOW);
        digitalWrite(pinLEDR, HIGH);
      }
      break;

    case ABOVE_A:
      if (mAVEMA > thresholdB)
      {
        systemState = ABOVE_B;
        timeLEDROn = timeNow;
        digitalWrite(pinLEDY, LOW);
        digitalWrite(pinLEDR, HIGH);
      }
      else if (mAVEMA <= thresholdA)
      {
        systemState = BELOW_A;
      }
      break;

    case ABOVE_B:
      if (mAVEMA <= thresholdA)
      {
        systemState = BELOW_A;
      }
      else if (mAVEMA < thresholdB && mAVEMA > thresholdA)
      {
        systemState = ABOVE_A;
      }
      break;
  }

  if (digitalRead(pinLEDY) == HIGH && timeNow - timeLEDYOn >= timeLEDOn)
  {
    digitalWrite(pinLEDY, LOW);
  }

  if (digitalRead(pinLEDR) == HIGH && timeNow - timeLEDROn >= timeLEDOn)
  {
    digitalWrite(pinLEDR, LOW);
  }

  delay(10); // Only for the serial plotter
}

11 posts - 3 participants

Read full topic


Viewing all articles
Browse latest Browse all 1072

Trending Articles