2014-12-24 3 views
0

C++ 스타일 라이브러리를 사용하여 ADXL345 가속도계와 통신하는 Arduino 메가의 코드를 작성하려고합니다. 이 내 Accelerometer.h 파일입니다Arduino 환경에서 클래스가 인스턴스화 될 때 직렬 통신이 작동하지 않음

#include <Wire.h> 
#define ADXL345 (0x53) // I2C Address of ADXL345 accelerometer 

struct Acceleration 
{ 
    float x; 
    float y; 
    float z; 
}; 

class Accelerometer 
{ 
    public: 
    Accelerometer(void);    // Constructor 
    Acceleration readData(void);     // Read sensor data 
    private: 
    char buffer[6]; // Buffer to store data (x, y, z: LSB and MSB of each) 
    char DATA_FORMAT; // Address of DATA_FORMAT Register 
    char POWER_CTL; // Address of POWER_CTL Register 
    char DATAX0;  // Address of X-Axis LSB Data 
    char DATAX1;  // Address of X-Axis MSB Data 
    char DATAY0;  // Address of Y-Axis LSB Data 
    char DATAY1;  // Address of Y-Axis MSB Data 
    char DATAZ0;  // Address of Z-Axis LSB Data 
    char DATAZ1;  // Address of Z-Axis MSB Data 
    void writeToAccelerometer(char address, char value); 
    void readFromAccelerometer(char address, int numOfBytes); 
}; 

그리고 이것은 내 Accelerometer.cpp 파일입니다

#include "Accelerometer.h" 
#include <Wire.h> 

Accelerometer::Accelerometer() 
{ 
    Wire.begin();        // Initialize I2C bus 
    writeToAccelerometer(DATA_FORMAT, 0x01);  // +/- 4g range 
    writeToAccelerometer(POWER_CTL, 0x08);  // Measurement Mode 

    DATA_FORMAT = 0x31;  // Address of DATA_FORMAT Register 
    POWER_CTL = 0x2D;  // Address of POWER_CTL Register 
    DATAX0  = 0x32;  // Address of X-Axis LSB Data 
    DATAX1  = 0x33;  // Address of X-Axis MSB Data 
    DATAY0  = 0x34;  // Address of Y-Axis LSB Data 
    DATAY1  = 0x35;  // Address of Y-Axis MSB Data 
    DATAZ0  = 0x36;  // Address of Z-Axis LSB Data 
    DATAZ1  = 0x37;  // Address of Z-Axis MSB Data 
} 

void Accelerometer::writeToAccelerometer(char address, char value) 
{ 
    Wire.beginTransmission(ADXL345); // start transmission to ADXL345 
    Wire.write(address);    // send register address 
    Wire.write(value);    // send value to write 
    Wire.endTransmission();   // end transmission 
} 

void Accelerometer::readFromAccelerometer(char address, int numOfBytes) 
{ 
    Wire.beginTransmission(ADXL345); // start transmission to ADXL345 
    Wire.write(address);    // send register address 
    Wire.endTransmission();   // end transmission 

    Wire.beginTransmission(ADXL345);   // start transmission to ADXL345 
    Wire.requestFrom(ADXL345, numOfBytes); // request some bytes from device 

    int i = 0; 
    while(Wire.available())   // while there is data 
    { 
    buffer[i] = Wire.read();  // receive a byte and save it in the buffer 
    i++; 
    } 
    Wire.endTransmission();   // end transmission 
} 

Acceleration Accelerometer::readData() 
{ 
    Acceleration R; 
    readFromAccelerometer(DATAX0, 6);   // Read data from sensor 

    // Merge of data and conversion to int format 
    int x_acceleration = (((int)buffer[1]) << 8) | buffer[0]; 
    int y_acceleration = (((int)buffer[3]) << 8) | buffer[2]; 
    int z_acceleration = (((int)buffer[5]) << 8) | buffer[4]; 

    R.x = x_acceleration*0.0078; 
    R.y = x_acceleration*0.0078; 
    R.z = x_acceleration*0.0078; 

    return R; 
} 

이 코드 내 아두 이노 스케치 메신저이 라이브러리를 사용하고 있습니다 :

#include <Wire.h> 
#include "Accelerometer.h" 

Accelerometer accel; 
Acceleration Racc; 

void setup() 
{ 
    Serial.begin(9600); // Start serial for outbut at 9600 bps 
} 

void loop() 
{ 
    Racc = accel.readData(); 

    // Print data 
    Serial.print("ACCELERATION - X: "); 
    Serial.print(Racc.x); 
    Serial.print(" G/Y: "); 
    Serial.print(Racc.y); 
    Serial.print(" G/Z: "); 
    Serial.print(Racc.z); 
    Serial.print(" G\n"); 

    delay(100); 
} 

이 코드는 오류없이 컴파일됩니다. 그러나 Accelerometer 클래스의 인스턴스화로 인해 직렬 통신이 작동하지 않습니다 (직렬 모니터에서 텍스트를 볼 수 없음). 코드의 클래스 인스턴스 (코드에서 직렬 통신 만 사용)를 제거하면 직렬 모니터에서 인쇄 내용을 볼 수 있습니다.

아무도 어떤 일이 벌어지고 있는지에 대해 알지 못합니까? 나는 어떤 도움을 주셔서 감사합니다.

답변

0

ADXL345는 SPI 또는 I2C를 작동시킬 수 있으므로 반드시 구성해야합니다. I2C로 사용하려고 당신의 경우, ADXL345의 CS는 CS의 pinis는 VDD I/O 높은 묶여 활성화됩니다 3.3V

I2C 모드로 연결해야합니다. CS 핀 은 CS 핀이 연결되지 않은 상태에서 노드 폴트 모드가 있기 때문에 항상 을 VDD I/O에 하이로 연결하거나 외부 컨트롤러로 구동해야한다. 따라서 이러한 사전주의 사항을 따르지 않으면 해당 부품과의 통신이 불가능해질 수 있습니다.

위의 코드에서 CS를 구동하기 위해 출력으로 구성된 핀이 보이지 않습니다.

I2C (wire.h) 라이브러리가 장치에 제대로 연결되어 있지 않으면 블로킹 할 수 있습니다. 여기에 설명 된 증상과 유사합니다. 같은 https://github.com/jenschr/Arduino-libraries/tree/master/ADXL345으로 당신은 다른 사람에 대한 코드를 참조 할 수 있습니다


. I2C를 통해 ADXL345의 많은 기능을 완벽하게 지원하는 것으로 보입니다.

+0

"while (Wire.available())"에 최대 시간 초과를 추가하여 영원히 차단하지 못하게 할 수도 있습니다. I2C가 올바르게 작동하지 않는 경우. – mpflaga

+0

답변 해 주셔서 감사합니다. 난 바보 같은 실수를하고 있었다. 생성자에서 DATA_FORMAT 및 POWER_CTL에 값을 할당하기 전에 writeToAccelerometer 메서드를 호출하고 있었다. 나는 이것을 고쳤다. (이전에 과제를해라.)하지만 여전히 작동하지 않는다. CS에 대한이 고려 사항에서 핀 53을 출력으로 정의하고 digitalWrite (53, HIGH);를 작성했습니다. 이것으로 충분합니까? –

관련 문제