Nano 33 BLE Sense 가속도계 LSM9DS1 3D 시각화
Nano 33 BLE Sense 3D Visualization with Accelerometer LSM9DS1.
가속도계의 움직임을 3D 시각화하려고 보니 적당한 내용이 있어서 소개합니다. 아래 내용은 ADXL345 가속도계와 아두이노 나노보드를 사용했고 출력을 Processing 코드를 사용하여 시각화한 것입니다.
우리는 Nnao 33 BLE Sense 보드와 Processing 코드로 구현할 것입니다. 아래 내용은 원문 사이트 내용을 번역하여 올린 것이다. 구현하고자 하는 내용은 동일하므로 내용을 참고하기 바랍니다.
이 튜토리얼에서는 Arduino 및 ADXL345 가속도계 센서를 사용하여 각도 및 트랙 방향을 측정하는 방법을 배웁니다. 자세한 내용은 다음 비디오를 보거나 아래 작성된 자습서를 읽을 수 있습니다.
먼저 센서의 작동 방식과 센서에서 데이터를 읽는 방법을 설명하고 Processing 개발 환경을 사용하여 가속도계 방향의 3D 시각화를 만들 것입니다.
ADXL345 가속도계의 작동 원리와 움직이는 각도의 계산
먼저 ADXL345 센서가 어떻게 작동하는지 살펴보겠습니다. 정적 및 동적 가속력을 모두 측정할 수 있는 3 축 가속도계입니다. 지구 중력은 정적 인 힘의 전형적인 예이며 동적 힘은 진동, 움직임 등에 의해 발생할 수 있습니다. 가속도 측정 단위는 초당 미터 제곱 (m/s^2)입니다. 그러나 가속도계 센서는 일반적으로 "g"또는 중력으로 측정값을 표시합니다. 하나의 "g"는 초당 9.8 미터 제곱에 해당하는 지구 중력의 값입니다. 따라서 가속도계가 중력과 반대로 Z 축이 위쪽을 향하도록 평평하게 배치된 경우 센서의 Z 축 출력은 1g가 됩니다. 반면에 중력이 이러한 축에 수직이고 전혀 영향을 미치지 않기 때문에 X 및 Y 출력은 0이 됩니다. 센서를 거꾸로 뒤집으면 Z 축 출력은 -1g가 됩니다. 이것은 중력에 대한 방향으로 인한 센서의 출력이 -1g에서 + 1g까지 다양할 수 있음을 의미합니다. 따라서 이 데이터에 따라 삼각법 수학을 사용하여 센서가 위치하는 각도를 계산할 수 있습니다.
Arduino로 ADXL345 가속도계 데이터를 읽는 방법
이제 Arduino를 사용하여 ADXL345 가속도계 데이터를 읽는 방법을 살펴보겠습니다. 이 센서는 Arduino와의 통신을 위해 I2C 프로토콜을 사용하므로 연결을 위한 두 개의 와이어와 전원을 공급하기 위한 두 개의 와이어만 필요합니다.
ADXL345 가속도계 Arduino 코드입니다. 코드의 출처는 아래 참고자료 원문 사이트고, 이 코드 아래에 Nano 33 BLE Sense 보드에서 가속도계의 값을 읽어오는 코드를 제공합니다.
/*
Arduino and ADXL345 Accelerometer - 3D Visualization Example
by Dejan, https://howtomechatronics.com
*/
#include <Wire.h> // Wire library - used for I2C communication
int ADXL345 = 0x53; // The ADXL345 sensor I2C address
float X_out, Y_out, Z_out; // Outputs
float roll,pitch,rollF,pitchF=0;
void setup() {
Serial.begin(9600); // Initiate serial communication for printing the results on the Serial monitor
Wire.begin(); // Initiate the Wire library
// Set ADXL345 in measuring mode
Wire.beginTransmission(ADXL345); // Start communicating with the device
Wire.write(0x2D); // Access/ talk to POWER_CTL Register - 0x2D
// Enable measurement
Wire.write(8); // Bit D3 High for measuring enable (8dec -> 0000 1000 binary)
Wire.endTransmission();
delay(10);
//Off-set Calibration
//X-axis
Wire.beginTransmission(ADXL345);
Wire.write(0x1E);
Wire.write(1);
Wire.endTransmission();
delay(10);
//Y-axis
Wire.beginTransmission(ADXL345);
Wire.write(0x1F);
Wire.write(-2);
Wire.endTransmission();
delay(10);
//Z-axis
Wire.beginTransmission(ADXL345);
Wire.write(0x20);
Wire.write(-9);
Wire.endTransmission();
delay(10);
}
void loop() {
// === Read acceleromter data === //
Wire.beginTransmission(ADXL345);
Wire.write(0x32); // Start with register 0x32 (ACCEL_XOUT_H)
Wire.endTransmission(false);
Wire.requestFrom(ADXL345, 6, true); // Read 6 registers total, each axis value is stored in 2 registers
X_out = ( Wire.read() | Wire.read() << 8); // X-axis value
X_out = X_out / 256; //For a range of +-2g, we need to divide the raw values by 256, according to the datasheet
Y_out = ( Wire.read() | Wire.read() << 8); // Y-axis value
Y_out = Y_out / 256;
Z_out = ( Wire.read() | Wire.read() << 8); // Z-axis value
Z_out = Z_out / 256;
// Calculate Roll and Pitch (rotation around X-axis, rotation around Y-axis)
roll = atan(Y_out / sqrt(pow(X_out, 2) + pow(Z_out, 2))) * 180 / PI;
pitch = atan(-1 * X_out / sqrt(pow(Y_out, 2) + pow(Z_out, 2))) * 180 / PI;
// Low-pass filter
rollF = 0.94 * rollF + 0.06 * roll;
pitchF = 0.94 * pitchF + 0.06 * pitch;
Serial.print(rollF);
Serial.print("/");
Serial.println(pitchF);
}
위 코드와 정확히 같은 동작을 하는 Nano 33 BLE Sense 코드입니다. LSM9DS1 가속도계에 관한 자세한 설명과 테스트 코드는 링크를 따라 가십시요. roll, pitch 구하는 코드도 참고문서와 동일하게 반영했습니다. 결과가 약간 다른 문제가 있습니다. 나중에 설명합니다.
/*
Arduino LSM9DS1 - Simple Accelerometer
This example reads the acceleration values from the LSM9DS1
sensor and continuously prints them to the Serial Monitor
or Serial Plotter.
The circuit:
- Arduino Nano 33 BLE Sense
created 10 Jul 2019
by Riccardo Rizzo
This example code is in the public domain.
*/
#include <Arduino_LSM9DS1.h>
float roll,pitch,rollF,pitchF = 0;
void setup() {
Serial.begin(9600);
while (!Serial);
Serial.println("Started");
if (!IMU.begin()) {
Serial.println("Failed to initialize IMU!");
while (1);
}
Serial.print("Accelerometer sample rate = ");
Serial.print(IMU.accelerationSampleRate());
Serial.println(" Hz");
Serial.println();
Serial.println("Acceleration in G's");
Serial.println("X\tY\tZ");
}
void loop() {
float x, y, z;
if (IMU.accelerationAvailable()) {
IMU.readAcceleration(x, y, z);
x = x / 256;
y = y / 256;
z = z / 256;
/*Serial.print(x);
Serial.print('\t');
Serial.print(y);
Serial.print('\t');
Serial.println(z);*/
// Calculate Roll and Pitch (rotation around X-axis, rotation around Y-axis)
roll = atan(y / sqrt(pow(x, 2) + pow(z, 2))) * 180 / PI;
pitch = atan(-1 * x / sqrt(pow(x, 2) + pow(z, 2))) * 180 / PI;
// Low-pass filter
rollF = 0.94 * rollF + 0.06 * roll;
pitchF = 0.94 * pitchF + 0.06 * pitch;
Serial.print(rollF);
Serial.print("/");
Serial.println(pitchF);
}
}
가속도계 3D 시각화 예제를 만들어 보겠습니다.
프로세싱 코드를 작성하기 전에 우선 가속도계의 센서 데이터를 보정 Calibration 해야 합니다. 자세한 설명은 freescale Semiconductor application note 문서를 참고하시고, 아래에는 실제 ADXL345 가속도계를 가지고 보정하는 방법을 설명합니다.
ADXL345 가속기 교정
그럼에도 불구하고 데이터를 읽은 후에는 값이 예상대로인지 확인하기 위해 직렬 모니터에 간단히 인쇄할 수 있습니다. 제 경우에는 제가 얻은 값이 정확하지 않았으며 특히 0.1g의 눈에 띄는 오차가 있는 Z 축이 필요했습니다.
이 문제를 해결하려면 3 개의 오프셋 교정 레지스터를 사용하여 가속도계를 교정해야 합니다. 이를 수행하는 방법은 다음과 같습니다. 따라서 센서를 평평하게 배치하고 RAW 값을 256으로 나누지 않고 인쇄해야 합니다.
이제 여기에서 출력이 얼마나 꺼져 있는지 알 수 있습니다. 제 경우에는 Z 출력이 약 283이었습니다. 이는 양수에서 27의 차이입니다. 이제이 값을 4로 나누어야 합니다. 그러면 Z 축 오프셋 레지스터에 쓰는 데 필요한 숫자를 사용할 수 있습니다. 지금 코드를 업로드하면 Z 축 출력은 정확히 256 또는 1g가 됩니다.
필요한 경우 동일한 방법을 사용하여 다른 축을 보정해야 합니다. 그리고이 보정은 레지스터에 영구적으로 기록되지 않습니다. 센서를 켤 때마다 레지스터에 이 값을 써야 합니다.
보정이 끝나면 마지막으로 이 두 공식을 사용하여 Roll and Pitch 또는 X 축을 중심으로 한 회전과 Y 축을 중심으로 한 회전을 계산할 수 있습니다.
다 되었습니다.
따라서 직렬 포트를 통해 Roll 및 Pitch 값을 보내는 동일한 코드를 사용하고 있습니다.
이제 Processing 개발 환경에서 이러한 값을 받아 생성할 3D 개체를 회전하는 데 사용해야 합니다. 링크를 따라가서 즉시 설치하고 아래 코드를 복사하여 붙여 넣고 RUN 하세요. 아주 멋진 영상을 보실 수 있습니다. 다음은 전체 Processing 코드입니다.
/*
Arduino and ADXL345 Accelerometer - 3D Visualization Example
by Dejan, https://howtomechatronics.com
*/
import processing.serial.*;
import java.awt.event.KeyEvent;
import java.io.IOException;
Serial myPort;
String data="";
float roll, pitch;
void setup() {
size (960, 640, P3D);
myPort = new Serial(this, "COM8", 9600); // starts the serial communication
myPort.bufferUntil('\n');
}
void draw() {
translate(width/2, height/2, 0);
background(33);
textSize(22);
text("Roll: " + int(roll) + " Pitch: " + int(pitch), -100, 265);
// Rotate the object
rotateX(radians(roll));
rotateZ(radians(-pitch));
// 3D 0bject
textSize(30);
fill(0, 76, 153);
box (386, 40, 200); // Draw box
textSize(25);
fill(255, 255, 255);
text("www.HowToMechatronics.com", -183, 10, 101);
//delay(10);
//println("ypr:\t" + angleX + "\t" + angleY); // Print the values to check whether we are getting proper values
}
// Read data from the Serial Port
void serialEvent (Serial myPort) {
// reads the data from the Serial Port up to the character '.' and puts it into the String variable "data".
data = myPort.readStringUntil('\n');
// if you got any bytes other than the linefeed:
if (data != null) {
data = trim(data);
// split the string at "/"
String items[] = split(data, '/');
if (items.length > 1) {
//--- Roll,Pitch in degrees
roll = float(items[0]);
pitch = float(items[1]);
}
}
}
설명 : 따라서 여기에 13번 라인의 직렬 라이브러리를 포함하고, 업로드된 Arduino 스케치의 전송 속도와 일치해야 하는 직렬 포트 및 전송 속도를 정의해야 합니다. 아래 COM 포트를 사용자 PC 환경에 맞도록 수정하세요.
myPort = new Serial(this, "COM8", 9600); // starts the serial communication
그런 다음 들어오는 데이터를 읽고 적절한 롤 및 피치 변수에 넣습니다. 아두이노 스케치를 실행하고 Nano 33 BLE Sense 보드는 업로딩을 완료하면 com 포트가 자동으로 끊어지니 그 포트 번호를 보고 processing 코드의 13라인에서 com 포트를 일치시키고 프로세싱을 런 하시면 됩니다.
아두이노 코드를 실행하면 3D 개체가 나타나고 가속도계 센서의 방향을 추적합니다. 여기서 물체가 실제로 약간 흔들리고 있다는 것을 알 수 있습니다. 가속도계가 중력뿐만 아니라 손의 움직임에 의해 생성된 작은 힘도 포착하기 때문입니다. 더 부드러운 결과를 얻기 위해 간단한 저역 통과 필터를 사용할 수 있습니다. 여기에서는 이전 상태의 94 %를 차지하고 현재 상태 또는 각도의 6 %를 추가하는 Arduino 코드에 이러한 필터를 구현했습니다.
// Low-pass filter
rollF = 0.94 * rollF + 0.06 * roll;
pitchF = 0.94 * pitchF + 0.06 * pitch;
이 필터를 사용하면 이제 오브젝트가 훨씬 더 부드럽게 움직인다는 것을 알 수 있지만 부작용도 있고 응답 속도가 느립니다. 또한 Yaw 또는 Z 축을 중심으로 회전이 누락되었음을 알 수 있습니다. 3 축 가속도계 데이터만 사용하여 Yaw를 계산할 수 없습니다.
이를 수행하고 방향 추적 센서의 전체 성능을 개선하려면 실제로 추가 센서, 자이로 스코프를 포함하고 해당 데이터를 가속도계와 융합해야 합니다.
따라서 일부 자이로 스코프 센서와 함께 ADXL345 가속도계를 사용하거나 단일 칩에 3 축 가속도계와 3 축 자이로 스코프가 모두 통합된 MPU6050 IMU를 사용할 수 있습니다. 다음 비디오에서 이 센서에 대한 자세한 자습서를 찾을 수 있습니다.
참고 자료
참고 문서 원문 How To Track Orientation with Arduino and ADXL345 Accelerometer
Tilt Sensing Using a Three-Axis Accelerometer
'개발자 > Arduino' 카테고리의 다른 글
SmartEverything LSM6DS3 라이브러리 사용법 - 3축 가속도계와 3축 각속도 센서 (0) | 2020.11.23 |
---|---|
Arduino Nano 33 IoT 최강 가이드 (0) | 2020.11.20 |
아두이노 라이브러리 설치하는 방법 3가지 (0) | 2020.11.18 |
Arduino Nano 33 BLE Sense 에서 Bluetooth LE 시작하기 (0) | 2020.11.18 |
미세진동 측정 - LSM6DS3 가속도계 자이로 센서를 이용 (4) | 2020.11.11 |
아두이노 퀴즈 40문제 파일 무료 제공 (0) | 2020.11.11 |
Arduino LCD KeyPad Shield SKU DFR0009 캐릭터 LCD (0) | 2020.11.08 |
HTTP를 통해 Arduino Nano 33 IoT와 Ubidots 데이터 보내기 3 Oled에 데이터 표시하기 (0) | 2020.10.30 |
더욱 좋은 정보를 제공하겠습니다.~ ^^