자기 균형 로봇 프로젝트를 진행 중이고 ITG-3200 자이로와 함께 ADXL345 가속도계를 사용하여 로봇 기울기를 감지하고 있습니다.ADXL345 Arduino Due로 가속도 정수 오버플로
Arduino Due는 표준 정수를 32 비트 숫자로 저장하므로 16 비트 부호있는 데이터가 모두 양수로 표시되고 음수는 65000 이상인 부호있는 데이터가 올바르게 표시되지 않는 문제가있었습니다. 몇 가지 연구를 수행했으며 서명 된 16 비트 시스템을 유지하기 위해 전체적으로 int16_t
을 구현했지만 새로운 문제를 발견했습니다.
로봇이 어느 방향 으로든 35도 이상 기울어 진 후에 정수가 넘치기 시작하여 32,767 이상의 숫자가 다시 감소하기 시작한 것 같습니다. 이것은 분명히 로봇의 각도를 결정할 때 적합하지 않습니다. 이 값을 다시 축소하거나 전체 범위에 대해 유효한 데이터의 상수 스트림을 수신하는 방법이 있습니까? 아래
참조 코드 :
#include <stdint.h>
int16_t accel_x;
int16_t accel_y;
int16_t accel_z;
int16_t gyro_x;
int16_t gyro_y;
int16_t gyro_z;
void setup()
{
// Init serial output
Serial.begin(57600);
// Init sensors
delay(50); // Give sensors enough time to start
I2C_Init();
Accel_Init();
Gyro_Init();
}
void loop()
{
Read_Accel();
Serial.print("#A:");
Serial.print(accel_x); Serial.print(",");
Serial.print(accel_y); Serial.print(",");
Serial.print(accel_z); Serial.println();
Read_Gyro();
Serial.print("#G:");
Serial.print(gyro_x); Serial.print(",");
Serial.print(gyro_y); Serial.print(",");
Serial.print(gyro_z); Serial.println();
}
// *******************I2C code to read the sensors************************
#include <Wire.h>
// Sensor I2C addresses
#define ACCEL_ADDRESS ((int) 0x53) // 0x53 = 0xA6/2
#define GYRO_ADDRESS ((int) 0x68) // 0x68 = 0xD0/2
void I2C_Init()
{
Wire.begin();
}
void Accel_Init()
{
Wire.beginTransmission(ACCEL_ADDRESS);
Wire.write(0x2D); // Power register
Wire.write(0x08); // Measurement mode
Wire.endTransmission();
delay(5);
Wire.beginTransmission(ACCEL_ADDRESS);
Wire.write(0x31); // Data format register
Wire.write(0x08); // Set to full resolution
Wire.endTransmission();
delay(5);
// Adjust the output data rate to 100Hz (50Hz bandwidth)
Wire.beginTransmission(ACCEL_ADDRESS);
Wire.write(0x2C); // Rate
Wire.write(0x0A); // Set to 100Hz, normal operation
Wire.endTransmission();
delay(5);
}
// Reads x, y and z accelerometer registers
void Read_Accel()
{
int i = 0;
byte buff[6];
Wire.beginTransmission(ACCEL_ADDRESS);
Wire.write(0x32); // Send address to read from
Wire.endTransmission();
Wire.beginTransmission(ACCEL_ADDRESS);
Wire.requestFrom(ACCEL_ADDRESS, 6); // Request 6 bytes
while(Wire.available()) // ((Wire.available())&&(i<6))
{
buff[i] = Wire.read(); // Read one byte
i++;
}
Wire.endTransmission();
{
accel_x = ((buff[2]) << 8) | buff[3]; // X axis (internal sensor y axis)
accel_y = ((buff[0]) << 8) | buff[1]; // Y axis (internal sensor x axis)
accel_z = ((buff[4]) << 8) | buff[5]; // Z axis (internal sensor z axis)
}
}
void Gyro_Init()
{
// Power up reset defaults
Wire.beginTransmission(GYRO_ADDRESS);
Wire.write(0x3E);
Wire.write(0x80);
Wire.endTransmission();
delay(5);
// Select full-scale range of the gyro sensors
// Set LP filter bandwidth to 42Hz
Wire.beginTransmission(GYRO_ADDRESS);
Wire.write(0x16);
Wire.write(0x1B); // DLPF_CFG = 3, FS_SEL = 3
Wire.endTransmission();
delay(5);
// Set sample rato to 100Hz
Wire.beginTransmission(GYRO_ADDRESS);
Wire.write(0x15);
Wire.write(0x09); // SMPLRT_DIV = 9 (100Hz)
Wire.endTransmission();
delay(5);
// Set clock to PLL with z gyro reference
Wire.beginTransmission(GYRO_ADDRESS);
Wire.write(0x3E);
Wire.write(0x00);
Wire.endTransmission();
delay(5);
}
// Reads x, y and z gyroscope registers
void Read_Gyro()
{
int i = 0;
byte buff[6];
Wire.beginTransmission(GYRO_ADDRESS);
Wire.write(0x1D); // Sends address to read from
Wire.endTransmission();
Wire.beginTransmission(GYRO_ADDRESS);
Wire.requestFrom(GYRO_ADDRESS, 6); // Request 6 bytes
while(Wire.available()) // ((Wire.available())&&(i<6))
{
buff[i] = Wire.read(); // Read one byte
i++;
}
Wire.endTransmission();
{
gyro_x = (((buff[2]) << 8) | buff[3]); // X axis (internal sensor -y axis)
gyro_y = (((buff[0]) << 8) | buff[1]); // Y axis (internal sensor -x axis)
gyro_z = (((buff[4]) << 8) | buff[5]); // Z axis (internal sensor -z axis)
}
}