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

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

by 이런 저런 2019. 12. 21.

먼저 올렸던 측정기의 구성과 프로그램을 좀 더 수정해 다시 업로드했습니다.

 

 

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

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

bjk110-2.tistory.com

바뀐점은 크게

1. 측정 시점을 선택할 수 있는 버튼 추가
2. 일정 횟수(기본 세팅은 10회) 를 측정해 평균을 낼 수 있는 기능 추가

의 2가지입니다.

먼저 소스는 단순히 측정이 가능한지 정도만을 볼 수 있는 수준이라 실제 사용시 불편함이 많을 듯 해 위 기능을 새로 추가했습니다.

회로 구성은 아래 이미지와 같습니다.

크게 달라진 점은 없고 이미지 우측 하단의 스위치가 추가된 정도가 차이입니다.

본래 아두이노에서 스위치를 달 때는 클릭 스위치에 10㏀ 풀업저항을 다는 구성을 사용하는게 일반적이지만, 전 예전 3D 프린터의 리밋스위치로 사용하던 SPDT 형식의  스위치(마우스에 사용하는 옴론 스위치와도 유사) 가 있어 이를 사용했습니다.

그리고 이를 반영해 아래와 같이 소스도 변경했습니다.

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

#define OLED_RESET 4
#define TEST_COUNT 10 // 10회 계산 후 평균값 계산
#define LATENCY_CORRECTION 0 // 레이턴시 측정값을 보정

Adafruit_SSD1306 display(OLED_RESET);

int lightSensorPin = 2; // 광센서 연결 핀 번호
int soundSensorPin = 3; // 사운드센서 연결 핀 번호
int startButton = 4; // 스위치 연결 핀 번호

int testCount;

long flash, beep, latency;
long latencyArray[TEST_COUNT];

//boolean isFlashRecorded = false;
//boolean isBeepRecorded = false;
boolean push = false;

void setup()   {                
  Serial.begin(9600);
  
  //디스플레이 초기화
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);  // initialize with the I2C addr 0x3C (for the 128x32)  
  display.display();
  delay(10);  
  display.clearDisplay();

  flash = 0;
  beep = 0;

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

void loop() {
  // 스위치를 누를 경우 레이턴시 측정을 시작
  if(digitalRead(startButton)== LOW) {
    push = true;    
    testCount = 0;
  }
    
  // 버튼이 눌렸을 경우 지정 횟수대로 테스트 시작
  while (testCount < TEST_COUNT && push) {
    
    /* 레이턴시를 계산하지 않은 상태에서 카운트 초기화 되는 것을 막기 위해 
      isFlashRecorded 가 false 인 상태에서만 광센서 입력 시간을 기록함 
      광센서가 신호를 수집한 경우 isFlashRecorded = true 로 변경*/
    if (!digitalRead(lightSensorPin) && flash == 0) {
      flash = millis();      
    }

    /* 광센서가 신호를 수집한 이후 사운드 센서의 신호 수집 시간을 기록 */
    if (digitalRead(soundSensorPin) && flash != 0) {
      beep = millis();
    }
    
    if (flash != 0 && beep != 0) {
      latency = beep - flash + LATENCY_CORRECTION;      
      latencyArray[testCount] = latency; // 평균값 측정을 위해 배열에 측정값 기록      
      long avgLatency = average(latencyArray, testCount + 1); // 레이턴시 평균값 계산

      Serial.println(avgLatency);
  
      // 레이턴시값을 화면에 표시
      display.clearDisplay();
      display.setTextSize(1);
      display.setTextColor(WHITE);
      display.setCursor(0,0);            
      display.print("(");
      display.print(testCount + 1);
      display.print("/");
      display.print(TEST_COUNT);
      display.print("st)");
      display.setTextSize(2);
      display.print(" ");
      display.print(latency);
      display.println("ms");
      display.setTextSize(1);
      display.print("(average)");
      display.setTextSize(2);
      display.print(" ");
      display.print(avgLatency);
      display.println("ms");
      display.display();
  
      //화면 표시후 변수 초기화
//      isFlashRecorded = false;
      beep = 0;
      flash = 0;
      testCount++;
//      Serial.println(testCount);
    }
  }
}

long average (long * array, int len){
  long sum = 0;
  for (int i = 0; i < len; i++) {
    sum += array[i];
  }
  return sum / len;
}

마지막으로 이 글의 소스를 적용한 측정기를 통해 실제 테스트 한 영상을 올렸습니다.

 

댓글