Как прочитать необработанные данные с модуля GY-85?

Этот модуль имеет 3 датчика. Гироскоп, акселерометр и магнитометр.

Мне кажется, я неправильно читаю необработанные данные.

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

  1. Магнитометр HMC5883L:

    void HMC5883L_print_Serial(void)
    {
      int16_t x,z,y;
      uint8_t data[6];
      float heading,heading_in_degrees,declination_angle_YANBU;
    
      data_read(data);
    
      // Этот нет
      x = data[1] << 8 | data[0];
      z = data[3] << 8 | data[2];
      y = data[5] << 8 | data[4]; 
    
      // Этот работает нормально
      /*x = data[0] << 8 | data[1];
      z = data[2] << 8 | data[3];
      y = data[4] << 8 | data[5];*/
    
      heading = atan2(y,x);
      declination_angle_YANBU = ((3.0 + (52.0 / 60.0)) / (180 / M_PI));  // в городе Янбу это
      heading += declination_angle_YANBU;
    
      // Правильно для заголовка < 0deg и заголовок > 360 градусов
      if (heading < 0){
        heading += 2 * PI;
      }
    
      if (heading > 2 * PI){
        heading -= 2 * PI;
      } 
    
      heading_in_degrees = heading * 180 / M_PI;
      Serial.println(heading_in_degrees);
      _delay_ms(20);  
    
    }
    
  2. Акселерометр ADXL345

    void ADXL345_print_Serial(void){
      int16_t x,z,y;
      uint8_t data[6];
    
      ADXL345_read_raw(data);
    
      // Этот дает значения от -255 до +255
      x = data[1] << 8 | data[0];
      z = data[3] << 8 | data[2];
      y = data[5] << 8 | data[4];
    
      // Этот дает значения от -32768 до +32768
      /*x = data[0] << 8 | data[1];
      z = data[2] << 8 | data[3];
      y = data[4] << 8 | data[5];*/
        Serial.print(x);Serial.print("\t");
        Serial.print(y);Serial.print("\t");
        Serial.println(z);
        _delay_ms(100);
    }
    

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

, 👍0

Обсуждение

Один дает вам абсолютную ориентацию, используя магнитное поле Земли. Другой дает вам изменения скорости (и гравитационного притяжения, которое является формой ускорения). В чем они одинаковы?, @Majenko

Просматривали ли вы таблицу данных ADXL345, чтобы узнать, какой протокол связи? Это то же самое, что и для HMC5883L? Или вам следует внедрить другую систему?, @Majenko

Привет, они оба используют протокол I2C. Все датчики на этой плате используют один и тот же протокол. Вы правы, они разные, но мне показалось, что они похожи, потому что они меняют значения при наклоне! Это меня смущает, потому что; например, акселерометр должен менять значения только тогда, когда я перемещаю его вперед, назад и вверх-вниз, поэтому он также меняет значения, когда я его переворачиваю или наклоняю… это сбивало с толку., @R1S8K

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


1 ответ


1

Одно из мест, где можно найти технические описания датчиков модуля GY-85, находится здесь: https://www.hotmcu.com/gy85-9dof-imu-sensor-module-p-298.html
Следующая информация взята из этих технических описаний:

И HMC5883L, и ADXL345 имеют внутренние регистры, которые пронумерованы последовательно. При чтении более чем одного регистра наиболее эффективно их читать в том порядке, в котором они пронумерованы. Для каждой из трех осей оба датчика используют два 8-битных регистра для хранения измеренного значения.

В HMC5883L регистр с меньшим номером содержит старший байт (MSB), а регистр с большим номером — младший байт (LSB). Это означает, что при последовательном чтении сначала читается старший бит, а затем младший бит. Когда вы объединяете эти два байта в одно 16-битное число (тип данных int), вам необходимо сдвинуть байт, содержащий старший бит (первый полученный байт), на 8 позиций влево и ввести «ИЛИ» байт, содержащий младший бит (второй байт). получил).
В ADXL345 внутренняя нумерация обратная: регистр с меньшим номером содержит младший бит, а регистр с большим номером — старший бит. При чтении первым красным становится младший бит, а затем старший бит. Итак, на этот раз вам придется сдвинуть второй полученный байт и выполнить операцию "ИЛИ" для первого полученного байта.

Оба датчика выдают измеренное значение в виде 16-битного числа с двумя дополнениями, соответствующего типу данных int (Arduino Uno). 16-битное целое число может содержать значения от -32 768 до +32 767, но датчики не используют (не могут) использовать этот полный диапазон:
ADXL345 имеет регулируемый диапазон до 13 бит (от -4096 до +4095).
HMC5883L имеет диапазон 12 бит (от -2048 до +2047).

,

Хорошо, тогда мой нынешний HMC5883L неправильный. Я поместил первый байт справа от 16-битного регистра. Как в этом коде: x = data[1] << 8 | данные[0]; z = данные[3] << 8 | данные[2]; y = данные[5] << 8 | data[4]; Но мне нужно это изменить., @R1S8K

Успех! Пожалуйста, дайте нам знать, если ваш новый код работает., @PimV

Да, сейчас это работает. Меня сейчас беспокоит то, что я знаю, что взятие atan2(y,x); даст мне заголовок. Но в чем преимущество оси Z? А как можно использовать HMC5883L в квадрокоптере?, @R1S8K