После восстановления смещения BNO055 на датчике все значения калибровки равны 0.
Плата: ESP32
Скрипт: restre_offsets.ino из библиотеки Adafruit BNO055
Единственная разница в том, что я храню информацию в NVS ESP, используя библиотеку Preferences
Код
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BNO055.h>
#include <utility/imumaths.h>
#include <Preferences.h>
/* Set the delay between fresh samples */
#define BNO055_SAMPLERATE_DELAY_MS (1000)
Adafruit_BNO055 bno = Adafruit_BNO055(1390);
Preferences Calibration;
/**************************************************************************/
/*
Display some basic info about the sensor status
*/
/**************************************************************************/
void displaySensorStatus(void)
{
/* Get the system status values (mostly for debugging purposes) */
uint8_t system_status, self_test_results, system_error;
system_status = self_test_results = system_error = 0;
bno.getSystemStatus(&system_status, &self_test_results, &system_error);
/* Display the results in the Serial Monitor */
Serial.println("");
Serial.print("System Status: 0x");
Serial.println(system_status, HEX);
Serial.print("Self Test: 0x");
Serial.println(self_test_results, HEX);
Serial.print("System Error: 0x");
Serial.println(system_error, HEX);
Serial.println("");
delay(500);
}
/**************************************************************************/
/*
Display sensor calibration status
*/
/**************************************************************************/
void displayCalStatus(void)
{
/* Get the four calibration values (0..3) */
/* Any sensor data reporting 0 should be ignored, */
/* 3 means 'fully calibrated" */
uint8_t system, gyro, accel, mag;
system = gyro = accel = mag = 0;
bno.getCalibration(&system, &gyro, &accel, &mag);
/* The data should be ignored until the system calibration is > 0 */
Serial.print("\t");
if (!system)
{
Serial.print("! ");
}
/* Display the individual values */
Serial.print("Sys:");
Serial.print(system, DEC);
Serial.print(" G:");
Serial.print(gyro, DEC);
Serial.print(" A:");
Serial.print(accel, DEC);
Serial.print(" M:");
Serial.print(mag, DEC);
}
/**************************************************************************/
/*
Display the raw calibration offset and radius data
*/
/**************************************************************************/
void displaySensorOffsets(const adafruit_bno055_offsets_t &calibData)
{
Serial.print("Accelerometer: ");
Serial.print(calibData.accel_offset_x); Serial.print(" ");
Serial.print(calibData.accel_offset_y); Serial.print(" ");
Serial.print(calibData.accel_offset_z); Serial.print(" ");
Serial.print("\nGyro: ");
Serial.print(calibData.gyro_offset_x); Serial.print(" ");
Serial.print(calibData.gyro_offset_y); Serial.print(" ");
Serial.print(calibData.gyro_offset_z); Serial.print(" ");
Serial.print("\nMag: ");
Serial.print(calibData.mag_offset_x); Serial.print(" ");
Serial.print(calibData.mag_offset_y); Serial.print(" ");
Serial.print(calibData.mag_offset_z); Serial.print(" ");
Serial.print("\nAccel Radius: ");
Serial.print(calibData.accel_radius);
Serial.print("\nMag Radius: ");
Serial.print(calibData.mag_radius);
}
/**************************************************************************/
/*
Arduino setup function (automatically called at startup)
*/
/**************************************************************************/
void setup(void)
{
Wire.begin(13, 16, 400000);
Serial.begin(115200);
delay(1000);
Serial.println("Orientation Sensor Test"); Serial.println("");
/* Initialise the sensor */
if (!bno.begin())
{
/* There was a problem detecting the BNO055 ... check your connections */
Serial.print("Ooops, no BNO055 detected ... Check your wiring or I2C ADDR!");
while (1);
}
Calibration.begin("offsets", false);
adafruit_bno055_offsets_t calibrationData;
sensor_t sensor;
int32_t bnoID = Calibration.getInt("bnoID");
bool foundCalib = false;
/*
* Look for the sensor's unique ID at the beginning oF EEPROM.
* This isn't foolproof, but it's better than nothing.
*/
bno.getSensor(&sensor);
if (bnoID != sensor.sensor_id)
{
Serial.println("\nNo Calibration Data for this sensor exists in NVS");
delay(500);
}
else
{
Serial.println("\nFound Calibration for this sensor in NVS.");
// Смещения акселерометра
calibrationData.accel_offset_x = Calibration.getInt("acc_off_x");
calibrationData.accel_offset_y = Calibration.getInt("acc_off_y");
calibrationData.accel_offset_z = Calibration.getInt("acc_off_z");
// Смещения гироскопа
calibrationData.gyro_offset_x = Calibration.getInt("gyr_off_x");
calibrationData.gyro_offset_y = Calibration.getInt("gyr_off_y");
calibrationData.gyro_offset_z = Calibration.getInt("gyr_off_z");
// Смещения магнитометра
calibrationData.mag_offset_x = Calibration.getInt("mag_off_x");
calibrationData.mag_offset_y = Calibration.getInt("mag_off_y");
calibrationData.mag_offset_z = Calibration.getInt("mag_off_z");
displaySensorOffsets(calibrationData);
Serial.println("\n\nRestoring Calibration data to the BNO055...");
bno.setSensorOffsets(calibrationData);
Serial.println("\n\nCalibration data loaded into BNO055");
foundCalib = true;
}
delay(1000);
/* Display some basic information on this sensor */
// displaySensorDetails();
/* Optional: Display current status */
displaySensorStatus();
//Кристалл необходимо настроить ПОСЛЕ загрузки данных калибровки в BNO055.
bno.setExtCrystalUse(true);
sensors_event_t event;
bno.getEvent(&event);
if (foundCalib){
Serial.println("Move sensor slightly to calibrate magnetometers");
while (!bno.isFullyCalibrated())
{
bno.getEvent(&event);
displayCalStatus();
Serial.println("");
delay(BNO055_SAMPLERATE_DELAY_MS);
}
}
else
{
Serial.println("Please Calibrate Sensor: ");
while (!bno.isFullyCalibrated())
{
bno.getEvent(&event);
Serial.print("X: ");
Serial.print(event.orientation.x, 4);
Serial.print("\tY: ");
Serial.print(event.orientation.y, 4);
Serial.print("\tZ: ");
Serial.print(event.orientation.z, 4);
/* Optional: Display calibration status */
displayCalStatus();
/* New line for the next sample */
Serial.println("");
/* Wait the specified delay before requesting new data */
delay(BNO055_SAMPLERATE_DELAY_MS);
}
}
Serial.println("\nFully calibrated!");
Serial.println("--------------------------------");
Serial.println("Calibration Results: ");
adafruit_bno055_offsets_t newCalib;
bno.getSensorOffsets(newCalib);
displaySensorOffsets(newCalib);
Serial.println("\n\nStoring calibration data to NVS...");
bno.getSensor(&sensor);
bnoID = sensor.sensor_id;
// вводим идентификатор датчика
Calibration.putInt("bnoID", bnoID);
// сохраняем новые смещения акселерометра
Calibration.putInt("acc_off_x", newCalib.accel_offset_x);
Calibration.putInt("acc_off_y", newCalib.accel_offset_y);
Calibration.putInt("acc_off_z", newCalib.accel_offset_z);
// сохраняем новые смещения гироскопа
Calibration.putInt("gyr_off_x", newCalib.gyro_offset_x);
Calibration.putInt("gyr_off_y", newCalib.gyro_offset_y);
Calibration.putInt("gyr_off_z", newCalib.gyro_offset_z);
// сохраняем новые смещения магнитометра
Calibration.putInt("mag_off_x", newCalib.mag_offset_x);
Calibration.putInt("mag_off_y", newCalib.mag_offset_y);
Calibration.putInt("mag_off_z", newCalib.mag_offset_z);
Serial.println("Data stored to NVS..");
Serial.println("\n--------------------------------\n");
delay(500);
}
void loop() {
/* Get a new sensor event */
sensors_event_t event;
bno.getEvent(&event);
/* Display the floating point data */
Serial.print("X: ");
Serial.print(event.orientation.x, 4);
Serial.print("\tY: ");
Serial.print(event.orientation.y, 4);
Serial.print("\tZ: ");
Serial.print(event.orientation.z, 4);
/* Optional: Display calibration status */
displayCalStatus();
/* Optional: Display sensor status (debug only) */
displaySensorStatus();
/* New line for the next sample */
Serial.println("");
/* Wait the specified delay before requesting new data */
delay(BNO055_SAMPLERATE_DELAY_MS);
}
Единственное отличие в коде заключается в том, что вместо передачи структуры смещения я сохраняю информацию индивидуально, используя метод putInt
шаги
- Я калибрую датчик, подключенный через I2C.
- После завершения калибровки сохраните его в NVS.
- Понаблюдайте за значениями
- Перезапустите узел и получите смещения из NVS.
Проблема
Калибровочные смещения сохраняются в BNO, и это занимает hella time в следующем блоке:
if (foundCalib){
Serial.println("Move sensor slightly to calibrate magnetometers");
while (!bno.isFullyCalibrated())
{
bno.getEvent(&event);
displayCalStatus();
Serial.println("");
delay(BNO055_SAMPLERATE_DELAY_MS);
}
}
Я добавил displayCalStatus
, чтобы увидеть значения акселерометра, гироскопа и магнитометра, и все значения в блоке равны нулю.
Разве это не противоречит самой идее хранения смещений, если все значения равны нулю?
Вывод с платы
Found Calibration for this sensor in NVS.
Accelerometer: 19 -10 4
Gyro: -3 -4 9
Mag: 589 986 1473
Accel Radius: 0
Mag Radius: 0
Restoring Calibration data to the BNO055...
Calibration data loaded into BNO055
System Status: 0x0
Self Test: 0xF
System Error: 0x0
Move sensor slightly to calibrate magnetometers
! Sys:0 G:0 A:0 M:0
! Sys:0 G:0 A:0 M:0
! Sys:0 G:0 A:0 M:0
! Sys:0 G:3 A:0 M:0
! Sys:0 G:3 A:0 M:0
! Sys:0 G:3 A:0 M:0
! Sys:0 G:3 A:0 M:0
! Sys:0 G:3 A:0 M:0
! Sys:0 G:3 A:0 M:0
! Sys:0 G:3 A:0 M:0
! Sys:0 G:3 A:0 M:0
! Sys:0 G:3 A:0 M:0
! Sys:0 G:3 A:0 M:0
! Sys:0 G:3 A:0 M:0
Как вы можете заметить, все калибровки установлены на 0, и мне приходится делать все заново. почему?
@Shan-Desai, 👍1
Обсуждение1 ответ
Лучший ответ:
Функция displayCalStatus() показывает состояние калибровки, а не смещения или текущие значения датчика. Во время калибровки статус равен нулю. После завершения калибровки датчика его статус равен 3. Датчик начинает калибровку самостоятельно с первых движений после включения питания.
Установленные смещения используются после включения питания только до завершения первоначальной автоматической калибровки.
из таблицы данных:
После калибровки устройства профиль калибровки можно использовать повторно, чтобы получить исправить данные ориентации сразу после «Силы сброса». Однако как только датчик попадает во внутренний процедура калибровки, профиль калибровки перезаписывается с вновь полученными смещениями датчика и радиусом датчика.
Есть ли способ избежать выполнения процедуры внутренней калибровки BNO055?, @Shan-Desai
нет. почему для тебя это проблема? это происходит в фоновом режиме. датчики работают постоянно. запомненные смещения хороши, чтобы иметь лучшие значения для первых показаний, @Juraj
Проблема в том, что как только смещения восстанавливаются, я калибрую магнитометр, потому что это очень легко, но цикл while не получается легко. Мне приходится выполнять все методы калибровки вместе., @Shan-Desai
но в своем эскизе вы можете делать что хотите. эскиз смещений является примером. Я бы проигнорировал калибровку. Датчик с этим справляется. После включения питания выполните те же действия, и датчик откалибруется сам., @Juraj
Думаю, я попробую ваши вещи., @Shan-Desai
- Значения кватернионов из BNO055 недоступны.
- Контакты ESP32 не помещаются в беспаянную макетную плату
- Определение относительно точной скорости с помощью ИДУ
- Увеличить частоту дискретизации на плате ESP32
- Получить значения акселерометра от BNO055 с помощью Единой библиотеки датчиков adafruit
- Adafruit esp32 Feather не удалось скомпилировать
- Ошибка при компиляции программы для esp32 с Preferences.h
- Одинаковый вывод на дисплеях с разными I2C-адресами (библиотека AdaFruit, ESP32)
Должны ли мы предположить, что возвращаются ненулевые смещения калибровки, что они правильно сохраняются в NVS и что они правильно извлекаются из NVS? Вы все это проверили, так что единственная проблема заключается в том, что вы уверены, что вы «сохранили» ненулевые смещения в датчик, и он по-прежнему возвращает нулевые смещения при обратном считывании?, @jose can u c
Могу заверить вас, что значения не равны нулю. Я почти уверен, что полученные значения также не равны нулю из NVS. Однако я могу снова провести тесты и отредактировать вопрос, указав более конкретные значения, чтобы поддержать предположение., @Shan-Desai
Я спрашиваю только потому, что конкретные ценности – это единственный способ, с помощью которого члены сообщества могут оценить проблему., @jose can u c
Я вернусь к воспроизведению запроса и отредактирую вопрос со всеми соответствующими выходными данными узла и bno055., @Shan-Desai
@josecanuc Я добавил журнал со своей доски, @Shan-Desai