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 클래스의 인스턴스화로 인해 직렬 통신이 작동하지 않습니다 (직렬 모니터에서 텍스트를 볼 수 없음). 코드의 클래스 인스턴스 (코드에서 직렬 통신 만 사용)를 제거하면 직렬 모니터에서 인쇄 내용을 볼 수 있습니다.
아무도 어떤 일이 벌어지고 있는지에 대해 알지 못합니까? 나는 어떤 도움을 주셔서 감사합니다.
"while (Wire.available())"에 최대 시간 초과를 추가하여 영원히 차단하지 못하게 할 수도 있습니다. I2C가 올바르게 작동하지 않는 경우. – mpflaga
답변 해 주셔서 감사합니다. 난 바보 같은 실수를하고 있었다. 생성자에서 DATA_FORMAT 및 POWER_CTL에 값을 할당하기 전에 writeToAccelerometer 메서드를 호출하고 있었다. 나는 이것을 고쳤다. (이전에 과제를해라.)하지만 여전히 작동하지 않는다. CS에 대한이 고려 사항에서 핀 53을 출력으로 정의하고 digitalWrite (53, HIGH);를 작성했습니다. 이것으로 충분합니까? –