2014-01-11 2 views
0

자기 균형 로봇 프로젝트를 진행 중이고 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) 
    } 
} 

답변

0

나는 그것이 바이트 형식의 문제가 될 수 있다고 생각합니다. 컴파일러보다 실제로 buff [2]에서 바이트를 사용하면 바이트 (8 비트)가 8로 nirwana로 이동합니다. 결과는 0이되며 이것은 버프 [3]와 오르간 결합됩니다. 컴파일러는 다음 단계로 작동합니다.

원본 :

바이트 [6]; 용액

accel_x = ((buff[2]) << 8) | buff[3]; // X axis (internal sensor y axis) 

:

accel_x = (((int16_t)buff[2]) << 8) | buff[3]; // X axis (internal sensor y axis) 

또는 단계

accel_x= buff[2];//accel_x has 16-bit-format 
accel_x<<= 8; 
accel_x|= buff[3]; 
관련 문제