// ПРИМЕР ОТДЕЛЬНОГО ЧТЕНИЯ ВСЕХ ДАТЧИКОВ:                  // АКСЕЛЕРОМЕТР: измеряет кажущееся угловое ускорение, которое является геометрической разницей между истинным угловым ускорением и ускорением силы гравитации (g).
                                                            // Если акселерометр неподвижен (истинное ускорение отсутствует), его оси XY параллельны земле, а ось Z направлена вверх, то ...
                                                            // проекция кажущегося ускорения на ось Z = 0 - -g = g. Где 0 это истинное ускорение, а -g сила гравитации направленная в сторону противоположную оси Z.
                                                            // Так как вектор g всегда направлен к земле, то в неподвижном состоянии, по данным датчика можно определить угол наклона устройства относительно поверхности Земли.
                                                            // Эти данные можно использовать, например, для поворота изображения на экране (альбомное / ландшафтное).
                                                            //
                                                            // ГИРОСКОП: измеряет угловую скорость вокруг собственных осей, он определяет воздействие момента внешней силы.
                                                            // Эти данные можно использовать, например, для включения режима фиксации жесткого диска в случае падения, удара или резкого перемещения ноутбука.
                                                            //
                                                            // МАГНИТОМЕТР: измеряет магнитную индукцию, он определяет положение устройства в пространстве отностиельно магнитных полюсов земли.
                                                            // Значения оси направленной в сторону северного полюса будут положительными, а значения оси направленной в сторону южного полюса будут отрицательны.
                                                            // На экваторе магнитные линии параллельны земле (0°), но ближе к полюсам их угол относительно земли приближается к 90° и они становятся перпендикулярны земле.
                                                            // Так что не удивляйтесь если максимальные показания осей будут направлены вниз или верх от земли, это не помешает использовать показания остальных осей как компас.
                                                            // Показания магнитометра сильно меняются от любых намагниченных предметов, по этому его нужно калибровать или указывать полученные ранее калибровочные коэффициенты.
// ССЫЛКИ для ознакомления:                                 //   
// IMU-сенсор на 9 степеней свободы (Trema-модуль V2.0):    // https://iarduino.ru/shop/Sensory-Datchiki/imu-9.html
// Информация о подключении модулей к шине I2C:             // https://wiki.iarduino.ru/page/i2c_connection/
// Информация о модуле и описание библиотеки:               // https://wiki.iarduino.ru/page/Trema_IMU9/
                                                            //
#include <Wire.h>                                           // Подключаем библиотеку для работы с аппаратной шиной I2C, до подключения библиотеки iarduino_Position_BMX055.
#include <iarduino_Position_BMX055.h>                       // Подключаем библиотеку iarduino_Position_BMX055 для работы с Trema-модулем IMU 9 DOF.
iarduino_Position_BMX055 sensorA(BMA);                      // Создаём объект sensorA указывая что ему требуется работать только с акселерометром.
iarduino_Position_BMX055 sensorG(BMG);                      // Создаём объект sensorG указывая что ему требуется работать только с гироскопом.
iarduino_Position_BMX055 sensorM(BMM);                      // Создаём объект sensorM указывая что ему требуется работать только с магнитометром.
                                                            // Имена создаваемых объектов должны отличаться!
void setup(){                                               // 
     Serial.begin(9600);                                    // Инициируем передачу данных в монитор последовательного порта на скорости 9600 бит/сек.
     while(!Serial){}                                       // Ждём готовность Serial к передаче данных в монитор последовательного порта.
     sensorA.begin(&Wire); // &Wire1, &Wire2 ...            // Инициируем работу с датчиком объекта sensorA - это акселерометр. Указав ссылку на объект для работы с шиной I2C на которой находится модуль (по умолчанию &Wire).
     sensorG.begin(&Wire); // &Wire1, &Wire2 ...            // Инициируем работу с датчиком объекта sensorG - это гироскоп.     Указав ссылку на объект для работы с шиной I2C на которой находится модуль (по умолчанию &Wire).
     sensorM.begin(&Wire); // &Wire1, &Wire2 ...            // Инициируем работу с датчиком объекта sensorM - это магнитометр.  Указав ссылку на объект для работы с шиной I2C на которой находится модуль (по умолчанию &Wire).
//   sensorA.setScale(BMA_4G);                              // Меняем диапазон измерений акселерометра до ±4G.          Возможные значения: BMA_2G (по умолчанию), BMA_4G, BMA_8G, BMA_16G.
//   sensorG.setScale(BMG_500DPS);                          // Меняем диапазон измерений гироскопа до ±500°/с.          Возможные значения: BMG_125DPS (по умолчанию), BMG_250DPS, BMG_500DPS, BMG_1000DPS, BMG_2000DPS.
//   sensorM.setScale(BMM_ENHANCED);                        // Меняем количество выборок магнитометра на BMM_ENHANCED.  Возможные значения: BMM_LOW_PWR, BMM_REGULAR (по умолчанию), BMM_ENHANCED, BMM_HIGH.
//   sensorA.setBandwidths(BMA_125Hz);                      // Меняем частоту обновления данных акселерометра на 125Гц. Возможные значения: BMA_8Hz, BMA_16Hz (по умолчанию), BMA_31Hz, BMA_63Hz, BMA_125Hz, BMA_250Hz, BMA_500Hz, BMA_1000Hz.
//   sensorG.setBandwidths(BMG_64Hz);                       // Меняем частоту обновления данных гироскопа     на 64Гц.  Возможные значения: BMG_12Hz, BMG_23Hz (по умолчанию), BMG_32Hz, BMG_47Hz, BMG_64Hz, BMG_116Hz, BMG_230Hz, BMG_523Hz.
//   sensorM.setBandwidths(BMM_20Hz);                       // Меняем частоту обновления данных магнитометра  на 20Гц.  Возможные значения: BMM_2Hz, BMM_6Hz, BMM_8Hz, BMM_10Hz (по умолчанию), BMM_15Hz, BMM_20Hz, BMM_25Hz, BMM_30Hz.
//   sensorA.setFastOffset();                               // Выполняем калибровку акселерометра после установки нового диапазона измерений или частоты обновления данных.
//   sensorG.setFastOffset();                               // Выполняем калибровку гироскопа после установки нового диапазона измерений или частоты обновления данных.
//   while(не_истекло_время){sensorM.setFastOffset();}      // Выполняем калибровку магнитометра после установки нового диапазона измерений или частоты обновления данных в течении указанного времени модуль должен вращаться.
}                                                           //
                                                            //
void loop(){                                                // 
//   Функция read() читает данные того датчика, для которого был создан объект.
//   Так как мы создали 3 разных объекта для работы с разными датчиками, то данные читаемые функцией read() будут зависеть от объекта для которого она вызвана.
//   Функцию read() можно вызвать с параметром, выбрав единицы измерений выводимых данных. Если параметра нет, то данные выводятся в единицах по умолчанию.
     sensorA.read();                                        // sensorA.read(BMA_M_S  ); читать угловое ускорение в м/с² (по умолчанию).
                                                            // sensorA.read(BMA_G    ); читать угловое ускорение в g.
                                                            // sensorA.read(BMA_DEG  ); читать углы «крен» и «тангаж» в градусах.
                                                            // sensorA.read(BMA_RAD  ); читать углы «крен» и «тангаж» в радианах.
     sensorG.read();                                        // sensorG.read(BMG_DEG_S); читать угловую скорость в °/c. (по умолчанию).
                                                            // sensorG.read(BMG_RAD_S); читать угловую скорость в рад/c.
     sensorM.read();                                        // sensorM.read(BMM_MG   ); читать индукцию магнитного поля в мГс. (по умолчанию).
                                                            // sensorM.read(BMM_MCT  ); читать индукцию магнитного поля в мкТл.
                                                            // Данные прочитанные функцией read() сохраняются в переменных axisX, axisY, axisZ и temp.
                                                            // Значение этих переменных у каждого объекта своё.
     Serial.print("АКСЕЛЕРОМЕТР(");                         //
     Serial.print((String) "X="+sensorA.axisX+", ");        // Выводим проекцию кажущегося углового ускорения на ось X в м/с².
     Serial.print((String) "Y="+sensorA.axisY+", ");        // Выводим проекцию кажущегося углового ускорения на ось Y в м/с².
     Serial.print((String) "Z="+sensorA.axisZ+" м/с²) ");   // Выводим проекцию кажущегося углового ускорения на ось Z в м/с².
     Serial.print("ГИРОСКОП(");                             //
     Serial.print((String) "X="+sensorG.axisX+", ");        // Выводим угловую скорость вокруг оси X в °/c.
     Serial.print((String) "Y="+sensorG.axisY+", ");        // Выводим угловую скорость вокруг оси Y в °/c.
     Serial.print((String) "Z="+sensorG.axisZ+" °/c) ");    // Выводим угловую скорость вокруг оси Z в °/c.
     Serial.print("МАГНИТОМЕТР(");                          //
     Serial.print((String) "X="+sensorM.axisX+", ");        // Выводим проекцию индукции магнитного поля на ось X в мГс.
     Serial.print((String) "Y="+sensorM.axisY+", ");        // Выводим проекцию индукции магнитного поля на ось Y в мГс.
     Serial.print((String) "Z="+sensorM.axisZ+" мГс)\r\n"); // Выводим проекцию индукции магнитного поля на ось Z в мГс.
//   Не рекомендуется получать данные магнитометра без      //
//   его калибровки, см. пример magnetometer_calib.         // 
}
