Как откалибровать магнитометр MMC5603

magnetometer calibration

Я только что получил магнитометр MMC5603 от Adafruit, однако измерения ненадежны. Например, когда я конвертирую его в заголовок, он меняется с 200° на 180°, а затем обратно на 200°, если я перемещаю его радиально.

, 👍0


1 ответ


1

Для калибровки магнитометра необходимо выполнить калибровку твердого и мягкого железа. В Интернете есть несколько руководств о том, как это сделать, но я нашел это руководство по Digikey, чтобы быть наиболее информативным. У Adafruit также есть руководство здесь

Однако у меня возникли проблемы с запуском этой функции, поэтому вот несколько хитростей

Использование MacBook M1

Оба руководства рекомендуют использовать MotionCal, но оно не обновлялось уже несколько лет. Если вы загрузили версию macOS, в ней могут не отображаться доступные порты. Чтобы это исправить, вам необходимо скомпилировать его из исходного кода. Подробности можно найти в этой Проблеме Github, но TL;DR это:

  1. git clone [email protected]:PaulStoffregen/MotionCal.git
  2. brew install wxwidgets
  3. Откройте Makefile
  4. Закомментируйте строку OS = LINUX
  5. Раскомментируйте строкуOS = MACOSX_CLANG
  6. Под else ifeq ($(OS), MACOSX) добавьте -arch Arm64 в CFLAGS
  7. Запустите make, и он должен собраться

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

Использование Arduino UNO

В обоих руководствах рекомендуется использовать Adafruit Sensor Lab, который слишком велик, чтобы поместиться во флэш-память Arduino UNO. Вместо этого вы можете использовать этот код:

#include <Arduino.h>

#include <Adafruit_MMC56x3.h>

/* Одновременно назначаем уникальный идентификатор этому датчику */
Adafruit_MMC5603 mmc = Adafruit_MMC5603(12345);

int loopcount = 0;

// Аппаратные настройки калибровки
const float hard_iron[3] = {
    0, 0, 0
};

// Настройки калибровки мягкого железа
const float soft_iron[3][3] = {
    { 1, 0, 0 },
    { 0, 1, 0 },
    { 0, 0, 1 }
};

void setup(void)
{
    Serial.begin(115200);
    while (!Serial)
        delay(10); // приостановит Зеро, Леонардо и т. д., пока не откроется последовательная консоль

    Serial.println("Adafruit_MMC5603 Magnetometer Test");
    Serial.println("");

    /* Initialise the sensor */
    if (!mmc.begin(MMC56X3_DEFAULT_ADDRESS, &Wire)) { // режим I2C
        /* There was a problem detecting the MMC5603 ... check your connections */
        Serial.println("Ooops, no MMC5603 detected ... Check your wiring!");
        while (1)
            delay(10);
    }

    /* Display some basic information on this sensor */
    mmc.printSensorDetails();
}

void loop(void)
{
    static float hi_cal[3];
    // Получаем новое событие датчика
    sensors_event_t event;
    mmc.getEvent(&event);

    // Помещаем необработанные показания магнитометра в массив
    float mag_data[] = { event.magnetic.x,
        event.magnetic.y,
        event.magnetic.z };

    // Применяем жесткие смещения
    for (uint8_t i = 0; i < 3; i++) {
        hi_cal[i] = mag_data[i] - hard_iron[i];
    }

    // Применяем мягкое масштабирование
    for (uint8_t i = 0; i < 3; i++) {
        mag_data[i] = (soft_iron[i][0] * hi_cal[0]) + (soft_iron[i][1] * hi_cal[1]) + (soft_iron[i][2] * hi_cal[2]);
    }

    // «Необработанные» значения, соответствующие ожиданиям MOtionCal
    Serial.print("Raw:");
    Serial.print(0);
    Serial.print(",");
    Serial.print(0);
    Serial.print(",");
    Serial.print(0);
    Serial.print(",");
    Serial.print(0);
    Serial.print(",");
    Serial.print(0);
    Serial.print(",");
    Serial.print(0);
    Serial.print(",");
    Serial.print(int(mag_data[0] * 10));
    Serial.print(",");
    Serial.print(int(mag_data[1] * 10));
    Serial.print(",");
    Serial.print(int(mag_data[2] * 10));
    Serial.println("");

    // унифицированные данные
    Serial.print("Uni:");
    Serial.print(0);
    Serial.print(",");
    Serial.print(0);
    Serial.print(",");
    Serial.print(0);
    Serial.print(",");
    Serial.print(0);
    Serial.print(",");
    Serial.print(0);
    Serial.print(",");
    Serial.print(0);
    Serial.print(",");
    Serial.print(mag_data[0]);
    Serial.print(",");
    Serial.print(mag_data[1]);
    Serial.print(",");
    Serial.print(mag_data[2]);
    Serial.println("");

    delay(10);
}

который будет выводить данные магнитометра в правильном формате с правильной скоростью передачи данных. Затем вы просто открываете MotionCal и выбираете правильный порт

,