Некорректная работа arduino в паре MPU6050 и HC-05

,

Добрый день! Уже кучу времени пытаюсь понять в чем проблема программы, но никак не удается выявить причину, надеюсь у кого то появятся идеи. Текст выйдет довольно большим, прошу набраться терпением =)

Есть два ардуино:
1 ардуино(отправляющая сторона NANO 168): arduino + HC-05 + MPU6050, ардуино берет данные с MPU и отправляет по bluetooth обработанные данные
2 ардуино(принимающая сторона UNO 328): arduino + HC-05, принимает данные от 1 ардуино и просто их выводит

Проблема
1 ардуино отсылает данные 2 ардуино, 2 ардуино показывает 4 значения типа float в COM-порте и вроде как все хорошо, но здесь появляются 2 пути:

    • Путь 1 (шанс появления 90%):* через 5-20 секунд ардуино 2 перестает принимать данные и прекращает выводить новые значения, также после этого блютузы отсоединяются друг от друга и блютуз 2 ардуино входит опять в поиск устройства( он master), а у блютуза 1 ардуино выключаются светодиоды и все!
      ВАЖНОЕ НАБЛЮДЕНИЕ РАБОТЫ СВЕТОДИОДОВ ДВУХ HC-05: когда система только включается, светодиоды двух блютузов в поиске (частое мигание красным светодиодом), когда они подключатся, то master не мигает никак, а slave мигает раз в 3 секунды, система работает, но через какое-то время, если master мигнет хоть 1 раз светодиодом, значит передача данных полностью останавливается и происходит то, что я описал выше когда они отсоединяются
    • Путь 2 (шанс появления 10%):* каким-то чудом эта система полностью работает ничего не отсоединяется и выводит значения так, как нужно

В коде по арудино 1 (смотри ниже), я думал, что когда идет быстрый опрос датчика MPU, HC-05 не справляется с такой скоростью и происходит какая-то рассинхронизация, я пробывал добавить отдельный цикл, где он отправляет не раз в 2мкс в основном цикле, а побольше времени ему давал, тогда он вообще ничего не отправляет и с MPU значений не принимает, как будто он заблокировал MPU и ничего не получает.
Отдельно я проверял как просто работу HC-05 (все хорошо они передают данные), так и только MPU6050 (тоже все хорошо, он работает), но как только я добавляю в код передачу данных возникает проблема.

Еще я заметил (может так и должно быть), что когда я решил посмотреть что выводит арудино 1 без кода о передаче данных он выводит нормальные значения

А когда с кодом о передаче данных

Монтажная схема:

P.S. Когда я работал с блютузами версии 3.0, то если они подключаются друг к другу и идет нормальная передача данных, то они синхронно мигают красным светодиодом, сейчас я работаю с версией 5.0, тут похоже после подключения master не мигает, а slave мигает раз в 3 секунды

КОД АРДУИНО 1

#include "I2Cdev.h"
#include "MPU6050.h"

#include <EasyTransfer.h>


  #define TO_DEG 57.2957f
  #define TIME_GYRO 2000 // период опроса mpu6050 в микросекундах
MPU6050 accgyro;


// ------------------------ BLUETOOTH ----------------------------
struct SEND_DATA_STRUCTURE {
  float tax;
  float tay;
  float tgx;
  float tgy;
};

SEND_DATA_STRUCTURE data;
EasyTransfer ETin, ETout; // 2 объекта ИзиТрансфера 1 для отправки и 1 получения информации

// ----------------------------------------------------


int16_t ax_raw, ay_raw, az_raw, gx_raw, gy_raw, gz_raw; // сырые данные в кодах АЦП (3 ускорения и 3 скорости)
long int time_timer=0; // переменная таймера для опроса
long int timerBT=1000;

// ------------------------ АКСЕЛЕРОМЕТР ----------------------------
float ax, ay, az; // значения ускорения в единицах гравитации g
float angle_ax, angle_ax1, angle_ay, angle_az; // углы, рассчитанные по акселерометру


// ------------------------ ГИРОСКОП ----------------------------
float gx, gy, gz; // значения угловой скорости в градусах в секунду
float angle_gx, angle_gy, angle_gz; // углы, рассчитанные по гироскопу
float gyro_x_zero, gyro_y_zero, gyro_z_zero; // калибровочные углы смещения нуля гироскопа

// ------------------------ ФИЛЬТР ----------------------------
float angle_fx, angle_fy, angle_fz; //угол после обработки комплементарным фильтром

void setup() {
  Serial.begin(19200); 
  //Serial.println("x, y, gx, gy");
  ETout.begin(details(data), &Serial);
  delay(5000);
  accgyro.initialize();
  calibrateMPU();
}

void loop() {
  if( time_timer < micros() ){
    time_timer = micros() + TIME_GYRO;
    accgyro.getMotion6(&ax_raw, &ay_raw, &az_raw, &gx_raw, &gy_raw, &gz_raw);
    getAngleAcsel(); // функция получения углов angle_ax, angle_ay, angle_az по акселерометру
    getAngleGyro(); // функция получения углов angle_gx, angle_gy, angle_gz по гироскопу
    getAngleFiltr(); // функция получения углов angle_fx, angle_fy, angle_fz с применением фильтра (по сути суммирует углы акселерометра и гироскопа)
    
    data.tax=angle_fx;
    data.tay=angle_fy;
    data.tgx=gx;
    data.tgy=gy;
    ETout.sendData();
    }

}

КОД АРДУИНО 2

#include <EasyTransfer.h>

struct RECEIVE_DATA_STRUCTURE {
  float tax;
  float tay;
  float tgx;
  float tgy;
};

RECEIVE_DATA_STRUCTURE data;
EasyTransfer ETin,ETout;

void setup() {
  Serial.begin(19200);
  Serial.println("ax, ay, gx, gy");
  ETin.begin(details(data), &Serial);
  delay(4000);
  //Serial.flush();
  
}

void loop() {
  
  if(ETin.receiveData()) {

    Serial.print(data.tax);
    Serial.print(' ');
    Serial.print(data.tay);
    Serial.print(' ');
    Serial.print(data.tgx);
    Serial.print(' ');
    Serial.println(data.tgy);
  }
 }

Так serial, судя по коду, «и там и там показывают» :grinning: В смысле, что он и для вывода на монитор порта и для передачи по блюпупу.
Может поэтому и не всегда всё правильно отрабатывает.
Убери вывод на монитор порта (диодами мигай или как-то ещё контролируй вывод), может «всё и наладится»? :slight_smile:

1 лайк

А что тогда не так, я вроде как просто задаю темп работы на двух ардуино
Или вы хотите сказать, что для приема данных и вывода их на ноутбук нужно отдельно по 2 порта?
Был бы очень благодарен если вы рассказали что не так
Я думал, что у 1 арудино(который передает данные), SERIAL это скорость работы всей системы (т.е. HC-05,MPU6050 и самой ардуино)
А у ардуино 2, SERIAL это скорость работы HC-05 и работы с ноутбуком

Возможно я не написал, но мне нужен вывод только со 2 арудино, 1 ардуино подключен к ноутбуку как простое питание

Я знаю, что например HC-05 и ноутбук общаются с arduino по RX/TX (UART-протоколу) и если например заливать код, то нужно отсоединять у блютуза эти порты, чтобы не было конфликта, но это все)

Похоже, тот же автор, что и в соседней ветке…

Должно быть unsigned long

увидел соседнюю ветку :smiley: , вот откуда люди задавали вопросы про моторы, которых у меня нет. Это код был взят у AlexRobotic

к сожалению, это не помогло

Вывод на монитор порта у меня только на 2 ардуинке. а мне он и нужен
На 1 арудино вывода вроде как никакого нет

Это лишь чтобы micros() “случайно” не “переполнился”))

Я бы сначала добился устойчивой работы блютуз модулей.
Т.е. отсоединил бы MPU6050, и немного переделал код

Попробуй для блюпупа использовать SoftSerial, а для вывода на монитор порта оставь HardSerial. Только скорость у последнего отличную поставь (9600, например, как обычно).

1 лайк

BOOM правильно говорит. Не стоит вешать на один TX
два устройства.

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

1 лайк

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

Когда этот эксперимент проводил, строки 15 и с 24 по 33 были закомментированы? Если нет - попробуй еще раз, но скомпилируй с закомментированными строками.

1 лайк

Не в обиду, пользы для. Повтори правописание.)

1 лайк

Да я сам в шоке - написал слитно и браузер подчеркнул как «неправильное» слово. Повелся на поводу технологий и сделал раздельно. :frowning: Ох уж эти технологии….
Спасибо :slight_smile:

1 лайк

Проверил, вроде как работало, похоже что есть конфликт по uart. Спасибо вам! Буду тогда разбираться с SoftwareSerial, никогда еще не работал с данным методом

Удачи! Потом напиши - получилось или нет.

Спасибо, обязательно отпишусь!

Добрый вечер! Спасибо вам огромное, провел несколько тестов, похоже что проблема решена!
Только появились небольшие проблемы с тем, что иногда значения которые приходят пишет нули, либо ovf (переполнение), а потом все дальше ок, пока не знаю с чем это может быть связано, и когда система долго работает из-за этих небольших сбоев в “Плоттере по последовательному соединению” переназначает мои подписанные графики на подписи ovf либо ?ovf

Решил проблему (скорее всего не совсем правильным путем), сделав проверку, чтобы приходящие числа были в заданном диапазоне

Отбрасывать некорректные данные - стандартная практика.

1 лайк