Arduino와 ADXL345 3축 가속도 센서를 활용한 다양한 실험

Arduino와 ADXL345 3축 가속도 센서를 활용한 다양한 실험

Arduino 플랫폼에서 사용 가능한 수많은 센서 모듈 중 ADXL345 3축 가속도 센서는 특히 인기 있는 선택이다. 이 센서는 I2C 또는 SPI 통신을 통해 3차원 공간에서의 가속도를 정밀하게 측정할 수 있으며, 기울기 감지, 충격 탐지, 진동 분석 등 다양한 응용에 적합하다.

실험 1: ADXL345 라이브러리를 이용한 각도 측정 및 보정

이 실험에서는 ADXL345_WE 라이브러리를 사용하여 정확한 각도 측정과 보정을 수행한다. 센서는 I2C 프로토콜을 사용하며, A4 핀이 데이터선(SDA), A5 핀이 클럭선(SCL)으로 연결된다.


#include <Wire.h>
#include <ADXL345_WE.h>

#define ACCELEROMETER_ADDRESS 0x53

ADXL345_WE sensor = ADXL345_WE(ACCELEROMETER_ADDRESS);

void setup() {
  Wire.begin();
  Serial.begin(9600);
  Serial.println("가속도 센서 테스트 시작");
  
  if (!sensor.initialize()) {
    Serial.println("센서 연결 확인 필요");
    return;
  }

  // 보정 계수 설정 (이전 보정 프로그램에서 얻은 값)
  sensor.setCalibrationFactors(-268.0, 283.0, -270.0, 276.0, -289.0, 216.0);

  Serial.println("센서를 평면에 수평으로 놓고 2초 대기");
  delay(2000);
  sensor.calculateAngleOffset();
  Serial.println("보정 완료");

  sensor.setDataRate(ADXL345_DATA_RATE_50);
  Serial.print("데이터 전송 속도: ");
  Serial.print(sensor.getDataRateString());

  sensor.setMeasurementRange(ADXL345_RANGE_2G);
  Serial.print("  /  측정 범위: ");
  Serial.println(sensor.getRangeString());
}

void loop() {
  xyzFloat rawData = sensor.getRawAcceleration();
  xyzFloat gravityData = sensor.getGravityValues();
  xyzFloat angles = sensor.getTiltAngles();
  xyzFloat correctedAngles = sensor.getCorrectedAngles();

  Serial.print("원시 X = ");
  Serial.print(rawData.x);
  Serial.print("  |  원시 Y = ");
  Serial.print(rawData.y);
  Serial.print("  |  원시 Z = ");
  Serial.println(rawData.z);

  Serial.print("중력 X = ");
  Serial.print(gravityData.x);
  Serial.print("  |  중력 Y = ");
  Serial.print(gravityData.y);
  Serial.print("  |  중력 Z = ");
  Serial.println(gravityData.z);

  Serial.print("각도 X = ");
  Serial.print(angles.x);
  Serial.print("  |  각도 Y = ");
  Serial.print(angles.y);
  Serial.print("  |  각도 Z = ");
  Serial.println(angles.z);

  Serial.print("보정 각도 X = ");
  Serial.print(correctedAngles.x);
  Serial.print("  |  보정 각도 Y = ");
  Serial.print(correctedAngles.y);
  Serial.print("  |  보정 각도 Z = ");
  Serial.println(correctedAngles.z);

  Serial.print("방향 상태: ");
  Serial.println(sensor.getDirectionString());
  
  delay(500);
}

실험 2: LED 매트릭스를 활용한 가속도 시각화

이 실험은 8x8 LED 매트릭스와 ADXL345 센서를 결합하여 가속도 방향을 시각적으로 표현한다. 센서의 값을 매핑하여 LED 매트릭스 상의 점을 이동시키는 효과를 구현한다.


#include <LedControl.h>
#include <Wire.h>

#define SENSOR_ADDR 0x53
#define READ_BYTES 6

byte buffer[READ_BYTES];
LedControl ledMatrix = LedControl(12, 10, 11, 1);
unsigned long refreshDelay = 50;

class GravityPoint {
  public:
    int posX = 0;
    int posY = 0;
    int weight = 1;
};

GravityPoint *gravityObject;

void setup() {
  gravityObject = new GravityPoint();
  initializeDisplay();
  
  Wire.begin();
  Serial.begin(9600);

  configureSensor(SENSOR_ADDR, 0x2D, 0);
  configureSensor(SENSOR_ADDR, 0x2D, 16);
  configureSensor(SENSOR_ADDR, 0x2D, 8);
}

void loop() {
  int startRegister = 0x32;
  int accX, accY, accZ;

  readAccelerationData(SENSOR_ADDR, startRegister, READ_BYTES, buffer);

  accX = combineBytes(buffer[1], buffer[0]);
  accY = combineBytes(buffer[3], buffer[2]);
  accZ = combineBytes(buffer[5], buffer[4]);

  accX = mapValue(accX, -300, 300, 0, 8);
  accY = mapValue(accY, -300, 300, 0, 8);
  accZ = mapValue(accZ, -300, 300, 0, 8);

  Serial.print("X축: ");
  Serial.print(accX);
  Serial.print("   Y축: ");
  Serial.print(accY);
  Serial.print("   Z축: ");
  Serial.println(accZ);

  clearMatrix();
  gravityObject->posX = constrain(accX, 0, 7);
  gravityObject->posY = constrain(accY, 0, 7);
  ledMatrix.setLed(0, gravityObject->posX, gravityObject->posY, true);

  delay(10);
}

void initializeDisplay() {
  int deviceCount = ledMatrix.getDeviceCount();
  for (int addr = 0; addr < deviceCount; addr++) {
    ledMatrix.shutdown(addr, false);
    ledMatrix.setIntensity(addr, 1);
    ledMatrix.clearDisplay(addr);
  }
}

void configureSensor(int deviceAddr, byte reg, byte value) {
  Wire.beginTransmission(deviceAddr);
  Wire.write(reg);
  Wire.write(value);
  Wire.endTransmission();
}

void readAccelerationData(int deviceAddr, byte reg, int count, byte* outputBuffer) {
  Wire.beginTransmission(deviceAddr);
  Wire.write(reg);
  Wire.endTransmission();
  
  Wire.requestFrom(deviceAddr, count);
  int index = 0;
  while (Wire.available()) {
    outputBuffer[index] = Wire.read();
    index++;
  }
  delay(10);
}

int combineBytes(byte highByte, byte lowByte) {
  return ((int)highByte << 8) | lowByte;
}

int mapValue(int input, int inMin, int inMax, int outMin, int outMax) {
  return (input - inMin) * (outMax - outMin) / (inMax - inMin) + outMin;
}

void clearMatrix() {
  ledMatrix.clearDisplay(0);
}

실험 3: 가속도 센서를 통한 LED 제어

이 간단한 실험에서는 ADXL345 센서의 가속도 값을 기준으로 아두이노의 내장 LED(D13 핀)를 제어한다. 특정 축의 가속도가 임계값을 초과하면 LED가 점등된다.


#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_ADXL345_U.h>

#define LED_PORT 13

Adafruit_ADXL345_Unified accelerometer = Adafruit_ADXL345_Unified();

void setup() {
  Serial.begin(9600);
  Serial.println("가속도 센서 기반 LED 제어");
  
  if (!accelerometer.begin()) {
    Serial.println("가속도 센서 인식 실패");
    while (1);
  }
  pinMode(LED_PORT, OUTPUT);
}

void loop() {
  sensors_event_t dataEvent;
  accelerometer.getEvent(&dataEvent);
  
  float xAxis = dataEvent.acceleration.x;
  float yAxis = dataEvent.acceleration.y;
  float zAxis = dataEvent.acceleration.z;

  Serial.print("X: "); 
  Serial.print(xAxis); 
  Serial.print("  ");
  Serial.print("Y: "); 
  Serial.print(yAxis); 
  Serial.print("  ");
  Serial.print("Z: "); 
  Serial.print(zAxis); 
  Serial.println(" m/s²");

  if (abs(xAxis) > 5.0) {
    digitalWrite(LED_PORT, HIGH);
    Serial.println("X축 임계치 초과 - LED ON");
  } else if (abs(yAxis) > 5.0) {
    digitalWrite(LED_PORT, HIGH);
    Serial.println("Y축 임계치 초과 - LED ON");
  } else {
    digitalWrite(LED_PORT, LOW);
  }
  
  delay(500);
}

태그: Arduino ADXL345 가속도 센서 I2C 3축 센서

8월 10일 18:25에 게시됨