본문 바로가기
사용기, 자작기/자작, 튜닝

아두이노로 블루투스 이어폰 레이턴시 측정하기(1)

by 이런 저런 2019. 12. 20.

최근 배터리 및 블루투스 기술이 발전하며 이전처럼 거치장스러운 선 없이 사용할 수 있는 TWS(True Wireless Stereo)이어폰들이 저렴한 가격에 잇달아 출시되고 있습니다.

그로 인해 편의성이 많이 증가된 것은 사실이지만 TWS 이어폰들 상당수가 가지고 있는 단점이 바로 영상과 음성 싱크, 즉 레이턴시(latency)가 꽤 크다는 것이죠

일반적인 블루투스 사운드 기기들도 레이턴시가 있긴 하지만 TWS의 경우 소스기기 <-> 좌우 이어폰 유닛이 각각 연결되는 특성 때문에 더욱 그 레이턴시가 커진다고 하는데, 안드로이드에서 유튜브 앱등 일부의 경우 어느 정도 보정을 해 준다고는 하지만 게임이나 다른 영상 재생시에 레이턴시가 존재하는 경우도 있고, 특히 리듬게임의 경우 게임 플레이가 어려울 정도로 지연이 발생하는 경우도 종종 생긴다고 합니다.

최근에 전문 리뷰 사이트 등에서 이어폰 등 기기 리뷰시 레이턴시를 측정해 주긴 하지만 마이너한 기종이나, 국내 정식 수입되지 않은 제품들의 경우 정보를 찾기가 쉽지 않기에 레이턴시를 직접 측정할 수 있는 방법을 찾아보기로 했습니다.

자료 수집

일단 레이턴시, 즉 지연은 영상과 음성에서 동일한 시간에 발생한 신호가 전달되는데 시간 차이가 발생하는 것인 만큼 영상 신호와 음성 신호를 측정하면 된다는 것 까지는 생각이 닿았지만 각각의 신호를 측정하는 방법이 쉽게 떠오르지 않더군요.

그래서 오실로스코프를 이용해 각각의 신호가 발생하는 시간을 측정해볼까도 했지만 오실로스코프의 기본 프로브는 전압 변화량만을 측정할 수 있다보니 각각의 신호를 전압 변화로 변환하는 장비를 별도로 써야 한다는게......

그래서 포토다이오드와 마이크를 이용해 신호를 직접 수집할까 고민하고 있던 도중 아두이노를 쓰면 되겠다는 생각이 문득 떠올랐습니다.

아두이노 같은 경우 취미나 교육용으로 다양한 센서들이 만들어져 있으며 가격 자체도 저렴한 만큼 이를 이용하면 쉽게 데이터 수집이 가능할 테니 말이죠.

마침 예전에 아두이노를 잠깐 만지작거린 적이 있어 기본형인 아두이노 우노와 아두이노 나노, 그리고 3D프린터용으로 많이 사용했던 Mega 2560등 다양한 아두이노 보드들은 이미 가지고 있어 필요한 센서를 찾았는데, 역시나 필요한 센서들을 이미 팔고 있었습니다.

비교해 보니 국내에서도 가격이 얼마 하지 않아 사운드 수집용으로 이 센서를,

 

DM439 아두이노 소리 센서 모듈 듀얼타입 : 도매키트

[도매키트] 코딩 교육 부품, 아두이노, 마이크로비트, 라즈베리파이 등을 업체에 도매가로 공급합니다.

smartstore.naver.com

그리고 영상 센서용으론 아래 센서를 각각 구매했습니다.

 

DM2007 광 다이오드센서 모듈/포토다이오드 모듈 : 도매키트

[도매키트] 코딩 교육 부품, 아두이노, 마이크로비트, 라즈베리파이 등을 업체에 도매가로 공급합니다.

smartstore.naver.com

그리고 각각의 센서에 신호를 전달하기 위해 같은 시간에 화면과 음성을 동시에 송출하는 앱을 짤까 하다 최근에는 스마트폰 메트로놈 앱이 많으니 이 앱중 박자에 맞춰 소리와 화면 깜박임을 동시에 제공하는 앱을 찾아 사용하기로 했습니다.

제가 사용한 것은 아래 앱입니다.

 

 

Metronome - Beats by Appsnemo - Google Play 앱

Metronome by Appsnemo is a professional metronome tool for all musicians, from beginners to professionals. It is the necessary app for daily practice and stage performance. Metronome by Appsnemo is fully packed with pro features and all of them are provide

play.google.com

센서 배선

그 다음 각각 센서들과 디스플레이를 아두이노에 연결합니다.

위 센서들은 아날로그 신호와 디지털 신호를 각각 지원하는데, 제 경우는 센서 입력 신호를 스위치로 사용할 것이기 때문에 디지털 신호를 사용하도록 아두이노에 연결했습니다.

배선은 아래와 같이 연결했습니다.

사진의 디스플레이는 가지고 있던 OLED 디스플레이로 사실 시리얼 모니터를 사용하면 굳이 디스플레이 없이도 레이턴시 측정이 가능하지만 이왕이면 직접 출력하는게 더 편할 듯 싶어 장착했습니다.

해당 디스플레이는 I2C 인터페이스로 아두이노에 연결되는 방식입니다.

 

프로그래밍

이제 프로그래밍입니다.

일단 동작 테스트 정도로 해보려고 평균값 계산이나 측정을 시작하는 스위치 등을 제외하고 전원이 들어오면 바로 동작하는 식으로 코드를 짰습니다.

동작방법은 간단해서 전원이 들어오면 아두이노가 신호를 기다리다 디스플레이 깜박임을 먼저 감지한 다음 사운드 입력 신호를 감지한 뒤 그 시간차를 반환하는 형식입니다.

소스 코드는 아래와 같습니다.

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);

int lightSensorPin = 2; // 광센서 연결 핀 번호
int soundSensorPin = 3; // 사운드센서 연결 핀 번호

unsigned long strobe, beep, latency;

boolean isStart = false;

void setup()   {                
  Serial.begin(9600);
  
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);  // OLED 동작 확인용
  display.display();
  delay(10);  
  display.clearDisplay();

  pinMode(lightSensorPin, INPUT);  
  pinMode(soundSensorPin, INPUT);  
}

void loop() {
  if (!digitalRead(lightSensorPin) && isStart == false) {
    strobe = millis();
    Serial.print("Start Time : ");
    Serial.println(strobe);
    Serial.print("LED Sensor Value : ");
    Serial.println(digitalRead(lightSensorPin));
    isStart = true;
  }
    
  if (digitalRead(soundSensorPin) && strobe != 0) {
    beep = millis();
    Serial.print("End Time : ");
    Serial.println(beep);
    Serial.print("Sound Sensor Value : ");
    Serial.println(digitalRead(soundSensorPin));                  
  }

  if (isStart == true && beep != 0) {
    latency = (beep - strobe);
    Serial.print("latency : ");
    Serial.println(latency);    

    // 레이턴시값을 화면에 표시
    display.clearDisplay();
    display.setTextSize(2);
    display.setTextColor(WHITE);
    display.setCursor(0,0);
    display.print(latency);
    display.println("ms");
    display.display();

    //화면 표시후 변수 초기화
    isStart = false;
    beep = 0;
    strobe = 0;
  }


}
데코레이션?

센서를 그대로 사용해도 되지만 외부 잡음이 유입될 우려가 있어 조금이나마 이를 억제하고자 3D 프린터를 사용해 각 모듈의 센서부를 감싸는 커버를 만들어 붙였습니다.

 

먼저 사운드 센서부는 아래와 같이 마무리했습니다.

원래는 귓구멍 모양을 본따 만들어볼까 했지만 그건 무리였고, 구경을 적당히 맞춰 이어폰의 팁이 들어갈 정도로만 적당히 모양을 만들었습니다.

포토다이오드 센서도 마찬가지로 디자인했습니다.

바닥면은 스마트폰 화면에 대서 고정할 수 있도록 편평하게...

완성된 측정기의 모습은 아래와 같습니다.

브레드 보드에 아두이노를 올리고 디스플레이와 센서를을 각각 위 올린 배선도대로 연결한 뒤 소스를 올렸습니다.

레이턴시(Latency) 측정

측정은 아래 사진처럼 영상측정 센서는 스마트폰 화면에 밀착시킨 채로,

그리고 음성 센서의 구멍에 이어폰을 넣어 신호를 측정하는 방식입니다.

테스트로는 삼성 갤럭시 S10의 기본 번들 이어폰과 QCY의 QCY-T1을 사용했습니다.

먼저 유선 이어폰을 사용했을 때입니다.

유선 이어폰 사용시 25ms 정도의 수치가 기록되는군요

다음은 블루투스 TWS인 QCY-T1을 측정했습니다.

QCY-T1의 경우 307ms 로 다른 리뷰에서 본 것 처럼 300ms 수준의 레이턴시를 보여주는군요

결론

결론을 내기에 앞서, 이 레이턴시 테스터로 측정한 값의 경우 절대적인 측정치로 신뢰할 수는 없음을 먼저 밝힙니다.

그 이유로는

  1. 사용한 메트로놈 앱이 정확하게 동일한 시간에 화면 깜박임과 비프음을 발생하도록 하는지
  2. 센서가 정확히 신호가 시작한 시간을 검출할 수 있는지
  3. 외부 잡음의 유입은 없는지

정도를 들 수 있겠죠.

다만 "상대적" 인 신호 비교 정도로는 유용할 듯 하니 다른 소스기기들을 동일한 환경에서 비교하거나, 유선 이어폰과의 레이턴시 차이를 측정하는 정도로는 쓸 수 있을 듯 합니다.

일단 대충 쓸 정도로는 만들어진 것 같으니 보유하고 있는 QCY 제품 중 QCY T1, T1X와 T3, T5를 나중에 이 기기들을 각각 측정해 비교해 보도록 하겠습니다.

댓글