Прерывание опроса с INT1/2 (LSM6DS33)

qwertysuin
Offline
Зарегистрирован: 21.09.2017

Доброго времени суток!
Дано: 
1х Arduino Due
3x датчики LSM6DS33 (гироскоп-акселерометр)
1x библиотека https://github.com/pololu/lsm6-arduino

Происходит подключение с помощью I2C, как вы могли заметить все данные в "коде" смешиваются в кучу малу на выходе. Проблема заключается в грустной инициализации и чтении, т.е. если мы взглянем на осцилограммы то заметим что не существует прерывания между опросами датчиков, они одновременно отправляют все свои данные, ведь датчики работают либо на высоком логическом уровне либо на низком ( то есть опрашивать до 2 датчиков)
Но я уверен что местные гуру смогут адекватно обьяснить, написать пару строк кода или скинуть ссылки на КАЧЕСТВЕННОЕ обьяснение как сделать следующее: 
После инициализации всех устройств читается первый гироскоп, пока 2 и 3 не "работают"; опрашивается второй гироскоп пока остальные не активны. И все это сделать ОБЯЗАТЕЛЬНО на I2C с помощью INT или CS (хотя это по-моему сложно). В код не включены функции фильтрации и переменные, просьба вглядываться в инициализацию и начало чтения датчиков.
Всем спасибо!
p.s. первый проект- просьба не кидаться помидорами

 

#include <Wire.h>
#include <LSM6.h>
//инициализация
LSM6 imu1;
LSM6 imu2;
LSM6 imu3;

// переменные для калмана
float varVoltAx1 = 4.65; // среднее отклонение (ищем в excel)
float varVoltAy1 = 4.08; 
float varVoltAz1 = 8.29; 
float varVoltGx1 = 0.92; 
float varVoltGy1 = 1.45;
float varVoltGz1 = 0.73; 

float varProcess1 = 0.05; //рость реакции на изменение (подбирается вручную)
float varProcess2 = 0.05;

float acl= 0.061;
float gyr= 0.00875;

char report[512];

void setup()
{
  Serial.begin(38400);
  Wire.begin();
  
    if (!imu1.init())
   {
    Serial.println("Failed to detect and initialize IMU1!");
    while (1);
  }
  imu1.enableDefault();

 if (!imu2.init())
   {
    Serial.println("Failed to detect and initialize IMU2!");
    while (1);
  }
  imu2.enableDefault();

 if (!imu3.init())
   {
    Serial.println("Failed to detect and initialize IMU3!");
    while (1);
  }
  imu3.enableDefault();

}

void loop()
{
  imu1.read(); //тут все смешивается в кучу
  imu2.read();
  imu3.read();
  
  //акселерометры1
   float acc11=imu1.a.x* acl;
   float acc12=imu1.a.y* acl;
   float acc13=imu1.a.z* acl;
  int fil_acc11 = filter11acc(acc11);
  int fil_acc12 = filter12acc(acc12);
  int fil_acc13 = filter13acc(acc13);
  
//гироскопы1 
float gyr11=imu1.g.x* gyr;
   float gyr12=imu1.g.y* gyr;
   float gyr13=imu1.g.z* gyr;
  int fil_gyr11 = filter11gyr(gyr11);
  int fil_gyr12 = filter12gyr(gyr12);
  int fil_gyr13 = filter13gyr(gyr13);

//акселерометры2
   float acc21=imu2.a.x* acl;
   float acc22=imu2.a.y* acl;
   float acc23=imu2.a.z* acl;
  int fil_acc21 = filter21acc(acc21);
  int fil_acc22 = filter22acc(acc22);
  int fil_acc23 = filter23acc(acc23);
  
//гироскопы2 
float gyr21=imu2.g.x* gyr;
   float gyr22=imu2.g.y* gyr;
   float gyr23=imu2.g.z* gyr;
  int fil_gyr21 = filter21gyr(gyr21);
  int fil_gyr22 = filter22gyr(gyr22);
  int fil_gyr23 = filter23gyr(gyr23);

//акселерометры3
   float acc31=imu3.a.x* acl;
   float acc32=imu3.a.y* acl;
   float acc33=imu3.a.z* acl;
  int fil_acc31 = filter31acc(acc31);
  int fil_acc32 = filter32acc(acc32);
  int fil_acc33 = filter33acc(acc33);
  
//гироскопы3 
float gyr31=imu3.g.x* gyr;
   float gyr32=imu3.g.y* gyr;
   float gyr33=imu3.g.z* gyr;
  int fil_gyr31 = filter31gyr(gyr31);
  int fil_gyr32 = filter32gyr(gyr32);
  int fil_gyr33 = filter33gyr(gyr33);  


  
  //вывод
  snprintf(report, sizeof(report), "A1: %6d %6d %6d G1:%6d %6d %6d  A2: %6d %6d %6d G2:%6d %6d %6d  A3: %6d %6d %6d G3:%6d %6d %6d ",
    fil_acc11, fil_acc12, fil_acc13, fil_gyr11, fil_gyr12, fil_gyr13,
    fil_acc21, fil_acc22, fil_acc23, fil_gyr21, fil_gyr22, fil_gyr23,
    fil_acc31, fil_acc32, fil_acc33, fil_gyr31, fil_gyr32, fil_gyr33);

 
  Serial.println(report);

  delay(10);
}
//функции фильтрации

 

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

Насколько я понимаю - если не предпринимать дополнительных схемотехнических решений, то на одной I2C шине может работать только два таких датчика. Их адреса конфигурируются ногой SDO/SA0 (LSM6DS33 pin 4). Если она притянута к VCC - чип откликается на один адрес, если к GND - то на второй.

Третье устройство на ту же шину не посадить. Но у Due, как я посмотрю, два I2C интерфейса. Т.е. один датчик можно отсадить на вторую шину. Однако, как потом сказать библиотеке Wire.h об этом - я не знаю. Как вариант - через i2c multiplexer или SoftWire library.

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

Насколько я помню, для каждой шины создается по одному экземпляру класса (Wire и Wire1).