Выяснил следующее. Примем, что ось 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 начинается "бред"

Подозреваю, что я с математикой напортачил.
Код
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 - Jul 22 2012, 15:51