Привет.
После сборки перчатки я столкнулся с двумя проблемами. Хочу поделиться своими способами их решений. Может быть, кому-то пригодиться.
1) Ошибки кода
После заливки кода на плату, светодиод начинал просто мигать и никак не реагировал на какие-либо движения. Версия среды разработки никак на это не влияла. После нескольких дней танцев с бубном я понял, что почему-то не работают функции i2cWrite и i2cRead. Поэтому код пришлось немного модифицировать. Сейчас все работает на отлично, и контроллер прошивается через последнюю версию среды разработки без каких-либо ошибок.
int light = 500; // задержка, свет включен, микросекунд
int dark; // свет выключен, микросекунды
int min_dark = 1; // миминмальнаЯ задержка темноты
int max_dark = 50; // максимальнаЯ задержка темноты
#define light_pin 2 // сюда подключен свет
#define potent_pin 6 // аналоговый пин потенциометра
int angle;
boolean flag;
long lastchange;
#include <Wire.h>
#include "Kalman.h"
Kalman kalmanX;
Kalman kalmanZ;
const int MPU_addr = 0x68; // I2C address of the MPU-6050
int16_t accX;
int16_t accY;
int16_t accZ;
int16_t tempRaw;
int16_t gyroX;
int16_t gyroY;
int16_t gyroZ;
double accXangle; // Angle calculate using the accelerometer
double accZangle;
double temp;
double gyroXangle = 180; // Angle calculate using the gyro
double gyroZangle = 180;
double compAngleX = 180; // Calculate the angle using a Kalman filter
double compAngleZ = 180;
double kalAngleX; // Calculate the angle using a Kalman filter
double kalAngleZ;
uint32_t timer;
void setup() {
Wire.begin();
pinMode(light_pin, OUTPUT);
Wire.beginTransmission(MPU_addr);
Wire.write(0x6B); // PWR_MGMT_1 register
Wire.write(0); // set to zero (wakes up the MPU-6050)
Wire.endTransmission(); // (true)
kalmanX.setAngle(180); // Set starting angle
kalmanZ.setAngle(180);
timer = micros();
}
void loop() {
measure();
if (accZ > 25000 && (millis() - lastchange > 300)) { // если ускорение по оси Z больше порогового
flag = !flag; // переключить свет
lastchange = millis(); // запомнить времЯ (чтобы сразу не выключилсЯ свет)
}
//flag=1;
if (flag == 1) {
angle = 250 - kalAngleZ; // вычислЯем угол, сделав поправку на 250 градусов
dark = map(analogRead(potent_pin), 0, 1024, min_dark, max_dark); //расчет времени темноты как сумму угла с датчика угла и значениЯ с потенциометра
digitalWrite(light_pin, 1); // включаем свет
delayMicroseconds(light); // ждем
digitalWrite(light_pin, 0); // выключаем
delay(dark);
delayMicroseconds(2000 + angle * 10); // ждем
}
}
void measure() {
Wire.beginTransmission(MPU_addr);
Wire.write(0x3B);
Wire.endTransmission(false);
Wire.requestFrom(MPU_addr,14);
accX=Wire.read()<<8|Wire.read();
accY=Wire.read()<<8|Wire.read();
accZ=Wire.read()<<8|Wire.read();
tempRaw=Wire.read()<<8|Wire.read();
gyroX=Wire.read()<<8|Wire.read();
gyroY=Wire.read()<<8|Wire.read();
gyroZ=Wire.read()<<8|Wire.read();
accZangle = (atan2(accX, accY) + PI) * RAD_TO_DEG;
accXangle = (atan2(accY, accX) + PI) * RAD_TO_DEG;
double gyroXrate = (double)gyroX / 131.0;
double gyroZrate = -((double)gyroZ / 131.0);
gyroXangle += kalmanX.getRate() * ((double)(micros() - timer) / 1000000); // Calculate gyro angle using the unbiased rate
gyroZangle += kalmanZ.getRate() * ((double)(micros() - timer) / 1000000);
kalAngleX = kalmanX.getAngle(accXangle, gyroXrate, (double)(micros() - timer) / 1000000); // Calculate the angle using a Kalman filter
kalAngleZ = kalmanZ.getAngle(accZangle, gyroZrate, (double)(micros() - timer) / 1000000);
timer = micros();
}
2) Плата BMS
Через непродолжительно время при подключении питания к модулю питания плата уходила в защиту. В интернете есть множество различных способов, как обойти защиту у BMS. Мне помогла установка пленочного конденсатора 2A223J на 0.022 мкФ. На фото выделил место, куда припаял конденсатор (у меня плата на 4 аккумулятора).