본문 바로가기
튜토리얼/아두이노

아두이노에서 WitMotion WT61C 센서 사용하기

by 아트하는 개발자 2024. 6. 19.

가속도 / 자이로 센서인 wit-motion의 WT61C 센서를 아두이노에서 사용해보겠습니다. 이 센서는 고정밀 센서로 mpu9250 같은 센서와 다르게 자체적으로 필터링이 되어 있습니다.

 

아두이노에서 WitMotion WT61C 센서 사용하기  

 

아두이노에서 WitMotion WT61C 센서 사용하기

 

1. 센서소개

2. 센서 확인하기

3. 아두이노 연결


추천글

위의 목차를 클릭하면 해당 글로 자동 이동 합니다.

 

센서소개

BMI160센서의 특징은 다음과 같습니다.

 

* 시리얼 통신으로 데이터를 출력하는 가속도, 자이로 센서 모듈입니다.

* 칼만필터 알고리즘이 적용되어있으며 모듈에서 자체 계산된 XYZ(roll, pitch, yaw) 기울기 값을 통신을 통해 얻을 수 있습니다.

* 가속도 3축, 자이로 3축
* 구동전압 : 3.3V ~ 5V
* 인터페이스 : UART < Baud rate : 9600, 115200(default) >

https://www.devicemart.co.kr/goods/view?no=10886279

 

컴퓨터에도 연결할 수 있다고 하지만 저는 아두이노에 연결해서 사용하겠습니다.

 

센서 확인하기

먼저 관련 자료를 찾아야하는데, 제가 구매한 디바이스마트에서 제공된 자료는 전부 만료라고 볼 수 없었습니다. 그래서 직접 홈페이지로 들어가서 확인을 했습니다.

제가 구매한 센서의 제대로 된 이름은 WT61C-TTL로 이 센서의 자료를 가져오면 됩니다.

 

https://www.wit-motion.com/down.html

 

Document(Google Drive)-WitMotion Shenzhen Co.,Ltd

Download Center Home / Download Center / Document(Google Drive)

www.wit-motion.com

 

하지만 전반적으로 제대로 되어 있지 않습니다. 너무 슬프고 어렵습니다. ㅠ 그렇지만 해결책은 찾았습니다.

이 프로그램을 먼저 다운 받은 뒤에 센서의 정상동작을 확인합니다. 아래 사진 처럼 MiniIMU.exe 실행파일 입니다.

(만약 처음이시라면 CH340 & CP2102 Driver.zip)도 받으셔서 설치하시면 됩니다.

여기서 추가적인 기기를 구매하셔야 합니다. TTL2USB라는 장비입니다.

사용하는 이유는 ... 현재 센서의 상태로는 컴퓨터에 연결할 수 없기 때문입니다.

https://www.devicemart.co.kr/goods/view?no=1324910

 

아래 사진처럼 연결합니다. 

USB연결후 MiniIMU를 실행하면 다음과 같이 나타납니다.

 

여기서 만약에 잘 나타나지 않았다면 왼쪽의 센서 명을 확인합니다. 처음에는 아마 WT90~머시기로 되어 있을 겁니다. 

왼쪽에 WT61C를 검색한 후 WT61CRS232-E를 선택합니다. 그러면 프로그램이 재시작 될 겁니다.

저는 보레이트를 9600으로 변경했는데요. 기본값은 115200입니다. 그대로 사용하셔도 됩니다.

만약에 바꾸실 분은 상단 메뉴의 Config을 클릭하신 후 아래 창에서 변경하시면 됩니다.

 

저는 보레이트만 변경하고 진행했습니다.

아두이노 연결

제일 어려웠던 아두이노 연결입니다. ㅠㅠ

물론 제공된 코드가 있습니다만 아두이노 메가만 되었고 저는 레오나르도를 사용하려 했기 때문에 호환도 안됐고... 또.. 관련 자료도 없었습니다. 

 

miniIMU 프로그램에서 raw 데이터가 있길래 이걸 토대로 데이터를 받아서 변환하는 방향으로 설정 했습니다.

 

아두이노의 TX와 RX에 연결합니다. 핀 바꾸는건 시도하진 않았습니다.

 

#include <Wire.h>

#define PACKET_LENGTH 11
#define HEADER 0x55

// 데이터 버퍼와 인덱스
uint8_t dataBuffer[PACKET_LENGTH];
int dataIndex = 0;

void setup() {
  Serial.begin(9600); // 시리얼 모니터 통신 시작, 보드레이트는 9600으로 설정
  Serial1.begin(9600); // Serial1 포트 통신 시작, 보드레이트는 9600으로 설정
}

void loop() {
  if (Serial1.available() > 0) { // Serial1 버퍼에 데이터가 있는지 확인
    while (Serial1.available() > 0) {
      uint8_t receivedByte = Serial1.read(); // Serial1에서 한 바이트 읽기
      processData(receivedByte); // 수신된 바이트 처리
    }
  }
  
  // 필요한 경우 데이터를 TTL 센서로 송신
  if (Serial.available() > 0) {
    while (Serial.available() > 0) {
      uint8_t dataToSend = Serial.read(); // 시리얼 모니터에서 한 바이트 읽기
      Serial1.write(dataToSend); // 읽은 데이터를 Serial1로 송신
    }
  }
}

void processData(uint8_t receivedByte) {
  if (dataIndex == 0 && receivedByte != HEADER) {
    return; // 패킷의 시작이 아닌 경우 무시
  }

  dataBuffer[dataIndex++] = receivedByte;

  if (dataIndex == PACKET_LENGTH) {
    if (dataBuffer[0] == HEADER) {
      parsePacket(dataBuffer);
    }
    dataIndex = 0; // 패킷 처리가 끝나면 인덱스 초기화
  }
}

void parsePacket(uint8_t *buffer) {
  uint8_t checksum = 0;
  for (int i = 0; i < PACKET_LENGTH - 1; i++) {
    checksum += buffer[i];
  }
  if (checksum != buffer[PACKET_LENGTH - 1]) {
    Serial.println("Checksum error");
    return;
  }

  // 가속도 데이터 추출 (예: 0x55 0x51 패킷)
  if (buffer[1] == 0x51) {
    int16_t accX = (buffer[3] << 8) | buffer[2];
    int16_t accY = (buffer[5] << 8) | buffer[4];
    int16_t accZ = (buffer[7] << 8) | buffer[6];

    float fAccX = accX / 32768.0 * 16.0;
    float fAccY = accY / 32768.0 * 16.0;
    float fAccZ = accZ / 32768.0 * 16.0;

    Serial.print("Acceleration X: ");
    Serial.print(fAccX);
    Serial.print(" Y: ");
    Serial.print(fAccY);
    Serial.print(" Z: ");
    Serial.println(fAccZ);
  }

  //각속도 데이터 추출 (예: 0x55 0x52 패킷)
  if (buffer[1] == 0x52) {
    int16_t gyroX = (buffer[3] << 8) | buffer[2];
    int16_t gyroY = (buffer[5] << 8) | buffer[4];
    int16_t gyroZ = (buffer[7] << 8) | buffer[6];

    float fGyroX = gyroX / 32768.0 * 2000.0;
    float fGyroY = gyroY / 32768.0 * 2000.0;
    float fGyroZ = gyroZ / 32768.0 * 2000.0;

    Serial.print("Gyro X: ");
    Serial.print(fGyroX);
    Serial.print(" Y: ");
    Serial.print(fGyroY);
    Serial.print(" Z: ");
    Serial.println(fGyroZ);
  }

  // 각도 데이터 추출 (예: 0x55 0x53 패킷)
  if (buffer[1] == 0x53) {
    int16_t angleX = (buffer[3] << 8) | buffer[2];
    int16_t angleY = (buffer[5] << 8) | buffer[4];
    int16_t angleZ = (buffer[7] << 8) | buffer[6];

    float fAngleX = angleX / 32768.0 * 180.0;
    float fAngleY = angleY / 32768.0 * 180.0;
    float fAngleZ = angleZ / 32768.0 * 180.0;

    Serial.print("Angle X: ");
    Serial.print(fAngleX);
    Serial.print(" Y: ");
    Serial.print(fAngleY);
    Serial.print(" Z: ");
    Serial.println(fAngleZ);
  }
  delay(500);
}

 

 

어지저찌 해서 이렇게 센서를 사용해봤습니다. 확실히 아무것도 없던 mpu9250이나 6050과는 달리 필터가 적용되어서 좋았습니다. 근데 자료가 더 많아서 사용하기 편했다면 좋았을 텐데 ㅠㅠ 

다들 관련 작품들도 많이 만드셔서 공유해주세요!

감사합니다.

 

추천글

아두이노로 서보모터 제어하기

 

아두이노로 서보모터 제어하기

이번에는 아두이노를 사용해서 서보모터를 제어하는 방법에 대해 소개하겠습니다. 서보모터는 회전각을 정밀하게 제어할 수 있어 로봇 팔, 그리퍼, 드론 등 다양한 분야에서 활용됩니다. 아두

creativecodingart.tistory.com

아두이노 조도 센서 활용하기: 기초

 

아두이노 조도 센서 활용하기: 기초

아두이노는 다양한 센서를 사용하여 외부 환경을 측정하고, 이를 통해 여러 가지 인터랙티브 프로젝트를 구현할 수 있는 강력한 도구입니다. 오늘은 그 중에서도 조도 센서를 사용하여 주변 빛

creativecodingart.tistory.com

 

반응형