#include "FastIMU.h"
#include "Madgwick.h"
#include "EEPROM.h"
#include <Wire.h>
// Для STM32 официального ядра вместо HID.h используем встроенные средства
#include <USBHID.h>
#define IMU_ADDRESS 0x68
MPU6050 IMU;
#define IMU_GEOMETRY 0
#define FILTER_MAX_BETA 0.15
#define FILTER_MIN_BETA 0.015
#define FILTER_DROPOFF 0.85
calData calib = { 0 };
AccelData IMUAccel;
GyroData IMUGyro;
MagData IMUMag;
GyroData GyroVel;
Madgwick filter;
bool flag = false;
// HID-дескриптор для SteamVR (Relativty)
static const uint8_t _hidReportDescriptor[] = {
0x06, 0x03, 0x00, 0x09, 0x00, 0xa1, 0x01, 0x15, 0x00, 0x26, 0xff, 0x00,
0x85, 0x01, 0x75, 0x08, 0x95, 0x3f, 0x09, 0x00, 0x81, 0x02, 0xc0
};
float quat[4];
uint8_t reportBuffer[63];
USBHID HIDDevice; // Создаем объект HID для STM32
void setup() {
// Настройка I2C для STM32 (Blue Pill: PB6 - SCL, PB7 - SDA)
Wire.setSDA(PB7);
Wire.setSCL(PB6);
Wire.begin();
Wire.setClock(400000);
Serial.begin(115200);
// Инициализация USB HID для STM32
HIDDevice.begin(_hidReportDescriptor, sizeof(_hidReportDescriptor));
int calStatus = 0;
EEPROM.get(100, calStatus);
if (calStatus == 99) {
EEPROM.get(200, calib);
}
IMU.setIMUGeometry(IMU_GEOMETRY);
int err = IMU.init(calib, IMU_ADDRESS);
if (err != 0) {
while(!Serial) { delay(10); }
Serial.print("Error! IMU not found: ");
Serial.println(err);
while (true) { delay(100); }
}
filter.begin(2.0f);
for (int i = 0; i < 2000; i++) {
IMU.update();
IMU.getAccel(&IMUAccel);
IMU.getGyro(&IMUGyro);
filter.updateIMU(IMUGyro.gyroX, IMUGyro.gyroY, IMUGyro.gyroZ, IMUAccel.accelX, IMUAccel.accelY, IMUAccel.accelZ);
}
}
void loop() {
// Калибровка через сериал
if (Serial.available() > 0 && Serial.read() == 'y') {
calib = { 0 };
IMU.init(calib, IMU_ADDRESS);
Serial.println("Calibrating...");
delay(5000);
IMU.calibrateAccelGyro(&calib);
EEPROM.put(200, calib);
EEPROM.put(100, 99);
Serial.println("Done! Resetting...");
delay(1000);
NVIC_SystemReset();
}
IMU.update();
IMU.getAccel(&IMUAccel);
IMU.getGyro(&IMUGyro);
float Av = GyroVel.gyroX * GyroVel.gyroX + GyroVel.gyroY * GyroVel.gyroY + GyroVel.gyroZ * GyroVel.gyroZ;
if (Av > 100.f) Av = 100.f;
filter.changeBeta(Av * (FILTER_MAX_BETA - FILTER_MIN_BETA) / 100 + FILTER_MIN_BETA);
filter.updateIMU(IMUGyro.gyroX, IMUGyro.gyroY, IMUGyro.gyroZ, IMUAccel.accelX, IMUAccel.accelY, IMUAccel.accelZ);
quat[0] = filter.getQuatW();
quat[1] = filter.getQuatX();
quat[2] = filter.getQuatY();
quat[3] = filter.getQuatZ();
// Отправка данных в драйвер SteamVR
memset(reportBuffer, 0, sizeof(reportBuffer));
memcpy(reportBuffer, quat, sizeof(quat));
HIDDevice.sendReport(1, reportBuffer, 63);
}