Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Акселерометр LIS302DL.
Форум разработчиков электроники ELECTRONIX.ru > Аналоговая и цифровая техника, прикладная электроника > Метрология, датчики, измерительная техника
SZ0
При расположении акселерометра как на рис. 2 и 4, где ось Z перпендикулярна земле датчик выдаёт показания, после расчёта которых получаются правильные углы если его отклонять до положения оси Z как на рис. 1 и 3. Как только ось Z начинает приближаться к положению горизонтально земле (рис. 1 и 3), то данные начинают скакать с огромной погрешностью. С чем это связано?
dac
а можно в цифрах - при каких углах какая погрешность (которая большая). по логике то понятно - на малых значениях большие ошибки - либо помеха, либо разрядность измерения
SZ0
Выяснил следующее. Примем, что ось Y фиксирована. Когда ось Х и Z поворачиваются относительно Y на рис. 1 влево вправо (ось Х как бы раскачивается с небольшой амплитудой), то при положении оси Х почти перпендикулярно из расчётов выходят углы:
Х 4 7 5 (хотя по Х тут угол должен быть в приделах 90)
У 13 35 19 (хотя Y в приделах 0)
но стоит Х начать опускаться ниже, начинают выводится нормальные углы в приделах 80 градусов и ниже. Как при заваливании Х влево, так и вправо.

На рис. 3 аналогичная ситуация при оси Х находящейся почти перпендикулярно вниз:
Х -7 -5 -3 (хотя по Х тут угол должен быть в приделах -90)
У 74 46 35 (хотя Y в приделах 0)
Стоит Х начать подниматься выше -80, как по Х и Y начинают выводится нормальные результаты.

При качании по осям на рис. 1 и 2 нормальные результаты получаются. Стоит углу по Х подойти к 80 или -80 начинается "бред" sad.gif

Подозреваю, что я с математикой напортачил.

Код
typedef     float                   f32;
#define     SENS18      0.018

  buff8mX = 0;
  buff8mY = 0;
  buff8mZ = 0;
  
  SENS = SENS18;

// определяем знак угла
// в  X, Y и Z значения, считанные из LIS302DL

  if(X > 127)
  {
   X = 255 - X;
   buff8mX = 1;
  }

  if(Y > 127)
  {
   Y = 255 - Y;
   buff8mY = 1;
  }

  if(Z > 127)
  {
   buff8mZ = 1;
   Z = 255 - Z;
  }

  // расчёт угла Х  

  if(buff8mX)uart_tx_byte('-'); // вывод знака угла "-"
  buff8 = (u8)(atan(((f32)((f32)X*SENS))/(sqrt((((f32)((f32)Y*SENS))*((f32)((f32)Y*SENS)))+(((f32)((f32)Z*SENS))*((f32)((f32)Z*SENS)))))) * 180) / M_PI; // расчёт угла
  itoa_usr(buff8); // преобразование значения в строку
  uart_tx_str((const char *)buff_str); // вывод строки

  // расчёт угла Y

  uart_tx_str((const char *)OutY);
  if(buff8mY)uart_tx_byte('-');
  buff8 = (u8)(atan(((f32)((f32)Y*SENS))/(sqrt((((f32)((f32)X*SENS))*((f32)((f32)X*SENS)))+(((f32)((f32)Z*SENS))*((f32)((f32)Z*SENS)))))) * 180) / M_PI;            
  itoa_usr(buff8);
  uart_tx_str((const char *)buff_str);
SZ0
Дело было в скобочках.

buff8 = (u8)((atan(((f32)((f32)X*SENS))/(sqrt((((f32)((f32)Y*SENS))*((f32)((f32)Y*SENS)))+(((f32)((f32)Z*SENS))*((f32)((
f32)Z*SENS)))))) * 180) / M_PI);

Поставил, пока только в симуляторе проверил (макетку сломал по неаккуратности).
jorikdima
Цитата(SZ0 @ Jul 27 2012, 12:05) *
Дело было в скобочках.

buff8 = (u8)((atan(((f32)((f32)X*SENS))/(sqrt((((f32)((f32)Y*SENS))*((f32)((f32)Y*SENS)))+(((f32)((f32)Z*SENS))*((f32)((
f32)Z*SENS)))))) * 180) / M_PI);

Поставил, пока только в симуляторе проверил (макетку сломал по неаккуратности).

Чтоб в следующий раз не убить кучу времени на ерунду, не пишите таких выражений. Разбивайте на несколько. Ассемблерный код при правильном программировании не увеличится, а гемора станет меньше.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.