Акселерометр GY-521. Определение факта удара.

Allleksey
Offline
Зарегистрирован: 28.11.2020

Коллеги, приветствую!

Вот такой вопрос у меня возник. Есть акселерометр GY-521 c MPU5060 на борту. С модуля читаем данные акселерометра. Они, естественно плавно изменяются при изменении угла наклона модуля по осям. Но вот есть у меня задачка, получить подтверждение наличия удара, т.е. при резком изменении показаний акселерометра получить флаг удара. И вот никак не могу придумать код для этого (уж простите не грамотного, в схемах еще немного понимаю, а вот в программировании совсем новичок).

Задач, по большому счету, в определении резкого изменения уровня сигнала с модуля. Если я правильно понимаю, что от силы удара будет зависеть крутизна переднего фронта. Т в программном коде нужно предусмотреть настройку силы удара, при котором устанавливается флаг удара.

Если провести аналогию, то нужно получить сигнал как на сигнализации машины. Ударили по кузову, получили предупреждение от сигнализации. Сила удара настраивается программно.

Натолкните на мысль, как сие реализовать. Спасибо большое.

rkit
Offline
Зарегистрирован: 23.11.2016

Моментальный вектор ускорения больше порога.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Точнее - длина вектора.

Densl
Offline
Зарегистрирован: 28.11.2018

Надо считывать ускорение и когда оно резко стало отрицательным по нужной вам оси, значит был удар в этом направлении.

Берете пример в  котором вычисляется это ускорение ищите нужную вам ось, по которой отслеживаете удар, и с помощью не хитрых расчетов в коде с этой переменной получаете нужный вам результат.

vlad072
Offline
Зарегистрирован: 01.08.2017

Не уверен что хорошая идея фиксировать удар акселерометром, это немного из другой оперы. Кстати когда то тоже посещали такие мысли, но вникнув в тему понял, что это тупик. Для получения сигнала о мех. вибрации (ударе) используют пьезоэлектрические датчики с усилителем-компаратором, а для надёжного детектирования регистры прерываний или внешние триггеры.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

А почему не подходит обычный датчик вибрации (которые, кстати, и используются в автосигнализациях)?

Allleksey
Offline
Зарегистрирован: 28.11.2020

В акселерометре можно выполнить программное регулирование силы регистрируемого удара. Датчики вибрации, которые я встречал, имею потенциометр на борту и не позволяют настраивать программно чувствительность. Возможно не видел датчиков с электронной регулировкой, если подскажете, какой можно использовать для решения вопроса, буду признателен.

rkit
Offline
Зарегистрирован: 23.11.2016

Проще акселерометра некуда уж. Школьная геометрия и 5 строчек кода.

Allleksey
Offline
Зарегистрирован: 28.11.2020

С тригонометрией школьного курса то вопросов нет. Посчитать результирующий вектор по трем осям не сложно. В результате вычислений получаем некие цифры. И вот тут начинается самое интересное, это те самые 5 строчек кода.

Более детально рассказываю о задаче. Блок должен стоять на автомобиле. (сын получил права и начинает ездит). Я, как его отец, переживаю за него, и хочу знать, если с ним что то случится. Так вот блок должен работать при заведенном двигателе и в случае обнаружения удара (что, скорее всего, будет при попадании в аварию), отправлять СМС на мой номер с координатами автомобиля. Эдакая Эра Глонас, но с информированием на мой номер телефона.

И тут возникает сложность в том, что в движении машина так же вибрирует. Нужно настроить так, что бы на штатные вибрации датчик не реагировал, а срабатывал только при настроенной перегрузке, например при 4g. И тут уже 5 строками кода не получится ограничится (по крайней мере я не понимаю, как это сделать) и по этому обратился к уважаемым участникам форума за советом и подсказками.

Bruzzer
Offline
Зарегистрирован: 17.03.2020

Соберите устройство, проведите измерения - сигнал при вибрации, сигнал при имитации удара. Может быть станет ясно, как их отличать.

rkit
Offline
Зарегистрирован: 23.11.2016

"Самое интересное" это самая простая из 5 строчек кода? Ну-ну.

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

Вибрация не проблема, а вот отличить легкую аварию от экстренного торможения будет достаточно сложно. Если же СМС требуется посылать только в случае серьезных проблем, то я бы снимал сигнал с подушки безопасности

Allleksey
Offline
Зарегистрирован: 28.11.2020

Ребенок будет учиться на детище Российского автопрома. Не факт, что там будет подушка (пока еще не определились на марке автомобиля). По этому есть желание сделать универсальный прибор.

Да и у экстренного торможения фронт нарастания ускорения будем медленнее, чем у аварии. По этому я изначально и говорил не только о величине результирующего вектора по трем осям, но и скорости его увеличения, т.е. следить нужно за размером и за динамикой изменения вектора.

Allleksey
Offline
Зарегистрирован: 28.11.2020

Схему для себя пока определил вот такую. Возможно будет меняться со временем и в процессе... (JP1 на схеме - конструктивный элемент как перемычка на плате. Возможно есть и другие варианты поставить перемычки на односторонней плате в программе, но я их пока не знаю).

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

Allleksey пишет:

Ребенок будет учиться на детище Российского автопрома. Не факт, что там будет подушка (пока еще не определились на марке автомобиля). По этому есть желание сделать универсальный прибор.

Да и у экстренного торможения фронт нарастания ускорения будем медленнее, чем у аварии. По этому я изначально и говорил не только о величине результирующего вектора по трем осям, но и скорости его увеличения, т.е. следить нужно за размером и за динамикой изменения вектора.

Перед аварией в большинстве случаев, таки, тормозят.А корпус сминается достаточно плавно при небольших авариях. Без проведения экспериментов с битьем критерии подобрать будет трудно. А вот при серьезном ударе модуль вектора будет больше любой вибрации или экстренного торможения. Я бы собрал схему, подключил все к лаптопу для постоянного сохранения логов, и поездил несколько дней поэкстремальнее. Потом найти максимум модуля ускорения добавить к нему процентов 20-30 и считать это за порог срабатывания.

 

PS А координаты откуда брать будете?

rkit
Offline
Зарегистрирован: 23.11.2016

Allleksey пишет:

 фронт нарастания ускорения будем медленнее, чем у аварии.

Какой кошмарный набор слов. Еще раз: удар это когда длина вектора ускорения больше порога. Всё.

Allleksey
Offline
Зарегистрирован: 28.11.2020

По координатам пока еще не придумал. Решать вопросы буду по мере их поступления. Сначала надо решить вопрос с акселерометром.

Вообще рассматриваю GY-NEO6MV2

Allleksey
Offline
Зарегистрирован: 28.11.2020

rkit пишет:

Еще раз: удар это когда длина вектора ускорения больше порога. Всё.

Максимальная длина вектора при торможении и ударе может быть одинаковой. А вот скорость изменения ускорения при ударе значительно выше. Ну не может машина начать моментально тормозить, а удар, это, все же, резкое изменение ускорения. Возможно не прав в своих умозаключениях. 

Пы.Сы. Уж извините за манеру изложения. Хотел передать мысли и соображения, но получилось кривовато :)

rkit
Offline
Зарегистрирован: 23.11.2016

Allleksey пишет:

Максимальная длина вектора при торможении и ударе может быть одинаковой. А вот скорость изменения ускорения при ударе значительно выше.

Нет, не будет. Ты путаешь скорость и ускорение.

Allleksey
Offline
Зарегистрирован: 28.11.2020

Вот так, наверное, будет выглядеть схема с GPS модулем.

sadman41
Offline
Зарегистрирован: 19.10.2016

Рассмотрите вариант с 328PB - в ней 2 UART, будет в отладке проще.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Пьеза всё таки попроще будет видимо, особенно для тазиков с их шумоизоляцией, а может + пьеза...

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Allleksey пишет:

В акселерометре можно выполнить программное регулирование силы регистрируемого удара. Датчики вибрации, которые я встречал, имею потенциометр на борту и не позволяют настраивать программно чувствительность. Возможно не видел датчиков с электронной регулировкой, если подскажете, какой можно использовать для решения вопроса, буду признателен.

Выше уже рекомендовали - пьезодатчики.

По крайней мере в электронных ударных установках (электронных барабанах) они вполне обеспечивают динамику, т.е. чувствительность к силе удара (которая по стандарту MIDI должна иметь 128 градаций).

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

asam пишет:

Вибрация не проблема, а вот отличить легкую аварию от экстренного торможения будет достаточно сложно. Если же СМС требуется посылать только в случае серьезных проблем, то я бы снимал сигнал с подушки безопасности

Как раз тут проблем нет, при экстренном торможении a < g*k, где k - коэффициент порядка 1 (можно с запасом взять 1.5). А при аварии ускорение существенно больше. Нужно только расположить датчик вдали от источников вибрации.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

asam пишет:

Я бы собрал схему, подключил все к лаптопу для постоянного сохранения логов, и поездил несколько дней поэкстремальнее. Потом найти максимум модуля ускорения добавить к нему процентов 20-30 и считать это за порог срабатывания.

Вот, кстати, очень полезная мысль. Только для логов лэптоп необязателен - вести логи на SD может и сама Ардуина.

rkit
Offline
Зарегистрирован: 23.11.2016

andriano пишет:

Выше уже рекомендовали - пьезодатчики.

По крайней мере в электронных ударных установках (электронных барабанах) они вполне обеспечивают динамику, т.е. чувствительность к силе удара (которая по стандарту MIDI должна иметь 128 градаций).

Барабанная установка работает в одной оси, а тут нужно 3, и даже если сколхозить три пьезо - совмещение результатов гораздо менее тривиальное.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

rkit пишет:

Барабанная установка работает в одной оси, а тут нужно 3, и даже если сколхозить три пьезо - совмещение результатов гораздо менее тривиальное.

Да, такое имеет место.

Но, с другой стороны, по моим прикидкам 328 вполне успевает обработать 4 барабана, а для автомобиля характерные времена, вроде как, должны быть побольше.

Та к что: нетривиальность - да, невозможность - нет.

 

PS. И "ось" - это про гироскоп, а для акселерометра - "измерение".

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

andriano пишет:

По крайней мере в электронных ударных установках (электронных барабанах) они вполне обеспечивают динамику, т.е. чувствительность к силе удара (которая по стандарту MIDI должна иметь 128 градаций).

мне по душе больше аналог )))

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

ua6em пишет:

мне по душе больше аналог )))

Ничего удивительного (даже не обращая внимания на "изюминку" этого видео). На самом деле - создание качественного электронного аналога барабана - задача нетривиальная. Удовлетворительная реализация зависимости тембра звука от места удара по барабану пока не создана. Возможно, потому, что не укладывается в стандарт MIDI.

Allleksey
Offline
Зарегистрирован: 28.11.2020

Коллеги, мне вот тут такая мысль в голову пришла (требует проверки на практике). Автомобиль при движении получает ускорение по оси Z, а в случае аварии лобовой или боковой удар - перегрузка будет по оси X или Y. Мне кажется это должно упростить задачу.

Код, подсчитывающий результирующий вектор ускорения, написал. Порог срабатывания прописал. Лог в монитор вывел. Надо прокатиться на машине, посмотреть, какие результаты на практике будут. По результатам отпишусь.

Allleksey
Offline
Зарегистрирован: 28.11.2020

Коллеги, приветствую! Подскажите, кто то работал с модулем GSM GPS SIM808? Вроде как и GSM есть и GPS в одном модуле. Значительно уменьшается размер всего устройства. Есть отзывы по модулю?

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Allleksey пишет:

Автомобиль при движении получает ускорение по оси Z

Обоснуйте.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

del

Allleksey
Offline
Зарегистрирован: 28.11.2020

andriano пишет:

Allleksey пишет:

Автомобиль при движении получает ускорение по оси Z

Обоснуйте.

Это я про вибрации от езды по неровной поверхности. Вектор будет направлен перпендикулярно плоскости дороги. А вот при ударе будет параллелен. Нет? Ошибаюсь?

Это справедливо вот при такой системе координат.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Allleksey пишет:

andriano пишет:

Allleksey пишет:

Автомобиль при движении получает ускорение по оси Z

Обоснуйте.

Это я про вибрации от езды по неровной поверхности. Вектор будет направлен перпендикулярно плоскости дороги. А вот при ударе будет параллелен. Нет? Ошибаюсь?

Ну т.е. двигатель, тормоза и рулевое управление не учитываем.

Правда, в отличие от вех остальных именно положительное ускорение по Z может оказаться больше g. Эту особенность необходимо учитывать. Один из простейших способов учета - исключить Z из рассмотрения. В принципе - как вариант.

 

Allleksey
Offline
Зарегистрирован: 28.11.2020

andriano пишет:

Один из простейших способов учета - исключить Z из рассмотрения. В принципе - как вариант.

Именно об этом я и говорю. Да, я согласен, что есть ускорение при разгоне, отрицательное ускорение при торможении, центростремительное при поворотах. Но из значения будут не столь значительными, как ускорение от неровностей дороги по оси Z.

И в простейшем алгоритме анализировать можно суммарный вектор по осям X и Y.

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

Allleksey пишет:

м я и говорю. Да, я согласен, что есть ускорение при разгоне, отрицательное ускорение при торможении, центростремительное при поворотах. Но из значения будут не столь значительными, как ускорение от неровностей дороги по оси Z.

А почему вы так считаете? Все это абстрактные рассуждения не подкрепленные ничем. Собирите схему, наберите данных при реальном вождении для анализа, а потом уже можно будет обсуждать, что там больше, а что меньше 

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Ну так для начала проехать на машине и просмотреть лог. Ну пару раз врезаться куда-нибудь ))). А дальше уже думать.

b707
Offline
Зарегистрирован: 26.05.2017

Почитал тему... не вдаваясь в технические вопросы... с точки зрения отца двух взрослых детей... зачем это все?

Попадет в ДТП - либо сам разрулит, либо сам позвонит...

А эта система - как не отлаживай - точно будет давать ложные срабатывания. Удар при въезде в крупную выбоину точно будет сильнее, чем сотрясение от небольшого ДТП. Вам надо приготовить побольше успокоительного. чтобы при каждой такой СМС-ке в обморок не падать...

До скольки лет вы планируете опекать свое дитятко? Если права получил - значит миним 18 есть. Не пора ему самому свои проблемы решать?

Allleksey
Offline
Зарегистрирован: 28.11.2020

Я не собираюсь контролировать его. Да, я согласен, что при небольшом ДТП разрулит сам или позвонит. А вот если что то серьезное? Я надеюсь, что все мои усилия останутся без прикладного применения, ведь система нужна на СЕРЬЕЗНЫЙ СЛУЧАЙ, когда не может сам позвонить. Хочется верить, что она не пригодится и я не получу уведомления о серьезном событии.

Факт небольшого ДТП меня не интересует.

sadman41
Offline
Зарегистрирован: 19.10.2016

Потом будете трястись - не завис ли модем, положителен ли баланс и т.п.

Нет смысла в одном экземпляре и на коленке делать событийную систему - надёжность ее неясна. В данном случае поможет только целая система, которая постоянно отчитывается в ЦУП о состоянии гироскопа

Allleksey
Offline
Зарегистрирован: 28.11.2020

Так возможно система такое развитие и получит. Тем не менее я обратился за помощью в технической реализации и Ваш комментарий принимаю как дополнение к функционалу устройства, который должен быть реализован для надлежащей работы. Спасибо большое за участие. Внес в перечень развития изделия.

SLKH
Offline
Зарегистрирован: 17.08.2015

sadman41 пишет:
отом будете трястись - не завис ли модем, положителен ли баланс и т.п. Нет смысла в одном экземпляре и на коленке делать событийную систему - надёжность ее неясна. ПВ данном случае поможет только целая система, которая постоянно отчитывается в ЦУП о состоянии гироскопа
система называется "эра-глонасс".

Кстати, при серьёзной аварии (тьфу-тьфу-тьфу) оперативное прибытие "скорой помощи" значительно полезнее, чем распсихованного отца. А при несерьёзных - вся эта байда не нужна вообще.

А что желательно - заплатить профессиональному инструктору, чтобы он накатал с юным водителем реально достаточное количество часов. Или хотя бы самому поездить рядом.

У мя когда племянница права получила, первый месяц ездила исключительно с ейным мужем, пока он не решил, что она готова к самостоятельным поездкам. И это правильно.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Allleksey пишет:

Я не собираюсь контролировать его. Да, я согласен, что при небольшом ДТП разрулит сам или позвонит. А вот если что то серьезное? Я надеюсь, что все мои усилия останутся без прикладного применения, ведь система нужна на СЕРЬЕЗНЫЙ СЛУЧАЙ, когда не может сам позвонить. Хочется верить, что она не пригодится и я не получу уведомления о серьезном событии.

Факт небольшого ДТП меня не интересует.

Если бы любое ДТП, тогда проще: ускорение > 1.5g и все.

А если разделять ДТП по градациям, придется разбить не менее десятка машин для подбора коэффициентов. Не проще ли купить автомобиль тонны на 3 с дюжиной подушек? 

b707
Offline
Зарегистрирован: 26.05.2017

andriano пишет:

Не проще ли купить автомобиль тонны на 3 с дюжиной подушек? 

это просто перенесет возможные проблемы с любимого чада на его оппонетов. По мне так честнее чтобы новички при коллизиях получали шишки сами, нежели чем калечили других, оттого что папочка купил им броневик, права к нему. но не обьяснил как правильно ездить...

Ну или пусть при выезде на улицы города рассылают СМС-оповещение на манер МЧС : "Рекомендуем автолюбителям отказаться от поездок..."

Allleksey
Offline
Зарегистрирован: 28.11.2020

Коллеги, приветствую!

Никак не пойму, как с модуля GY-521 получить цифры ускорения без лишних данных. По мануалу данные из 0x3B и 0x3С это акселерометр по оси X. Читая из них данные я имею непонятные значения. Если я поворачиваю модуль по оси X, то значения изменяются и остаются. Ощущение, что модуль показывает значение угла в каких то единицах. Ускорение по оси X даже увидеть не могу из за постоянного изменения показаний из за наклона.

Вот скетч: В значениях accX и accY не вижу ускорения по осям :(

/*****************************************************
   НАСТРОЙКИ И ПОДСТАВЛЕНИЯ
*****************************************************/
#define ACC_TYPE 0                // 0 - 2g, 1 - 4g, 2 - 8g, 3 - 16g
#define GYRO_TYPE 0               // 0 - 250 deg/sec, 1 - 500 deg/sec, 2 - 1000 deg/dec, 3 - 2000 deg/sec
#define DEBUG 1                   // 0 - Debug OFF, 1 - Debug ON


/*****************************************************
   Подключение библиотеки работы с экраном для отладки
*****************************************************/
#if (DEBUG == 1)                          // Подключение если включена отладка
  #include <iarduino_OLED_txt.h>          //
  iarduino_OLED_txt myOLED(0x78);         //
  extern uint8_t SmallFontRus[];          //
#endif                                    // Окончание условного компилирования

#include <Wire.h>
#include <Kalman.h>


/*****************************************************
Определение переменных, констант и подстановок
*****************************************************/
Kalman kalmanX;
Kalman kalmanY;
uint8_t IMUAddress = 0x68;
/* IMU Data */
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 accYangle;
double temp;
double gyroXangle = 180; // Angle calculate using the gyro
double gyroYangle = 180;
double compAngleX = 180; // Calculate the angle using a Kalman filter
double compAngleY = 180;
double kalAngleX; // Calculate the angle using a Kalman filter
double kalAngleY;
uint32_t timer;




/*****************************************************
******************************************************
*   Функция SETUP
******************************************************
*****************************************************/
void setup() 
{
#if (DEBUG == 1)                          // Подключение если включена отладка
  myOLED.begin();                         //
  myOLED.setFont(SmallFontRus);           // Указываем шрифт который требуется использовать для вывода цифр и текста.
  myOLED.setCoding(TXT_UTF8);             //
  myOLED.clrScr();                        // Очистка экрана
#endif                                    // Окончание условного компилирования

  Wire.begin();
  Serial.begin(9600);
  i2cWrite(0x6B,0x00); // Disable sleep mode      
  kalmanX.setAngle(180); // Set starting angle
  kalmanY.setAngle(180);
  timer = micros();

}


/*****************************************************
******************************************************
*   Функция LOOP
******************************************************
*****************************************************/
void loop() 
{
  uint8_t* data = i2cRead(0x3B,14);
  accX = ((data[0] << 8) | data[1]);
  accY = ((data[2] << 8) | data[3]);
  accZ = ((data[4] << 8) | data[5]);
  tempRaw = ((data[6] << 8) | data[7]);
  gyroX = ((data[8] << 8) | data[9]);
  gyroY = ((data[10] << 8) | data[11]);
  gyroZ = ((data[12] << 8) | data[13]);
  /* Calculate the angls based on the different sensors and algorithm */
  accYangle = (atan2(accX,accZ)+PI)*RAD_TO_DEG;
  accXangle = (atan2(accY,accZ)+PI)*RAD_TO_DEG;  
  double gyroXrate = (double)gyroX/131.0;
  double gyroYrate = -((double)gyroY/131.0);
  gyroXangle += kalmanX.getRate()*((double)(micros()-timer)/1000000); // Calculate gyro angle using the unbiased rate
  gyroYangle += kalmanY.getRate()*((double)(micros()-timer)/1000000);
  kalAngleX = kalmanX.getAngle(accXangle, gyroXrate, (double)(micros()-timer)/1000000); // Calculate the angle using a Kalman filter
  kalAngleY = kalmanY.getAngle(accYangle, gyroYrate, (double)(micros()-timer)/1000000);
  timer = micros();

#if (DEBUG == 1)                          // Подключение если включена отладка
  myOLED.print( "kalmanX:"    , 0, 1);
  myOLED.print( "          ", 60, 1);
  myOLED.print( kalAngleX, 60, 1);

  myOLED.print( "kalmanY:"    , 0, 2);
  myOLED.print( "          ", 60, 2);
  myOLED.print( kalAngleY, 60, 2);

  myOLED.print( "accX:"    , 0, 3);
  myOLED.print( "          ", 60, 3);
  myOLED.print( accX, 60, 3);

  myOLED.print( "accY:"    , 0, 4);
  myOLED.print( "          ", 60, 4);
  myOLED.print( accY, 60, 4);
  delete data;
#endif
}
void i2cWrite(uint8_t registerAddress, uint8_t data)
{
  Wire.beginTransmission(IMUAddress);
  Wire.write(registerAddress);
  Wire.write(data);
  Wire.endTransmission(); // Send stop
}
uint8_t* i2cRead(uint8_t registerAddress, uint8_t nbytes) 
{
  uint8_t *data = new uint8_t [nbytes];
  Wire.beginTransmission(IMUAddress);
  Wire.write(registerAddress);
  Wire.endTransmission(false); // Don't release the bus
  Wire.requestFrom(IMUAddress, nbytes); // Send a repeated start and then release the bus after reading
  for(uint8_t i = 0; i < nbytes; i++)
    data [i]= Wire.read();
  return data;
}

 

rkit
Offline
Зарегистрирован: 23.11.2016

Allleksey пишет:

По мануалу данные из 0x3B и 0x3С это акселерометр по оси X. Читая из них данные я имею непонятные значения. Если я поворачиваю модуль по оси X, то значения изменяются и остаются.

И почему ты решил, что акселерометр должен реагировать на поворот?

Allleksey
Offline
Зарегистрирован: 28.11.2020

Так в том то и дело, что я решил, что он НЕ должен реагировать на поворот, а должен реагировать на ускорение вдоль оси. А вижу я как раз реакцию на поворот. Примем не на угловое ускорение, как на гироскопе. При повороте показания начинают увеличиваться (уменьшаться) и при остановке вращения изменение останавливается, но не сбрасывается. Очень похоже на показания угла поворота в каких то своих единицах.

Allleksey
Offline
Зарегистрирован: 28.11.2020

И что любопытно... значение растет до поворота на угол 90 градусов... если продолжать поворачивать дальше, что значение начинает уменьшаться. 

Изменил скетч. Слежу за максимальным значением данных с акселерометра. И после запуска в максимальных значениях нули. Начинаешь шевелить, значение, естественно, увеличивается. От поворота, кстати, не изменяется максимальное значение. В то время как мгновенное значение изменяется. Ничего не понимаю.

Надеюсь видео получится увидеть по ссылке.

/*****************************************************
   НАСТРОЙКИ И ПОДСТАВЛЕНИЯ
*****************************************************/
#define ACC_TYPE 3                // 0 - 2g, 1 - 4g, 2 - 8g, 3 - 16g
#define GYRO_TYPE 0               // 0 - 250 deg/sec, 1 - 500 deg/sec, 2 - 1000 deg/dec, 3 - 2000 deg/sec
#define DEBUG 1                   // 0 - Debug OFF, 1 - Debug ON


/*****************************************************
   Подключение библиотеки работы с экраном для отладки
*****************************************************/
#if (DEBUG == 1)                          // Подключение если включена отладка
  #include <iarduino_OLED_txt.h>          //
  iarduino_OLED_txt myOLED(0x78);         //
  extern uint8_t SmallFontRus[];          //
#endif                                    // Окончание условного компилирования

#include <Wire.h>
#include <Kalman.h>


/*****************************************************
Определение переменных, констант и подстановок
*****************************************************/
Kalman kalmanX;
Kalman kalmanY;
uint8_t IMUAddress = 0x68;
/* IMU Data */
int16_t accX;
int16_t accY;
int16_t accXMax;
int16_t accYMax;
int16_t accZ;
int16_t tempRaw;
int16_t gyroX;
int16_t gyroY;
int16_t gyroZ;
double accXangle; // Angle calculate using the accelerometer
double accYangle;
double temp;
double gyroXangle = 180; // Angle calculate using the gyro
double gyroYangle = 180;
double compAngleX = 180; // Calculate the angle using a Kalman filter
double compAngleY = 180;
double kalAngleX; // Calculate the angle using a Kalman filter
double kalAngleY;
uint32_t timer;

boolean StartEngen = 1;       // Старт двигателя (зажигание включено)




/*****************************************************
******************************************************
*   Функция SETUP
******************************************************
*****************************************************/
void setup() 
{
#if (DEBUG == 1)                          // Подключение если включена отладка
  myOLED.begin();                         //
  myOLED.setFont(SmallFontRus);           // Указываем шрифт который требуется использовать для вывода цифр и текста.
  myOLED.setCoding(TXT_UTF8);             //
  myOLED.clrScr();                        // Очистка экрана
#endif                                    // Окончание условного компилирования

  Wire.begin();
  Serial.begin(9600);
  i2cWrite(0x6B,0x00); // Disable sleep mode
  switch (ACC_TYPE)
  {
    case 0:
      i2cWrite(0x6B,0x00);
      break;
    case 1:
      i2cWrite(0x6B,0x01);
      break;
    case 2:
      i2cWrite(0x6B,0x02);
      break;
    case 3:
      i2cWrite(0x6B,0x03);
      break;
  }
        
  kalmanX.setAngle(180); // Set starting angle
  kalmanY.setAngle(180);
  timer = micros();

}


/*****************************************************
******************************************************
*   Функция LOOP
******************************************************
*****************************************************/
void loop() 
{
  // Показания датчиков акселерометров
  acceler();

#if (DEBUG == 1)                          // Подключение если включена отладка
  if (StartEngen == LOW)
  {
  myOLED.print( "kalmanX:"    , 0, 1);
  myOLED.print( "          ", 60, 1);
  myOLED.print( kalAngleX, 60, 1);

  myOLED.print( "kalmanY:"    , 0, 2);
  myOLED.print( "          ", 60, 2);
  myOLED.print( kalAngleY, 60, 2);
  }
  else
  {
  myOLED.print( "accX:"    , 0, 1);
  myOLED.print( "          ", 60, 1);
  myOLED.print( accX, 60, 1);

  myOLED.print( "accY:"    , 0, 2);
  myOLED.print( "          ", 60, 2);
  myOLED.print( accY, 60, 2);
  
  myOLED.print( "accXMax:"    , 0, 3);
  myOLED.print( "          ", 60, 3);
  myOLED.print( accXMax, 60, 3);

  myOLED.print( "accYMax:"    , 0, 4);
  myOLED.print( "          ", 60, 4);
  myOLED.print( accYMax, 60, 4);
  }
#endif
}

void acceler()
{
  uint8_t* data = i2cRead(0x3B,14);
  accX = ((data[0] << 8) | data[1]);
  accY = ((data[2] << 8) | data[3]);
  accZ = ((data[4] << 8) | data[5]);
  tempRaw = ((data[6] << 8) | data[7]);
  gyroX = ((data[8] << 8) | data[9]);
  gyroY = ((data[10] << 8) | data[11]);
  gyroZ = ((data[12] << 8) | data[13]);
  /* Calculate the angls based on the different sensors and algorithm */
  if (StartEngen == LOW)
  {
  accYangle = (atan2(accX,accZ)+PI)*RAD_TO_DEG;
  accXangle = (atan2(accY,accZ)+PI)*RAD_TO_DEG;  
  double gyroXrate = (double)gyroX/131.0;
  double gyroYrate = -((double)gyroY/131.0);
  gyroXangle += kalmanX.getRate()*((double)(micros()-timer)/1000000); // Calculate gyro angle using the unbiased rate
  gyroYangle += kalmanY.getRate()*((double)(micros()-timer)/1000000);
  kalAngleX = kalmanX.getAngle(accXangle, gyroXrate, (double)(micros()-timer)/1000000); // Calculate the angle using a Kalman filter
  kalAngleY = kalmanY.getAngle(accYangle, gyroYrate, (double)(micros()-timer)/1000000);
  timer = micros();
  }
  else
  {
    if (accXMax < accX)
    {
      accXMax = accX;
    }
    if (accYMax < accY)
    {
      accYMax = accY;
    }
  }
  delete data;
}

void i2cWrite(uint8_t registerAddress, uint8_t data)
{
  Wire.beginTransmission(IMUAddress);
  Wire.write(registerAddress);
  Wire.write(data);
  Wire.endTransmission(); // Send stop
}
uint8_t* i2cRead(uint8_t registerAddress, uint8_t nbytes) 
{
  uint8_t *data = new uint8_t [nbytes];
  Wire.beginTransmission(IMUAddress);
  Wire.write(registerAddress);
  Wire.endTransmission(false); // Don't release the bus
  Wire.requestFrom(IMUAddress, nbytes); // Send a repeated start and then release the bus after reading
  for(uint8_t i = 0; i < nbytes; i++)
    data [i]= Wire.read();
  return data;
}

 

rkit
Offline
Зарегистрирован: 23.11.2016

Так ты не вокруг центра координат прибора поворачиваешь, солнце. Не говоря уж о том, что у тебя руки дрожат.

Allleksey
Offline
Зарегистрирован: 28.11.2020

все равно не понимаю, почему показания имею накопительных характер. Понятно, если я начинаю поворачивать, показания увеличились. Перестал поворачивать, снова уменьшились. А тут же в процессе поворота они растут, перестаю поворачивать, перестают расти, но и не сбрасываются.