#include <H3LIS331DL.h>
#include <Wire.h>
#define VAL_X_AXIS 203
#define VAL_Y_AXIS 165
#define VAL_Z_AXIS 371
H3LIS331DL h3lis;
const float threshold = 3.0; // Порог для удара (g)
const float noiseFloor = 0.2; // Уровень отсечки шума
const float hysteresis = 2.0; // Гистерезис для устранения дребезга
float prevZ = 0;
bool peakDetected = false;
unsigned long lastPeakTime = 0;
unsigned long lastStrikeTime = 0;
const unsigned long debounceTime = 50; // Минимальное время между ударами
const unsigned long resetTimeout = 100; // Сброс флага пика
void setup() {
Serial.begin(115200);
Wire.begin();
// Инициализация H3LIS331DL с диапазоном ±400g
h3lis.init(H3LIS331DL_ODR_1000Hz, H3LIS331DL_NORMAL);
h3lis.setFullScale(400);
h3lis.importPara(VAL_X_AXIS, VAL_Y_AXIS, VAL_Z_AXIS);
Serial.println("H3LIS331DL найден!");
}
void loop() {
unsigned long now = millis();
double acc[3];
h3lis.getAcceleration(acc);
float accZ = acc[2];
// Игнорируем мелкий шум
if (abs(accZ - prevZ) < noiseFloor) {
prevZ = accZ;
return;
}
// Условие пика: значение уменьшилось, предыдущее было выше порога
if ((accZ + hysteresis < prevZ) && prevZ > threshold && !peakDetected) {
if (now - lastStrikeTime > debounceTime) {
int peakInt = (int)(prevZ + 0.5); // Быстрое округление
Serial.print("Пик удара: ");
Serial.println(peakInt);
if (lastStrikeTime > 0) {
float interval = (now - lastStrikeTime) / 1000.0;
float bpm = 60.0 / interval;
Serial.print("BPM: ");
Serial.println(bpm, 1); // 1 знак после запятой
}
lastStrikeTime = now;
peakDetected = true;
lastPeakTime = now;
}
}
// Сброс пикового флага
if (peakDetected && (now - lastPeakTime > resetTimeout)) {
peakDetected = false;
}
prevZ = accZ;
}