产品介绍
ATK IMU 901是新西兰威森公司(Hemisphere)生产的一款先进的惯导组合导航系统(strapdown INS)硬件平台。它集成了三轴陀螺仪、三轴加速度计和三轴磁力计,可以提供精密的角速度、加速度和磁场测量结果。该惯导组件广泛应用于各类导航定位和稳定控制系统中。
产品图片
Arduino
由于该模块不同数据,串口主动上传的长度不一致,姿态上传11位(双字节十六进制)、四元数上传13位、加速度和角速度上传17位,SSCOM程序直接读取串口内容,如下:
55 55 01 06 91 22 20 FF 0A 4C D9
55 55 02 08 FC 44 5F 20 95 29 0F 5E 9E
55 55 03 0C 7D 01 EB 2F 25 2A 94 00 D7 00 99 FF A3
55 55 06 08 56 03 5B 03 59 03 5C 03 2A
55 55 01 06 92 22 20 FF 0A 4C DA
55 55 02 08 FC 44 5F 20 96 29 0F 5E 9F
55 55 03 0C 68 01 2D 30 16 2A 39 00 07 01 E5 FF E4
55 55 06 08 72 03 6D 03 58 03 6F 03 6A
55 55 01 06 91 22 20 FF 0A 4C D9
55 55 02 08 FC 44 5E 20 95 29 10 5E 9E
55 55 03 0C 4B 01 5A 30 66 2A B6 FF 1B 01 07 00 F7
所以不能直接用mpu6050的例程,要修改一下。传感器手册同样也描述了传感器模块的帧格式的差异。
上传姿态角数据
因此程序书写时,需要将不同长度数据区分开。
话不多说,直接上代码
/*
This code is used for connecting arduino to serial ATK-IMU901 module, and test in arduino uno R3 board.
connect map:
arduino ATK901 module
VCC 5v/3.3v
TX RX<-0
TX TX->1
GND GND
*/
unsigned char Re_buf[16], counter = 0;
unsigned char sign = 0;
float acc[3], Roll, Pitch, Yaw, Q[4], w[3];
void setup() {
Serial.begin(115200);
}
void loop() {
if (sign)
{
sign = 0;
if (Re_buf[0] == 0x55) //检查帧头
{
switch (Re_buf [2])
{
case 0x01:
Roll = (short(Re_buf [5] << 8 | Re_buf [4])) / 32768.0 * 180;
Pitch = (float(Re_buf [7] << 8 | Re_buf [6])) / 32768.0 * 180;
Yaw = (float(Re_buf [9] << 8 | Re_buf [8])) / 32768.0 * 180;
// Serial.print("Angle:");
Serial.print(Roll); Serial.print(" ");
Serial.print(Pitch); Serial.print(" ");
Serial.print(Yaw); Serial.println(" ");
break;
case 0x02:
Q[0] = (float(Re_buf [5] << 8 | Re_buf [4])) / 32768.0;
Q[1] = (float(Re_buf [7] << 8 | Re_buf [6])) / 32768.0;
Q[2] = (float(Re_buf [9] << 8 | Re_buf [8])) / 32768.0;
Q[3] = (float(Re_buf [11] << 8 | Re_buf [10])) / 32768.0;
// Serial.print("Quarternion:");
Serial.print(Q[0]); Serial.print(" ");
Serial.print(Q[1]); Serial.print(" ");
Serial.print(Q[2]); Serial.print(" ");
Serial.print(Q[3]); Serial.println(" ");
break;
case 0x03:
acc[0] = (float(Re_buf [5] << 8 | Re_buf [4])) / 32768.0 * 2 * 9.8; // 2 为设置的1G单位刻度
acc[1] = (float(Re_buf [7] << 8 | Re_buf [6])) / 32768.0 * 2 * 9.8;
acc[2] = (float(Re_buf [9] << 8 | Re_buf [8])) / 32768.0 * 2 * 9.8;
w[0] = (float(Re_buf [11] << 8 | Re_buf [10])) / 32768.0 * 90;
w[1] = (float(Re_buf [13] << 8 | Re_buf [12])) / 32768.0 * 90;
w[2] = (float(Re_buf [15] << 8 | Re_buf [14])) / 32768.0 * 90;
// Serial.print("Accelerate:");
Serial.print(acc[0]); Serial.print(" ");
Serial.print(acc[1]); Serial.print(" ");
Serial.print(acc[2]); Serial.println(" ");
// Serial.print("Gravity:");
Serial.print(w[0]); Serial.print(" ");
Serial.print(w[1]); Serial.print(" ");
Serial.print(w[2]); Serial.println(" ");
break;
}
}
}
}
void serialEvent() {
while (Serial.available()) {
Re_buf[counter] = (unsigned char)Serial.read();
if (sizeof(Re_buf) < 11) // 判断接收缓冲区数据量是否充足
return;
if (counter == 0 && Re_buf[0] != 0x55) // 第0号数据不是帧头
return;
counter++;
switch (Re_buf [2]) // 根据数据帧类型判断
{
case 0x01:
if (counter == 10) {
counter = 0; // 重新赋值,准备下一帧数据的接收
sign = 1;
}
break;
case 0x02:
if (counter == 12) {
counter = 0;
sign = 1;
}
break;
case 0x03:
if (counter == 16) {
counter = 0;
sign = 1;
}
break;
default: // 增加其他类型数据帧的判断
break;
}
if (counter > 16 && sign == 0)
{
counter = 0; // 清除计数器,重新开始接收新的数据帧
}
}
}
输出的数据可以和ATK-IMU的上位机数据作对比。
由于该陀螺仪为6轴信号,所以只显示加速度、角速度、角度和四元数(端口数据我未读取)。磁场、气压需9轴版本方可支持。