ARDUINO Перчатка времени

  • У нас появились СТАТЬИ! Левая кнопка в меню навигации. Любую тему можно преобразовать в статью (в настройках темы И при её создании): первое сообщение станет текстом статьи, а остальные - комментариями. На форуме много достойных тем, думаю стоит навести порядок в первом сообщении с учётом всех остальных постов, красиво оформить и перевести их в статьи. Хорошие темы должны быть на "витрине"! Данное объявление можно отключить крестиком (куки должны быть включены)

AlexGyver

★★★★★✩✩
Команда форума
30 Июл 2018
124
378
Ветка обсуждения проекта Перчатка времени.
Страница проекта на AlexGyver.ru: https://alexgyver.ru/time_glove/
Видео:

Делитесь своими вариантами изготовления, модификациями и улучшениями!
 
  • Лойс +1
Реакции: Potapov

Sanysiro

✩✩✩✩✩✩✩
10 Май 2019
2
0
Привет.
После сборки перчатки я столкнулся с двумя проблемами. Хочу поделиться своими способами их решений. Может быть, кому-то пригодиться.

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 аккумулятора).
 

Вложения

Plugway

✩✩✩✩✩✩✩
17 Авг 2019
1
0
Прив всем. Наконец то собрал перчатку спустя 2 с лишним года. И в итоге я убрал акселерометр, поставил вместо него oled дисплей и сделал управление полностью на потенциометрах и одной кнопочке. Ниже прикрепляю переписанный скетч и схему подключения.
---------------------
Внимание!
Существует 2 вида прошивки и в одном из них регулируется световая задержка, а в другом нет(соответственно 3 и 2 потенциометра используется).
---------------------
Сначала об аккумуляторе:
Засунул 3 литиевых банки в холдер и сверху поставил плату BMS 3s на 25А и выключатель последовательно выходу. Так как у повышающего модуля по входу стоит конденсатор, пришлось поставить параллельно входу конденсатор на 35в 2000мкф(можно и на 16в и не менее 1000мкф) чтобы плата не уходила в защиту.
О повышающем модуле:
Заменил конденсаторы на 63 вольта 1000 мкф(желательно на 50в 1000мкф, потому что они идеально влезают). Приклеил на термосопли 3(2 для версии без регулировки световой задержки) адресных светодиода для индикации(потому что они у меня были).
Об ардуинке:
Помимо всех подключений поставил делитель напряжения Vin-A6-gnd для отображения заряда батареи на дисплее.
Об информации на дисплее:
1. Для 2 потенциометров:
Сверху слева Freq - частота, с которой мерцает светодиод в герцах, правее Stat - состояние светодиода(вкл или выкл), в нижней строке Battery - заряд батареи.
2. Для 3 потенциометров:
Сверху слева Freq - частота, с которой мерцает светодиод в герцах, правее Stat - состояние светодиода(вкл или выкл), в нижней строке L - сначала проценты - это процент времени от всего периода когда свет включен, после слеша - световая задержка в микросекундах. Далее B - заряд батареи.
О настройке делителя напряжения для измерения заряда:
Нужно подобрать делитель таким образом чтобы при вольтах 13 на аналоговом пине было не более 5 вольт. После нужно настроить на понижающем преобразователе напряжение полного заряда батареи и посмотреть среднее значение с аналогового порта и указать его как верхний предел функции map(сами разберетесь где). Так же выставляем нижний предел.
IMG_20190818_135334.jpg
IMG_20190818_135310.jpg
IMG_20190818_135257.jpgIMG_20190818_135231.jpgIMG_20190818_135206.jpg
IMG_20190818_135156.jpg
 

Вложения