2023/12/10 ~ 12/19 인도네시아 발리 여행

코로나 이후 간만에 여행을 다녀왔다.
빈땅은 맛있었다.

Sensorless BLDC ESC to Single Phase AC Inverter 개조

  예전에 기타 이펙터 전원을 배터리로 사용하기 위해 차량용 인버터를 개조하여 잘 사용해 오고 있었다. 그런데 이게 부피도 크고 무겁고, 여러 소자들을 사용한 방식이다 보니 자체 전력 소모도 적지 않았다. 그래서 이번에는 RC(Radio Control)용으로 판매되는 소형 ESC(Electronic Speed Controller)를 개조하여 사용해 보기로 했다.

[그림 1] 개조에 사용된 ESC 정면

[그림 2] 개조에 사용된 ESC 후면

  생긴건 [그림 1]과 [그림 2]처럼 작은 사이즈에 전압 입력범위도 넓고 출력도 굉장하다. 보통 ESC는 브러쉬 DC 모터용과 브러쉬리스 DC 모터용이 있는데 내가 가지고 있는건 브러시리스 DC모터용이라 3상 출력을 가지고 있다. 3상 인버터 스위칭을 위한 6개 FET와 이 FET들의 구동을 위한 드라이버 칩, 그리고 제어를 위한 MCU로 구성되어 있는데 FET에는 방열판이 붙어 있어 구체적인 모델명 파악은 하지 못했다. 스펙상 45A라고 하는데 수A만 되어도 충분하니 차고 넘친다.
  FET 구동용 드라이버 칩은 SA6288이라고 마킹되어 있는데 FD6288과 동일해 보인다. 제어용 MCU는 8051코어 기반의 EFM8BB21F16이 사용되었다. 펌웨어 개조를 하려고 관련 자료들을 찾아 봤는데 죄다 어셈블리로 짜여져있고 다양한 모델들과 많은 기능을 지원하다 보니 소스 파일 덩치도 만만치 않아 분석하기 쉽지 않았다.

[그림 3] 개조 완료

  익숙하지도 않고 크기도 적지 않은 어셈블리코드 분석하는거 보다 새로 짜는게 빠를듯 하여 대충 핀맵 찾아서 C언어로 간단하게 프로그래밍 하여 [그림 3]처럼 완성 하였다. 적당한 주파수 (수십~수백Hz)로 단상 AC만 만들면 되니 소스도 그리 복잡하지 않다. [그림 4]
  ABC 3상중에 A상과 B상만 사용하여 단상 AC를 만들도록 코드를 구성하였으므로, [그림 2]와 같이 A상과 B상을 납땜하여 출력으로 사용 하면 된다. ESC에 사용된 EFM8BB21F16은 20핀짜리 QFN 패키지이고 파악한 핀맵은 아래와 같다 (??로 표기된건 파악하지 못한 핀이다).
  * P0.0(pin02): ??
  * P0.1(pin01): ??
  * P0.2(pin20): ??
  * P0.3(pin19): ??
  * P0.4(pin18): PCM 입력
  * P0.5(pin17): 파란색 LED (0일때 켜짐)
  * P0.6(pin16): 초록색 LED (0일때 켜짐)
  * P0.7(pin15): 빨간색 LED (0일때 켜짐)
  * P1.0(pin14): FD6288Q-HIN1
  * P1.1(pin13): FD6288Q-HIN2
  * P1.2(pin11): FD6288Q-HIN3
  * P1.3(pin10): FD6288Q-LIN1
  * P1.4(pin09): FD6288Q-LIN2
  * P1.5(pin08): FD6288Q-LIN3
  * P1.6(pin07): ??
  * P2.0(pin06): C2D
  * RSTb(pin05): C2C

[그림 4] 단상 인버터 소스

[그림 5] 동작 확인

[그림 6] 크기 비교

  [그림 6] 처럼 기존 차량용인버터 개조판 보다 크기와 무게가 획기적으로 줄었다. 소비전류도 기존 대비 500mA에서 350mA로, 인버터 자체에서 소비하는 소모전류도 상당히 감소하여 배터리 사용 시간도 증가 되었다.

간만에 버스킹...


참 오래간만에 거리공연을 했다.
이번엔 종목을 바꿔서...
날씨는 그날만 많이 추웠다.

PPM to USB Adapter 자작

  만들기는 꽤나 오래전에 만들었었는데 이제서야 올린다.
레이싱 드론이 재밌어보여 시뮬레이터로 연습좀 해볼까 해서 만들었다.
일반 게임용 조이스틱을 써도 되는데, 실제 레이싱 드론에 주로 사용되는 조종기와는 조종감이 상당히 다르기에, 레이싱 드론용 조종기에 USB 어댑터를 부착하여 PC에서 일반 조이스틱으로 인식하도록 꾸며 봤다.
  우선 레이싱 드론 조종용 조종기는 위 그림처럼 좀 투박하게 생겼는데, 갖고 있던 오래된 기종이다. 아래 그림처럼 조종기 뒷면을 보면 RF 모듈을 부착할 수 있는 핀 헤더들이 나와있는데 조종기의 조종스틱과 각종 스위치들의 상태 정보를 PPM (Pulse Position Modulation)이라고 부르는 디지털 신호로 만들어 보내준다.
  이 PPM 신호를 받아 해석한 다음 USB 통신으로 PC에 전송해주면 된다. PC로 전송해줄 때 기왕이면 표준 HID 조이스틱 프로토콜로 보내주면 따로 디바이스드라이버를 만들필요가 없어 표준 게임 패드 USB Client로 펌웨어 만들어주면 끝난다. 참 쉽죠?
  아래 PCB 뒷면 검은 상자는 빈 공간을 채우기 위한 용도로 내부에는 아무것도 없다.
  PC와 USB로 연결해주면 별다른 설정 필요 없이 바로 게임패드로 인식되므로 시뮬레이터에서 적당하게 조종기 캘리브레이션 해주고 시작 하면 된다.
요렇게 만들어서 1년정도 시뮬레이터로 레이싱 드론 조종 연습을 해봤는데 이제야 감이 좀 잡힌다.
실제 드론으로 날려봐야 하는데, 이거 속도도 엄청 빠르고 무서워서리....

전기기타 디지털 꾹꾹이 자작 (D.I.Y. Electric Guitar Digital Stompbox)

  쓰고 있지 않던 DSP (Digital Signal Processor) 평가 보드를 활용하여 전기기타용 꾹꾹이를 자작해 봤다. 기타 전문가도 아니고 입문용 싼 기타로 잠깐씩 취미삼아 연주하는 정도인지라 디스토션하고 딜레이 한 개 정도면 충분하다. 그래서 만들어 봤다. 디스토션과 딜레이 두 가지 이펙터만 구현하여 DSP보드에 집어 넣었다. 우선, 적용한 하드웨어는 DSP 평가보드로, Spectrum Digital TMS320C6416T DSK Starter Kit[1]인데 [Fig. 1]처럼 생겼다. 이게 나온지 10년 가까이 되고 고정 소수점 연산 이긴 하지만 1GHz 동작속도에 실수 연산용 하드웨어가 내장되어 있어 성능은 차고 넘친다. 오디오 신호처리를 위한 코덱칩과 AFE (Analog Front End) 회로가 잘 구성되어 있다. 여기에 LCD 디스플레이와 풋 스위치 (Foot Switch)를 추가로 장착 하였다.
  I got a cheap electric guitar for hobby and as you already know, effector or stompbox is essential for the electric guitar to play Hard Rock or Heavy Metals. Since I'm not a guitar expert, just distortion and delay are enough for me and I made one (distortion and delay integrated) by myself. I hope to share my D.I.Y. digital stompbox result in this text. For digital signal processing, I used old but still good DSP evaluation board - Spectrum Digital TMS320C6416T DSK Starter Kit[1], [Fig. 1].
[Fig. 1] DSP Evaluation Kit

  우선 디지털 오디오 이펙터와 신호처리에 대한 지식이 필요한데 관련 자료들을 뒤져보니 거의 교과서 처럼 등장하는 'DAFX: Digital Audio Effects'[2]라는 책이 있어 오버드라이브와 디스토션 관련 내용만 일단 찾아 봤다. 디스토션 전달 함수가 비교적 간단하여 이것만 적용하면 될 줄 알았는데, 교과서는 그냥 교과서 일뿐 실제 구현하면서 겪어 보니 무엇인가 더 많은 것들이 필요하였다. 고난의 시작이였다. 책에 소개된 오버드라이브와 디스토션 전달 함수를 구현하여 DSP보드에 집어 넣고 소리를 들어보았는데 그냥 뭉툭하고 고장난 앰프와 같은 소리만 날뿐, 내 싱글픽업 기타로는 하드록이나 헤비메탈과 같은 멋진 소리를 만들어 낼 수가 없었다.
  Before start, I've gathered useful methods, theories, implementations and examples of the digital audio signal processing for audio FX and I've found a book titled 'DAFX: Digital Audio Effects'[2] which is frequently commented at the replies or answers from the web. I just read only a chapter about overdrive and distortion wave-shaping and I expected it should be easy to implement because of very simple tranfer function of the overdrive and distortion introduced in the book. BUT, It's my big misjudgment. I've been struggling to make suitable distorted sound through lots of trial and errors and I've noticed that there are more and more than the simple distortion tranfer function.

  인터넷에서 찾을 수 있는 온갖 종류의 오버드라이브, 디스토션, 퍼즈 전달 함수들을 모조리 구하고 구현하여 소리를 들어 보았으나, 이득 (Gain)값을 올리면 그냥 뭉개지는 소리만 날 뿐이었다. 그렇게 시간만 흘려보내다 나와 같은 고민을 하던 사람의 꽤 오래전 글을 발견하였다[3]. 해당 글의 댓글중 Paul Chana의 짧지만 눈에 띄는 답변이 있었다. 'Upsampling' 2배 오버 샘플링이면 만족스럽다는 의견이 있어, 간단한 선형 보간 기법의 x2 오버샘플링 적용 후 디스토션 전달 함수를 거친 다음, 다시 원래 샘플링 속도로 돌려보니 완벽하지는 않으나 그래도 뭉툭한 소리가 상당히 개선 되었다. 비디오 게임 할 때만 눈에 보이던 안티 얼라이어싱 (Anti-Aliasing)을 소리로 직접 경험한 계기가 되었다.
  To make right sound, I've tried almost every transfer functions and wave-shaping methods from the web but, I could not escape from chubby and fat sound with high distortion gain, A.K.A. ALIASED sound. I didn't noticed that chubby/fat sound is the aliased one until Paul Chana's short reply[3]. 'UPSAMPLING'. Yes, to solve the aliasing problem, anti-aliasing method is needed. Through that comment, I've implemented x2 oversampling with simple linear interpolation and I found that the sound quality was improved very well. But it could not perfectly close my sound needs issue. No luck with digital filters and my project was stucked for a while.

  그런데, 아직도 여전이 뭔가 부족하다. 중/고음 영역대에서 쏴대는 소리가 많이 아쉬웠다. 또 다시 한 동한 진척이 없었다. 디지털 필터를 이리저리 넣어 봐도 딱히 마음에 들 정도의 개선은 이루어 지지 않았다. 그러다 찾게된 인터넷 동영상[4]에서 힌트를 얻었다. 동영상 내용중 'High Crossover Distortion'이라고 표현한 부분인데 내게 부족했던 그 소리를 만들어 주고 있었다. 구현을 위해 'High Crossover Distortion'과 관련된 이론을 찾아 봤으나, 정형화 되거나 일반화된 이론은 찾을 수가 없었다. 그래서 sin() 함수를 적용하여 직접 구현 했다. 동영상에서 소개된것 처럼 일정 이하의 낮은 신호에 대해 높은 이득을 주고, 그 이상의 신호에 대해서는 디스토션 전달 함수를 적용하면 되는데 'YetAnotherElectronicsChannel'[5]과 같이 Threshold 기법으로 이득을 적용하는 것 보다는 sin() 함수를 적용하면, sin()함수 특성상 신호가 0에 가까워 지면 이득값도 0으로 수렴하게 되므로, 싱글픽업 특유의 험 노이즈 (Hum Noise)와 Threshold 근처에서 발생하는 특유의 끊기는 소리를 최소화 할 수 있다.
  At last, I found a good video[4]. 'High Crossover Distortion' is the keyword of that contents. I could not found some general theory about the 'High Crossover Distortion' but, some guy[5] was presented implementation of the 'High Crossover Distortion' with simple threholding method. I implemented this 'High Crossover Distortion' with sin() function for distortion gain instead. If audio signal is going to zero, sin() function based gaining is also converged to the zero. This charicteristic makes low hum noise and stuttering sound at the near-threshold, in spite of high gain with single pickup guitar. [Fig. 2] shows my distortion implementation in C-code. Small audio signal is amplitude by sin() function and higher signal is transfered by distortion transfer function [Eq. 2] introduced in lecture [6]. Standard sin() function that is supported by C-runtime math library is a kind of costly one and it's not suitable for realtime digital signal processing. So I used fast apporoximated and simple sin() function which was introduced by 'javidx9'[7]. [Fig. 3] shows the C-codded fast apporoximated sin() function.

  그렇게 정리되고 구현된 나의 디스토션 코드는 [Fig. 2]과 같다. sin() 함수는 시간소모가 많이 발생되는 함수 이므로, 기본 개발 도구에서 지원하는 수학 라이브러리는 실시간 오디오 DSP에는 거의 쓸 수가 없고, 'javidx9'[7]이 소개한 고속 근사 sin() 함수를 [Fig. 3]과 같이 구현하여 적용했다. 큰 신호에 대한 디스토션 전달 함수는 한 대학 강좌[6]에서 소개한 [Eq. 2]을 전달 함수로 적용 하였다. 그렇다고 해서 고가의 멀티이펙터나 고급 디스토션/퍼즈 만큼의 소리가 바로 나지는 않았다. 개선은 됐지만 여전히 뭉툭하고 답답한 소리가 남아 있었다. 섞여있는 뭉툭한 Aliased-Sound 제거를 위해 디스토션 처리 전과 후에 고주파 대역 통과 필터 (High Pass Filter)를 적용해 보니, 더욱 개선된 소리를 내어주었다. 구현된 전체 디스토션 이펙터를 블럭 다이어그램으로 표현하면 [Fig. 4]과 같다. 딜레이 효과는 메모리에 딜레이가 필요한 만큼 저장하고, 현재 입력된 오디오 신호와 메모리에 저장된 과거의 신호를 적절히 섞어 주면 구현은 간단하다. 메모리에 저장된 오디오 신호를 활용해 고속 푸리에 변환 (FFT - Fast Fourier Transform)을 적용하여 기타줄 튜너기능도 함께 넣어 주었는데, 이게 또 그리 녹록치가 않았다. FFT로 분석하고 최대치 주파수만 뽑아내면 될 줄 알았는데 4, 5, 6번줄의 경우 기본 주파수보다 하모닉 주파수의 크기가 더 커서 보통 Autocorrelation 기법과 같은 어느정도 정형화된 Pitch Detection 알고리즘을 적용해야 했다. 정형화된 고급 알고리즘 대신, 간단하게 1~150Hz구간에서 FFT 변환 최대치, 150~350Hz 구간에서 최대치 2가지를 구하게되면 1~150Hz구간은 4, 5, 6번 기타줄 튜닝이 가능하고, 150~350Hz구간은 기타줄 1, 2, 3번줄 튜닝이 가능함을 실험을 통해 확인하고 FFT와 연동하여 비교적 단순하게 만들어 넣었다. CPU여유가 좀 있는듯 하여 만드는 김에 계획에 없던 노이즈 게이트도 만들어 추가해 주었다. 주요 알고리즘 구현이 얼추 되었으니, 다음 사진들 처럼 껍데기까지 만들어 완성 시켰다. 입력 신호 샘플링은 48 kHz이다.
  Almost done, but still there are little chubby and fat sound. So I added high pass digital filter for the distortion input and output and sound was improved enough for me since the HPF limits large energe signal. The Delay effect is quit simple. Just store the audio signal into RAM and mix it with currently processed audio signal. The audio signals in RAM also can be used for other purpose such as guitar tuner with FFT (Fast Fourier Transform). You may need well known general Pitch Detection algorithm such as Autocorrelation method since peak detection is not suitable with 4th, 5th and 6th string because of larger harmonics magnitute than fundamntal frequency. I solved this problem with a simple frequency divide method without sophisticated algorithm. If you find peak magnitude in range 1~150Hz, the pitch of the 4th, 5th and 6th strings are can be easly separated and detected with simple max detection method. In range 150~350Hz, the pitch of the 1st, 2nd and 3rd strings are also can be detected. [Fig. 4] shows my stompbox's signal path/processing diagram and sampling frequency is 48 kHz.

[Fig. 2] My Distortion Code

[Fig. 3] Fast sin() Function

[Fig. 4] Signal Processing Diagram

[Fig. 5] Heatsink Attatched

[Fig. 6] Assembling

[Fig. 7] Final Result

[Fig. 8] Powered On

[Fig. 9] LCD Display

[Fig. 10] My Luxury Guitar Amplifier

  소리를 들어볼 시간. 소리 녹음은 [Fig. 10]의 내 고급 기타 앰프에 자작한 꾹꾹이를 연결하고 촬영한 카메라 마이크로 그냥 녹음했다. 카메라 세팅하고 녹화하고 테스트하고 편집하고 유튜브 올리고... 어우 힘들어. 유튜버님들 대단함.
  It's time to play. Sound is simply recorded through my camera microphone with my luxury guitar amplifier [Fig. 10].

[Fig. 11] Demo. Sound

* References
[4] FL Studio Guru, Fruity Waveshaper and Distortion: https://www.youtube.com/watch?v=1L9djVLaUSU
[5] YetAnotherElectronicsChannel, Guitar Distortion Effect: https://www.youtube.com/watch?v=azLQf4aLv9w
[6] A Guitar Distortion Pedal Using The Stanford DSP Sheild: https://web.stanford.edu/class/ee264/projects/EE264_w2015_final_project_herman.pdf
[7] javidx9, Fast and Simple Approximation of Sine Function: https://www.youtube.com/watch?v=1xlCVBIF_ig

중년 즈음에...

  잠시라도 아무것도 하지 않으면 남들에게 뒤쳐져 사라질 것만 같은 강박과 불안감으로 뭔가를 부스럭부스럭 끝없이 해야만 했던 20대를 지나고, 그 강박에 익숙해질 즈음엔 내가 30대를 지나고 있었음을 인지 했던것 같다. 거창하게 내세울 것도 없지만 그 강박과 불안감을 이겨 내고자, 주어진 환경과 힘 닿는 범위 안에서 너무도 치열하게, 그리고 내가 맞다고 생각하는 신념과 확신이라면 그거 하나만 믿고 참말로 징글징글하게 열심히 살았다. 다시 돌아가라면 죽기보다 싫을 만큼 말이다.
  콘크리트, 강철과도 같던 굳은 신념이 부서지고 깨지며, 세상에 영원한건 아마 없을 것 같다는 것을 머리가 아닌 가슴으로 이해하게 될 때 즈음에서야 내가 중년을 지나고 있음을 알게 되었다.
  돈 몇 푼에 구질구질했던 시절보다 물질적으로 풍요하지만, 아무것도 하기 싫고 뭘 해도 재미 없고 갖고 싶은 것도, 먹고 싶은 것도 없을 때가 잠시 있었던것 같다. 욕구와 호기심, 그리고 궁금증도 사라지고 모든게 귀찮고 성가시기만 할 때 말이다. 꼭 거쳐 가야만 하는 길이었던 건가?
  이제 내 일생중 반을 지났지만 여전히 부족하고, 여전히 모르겠고, 여전히 앞이 보이지 않는 안개 속에서 매 순간순간, 내가 가야 할 길목에 서서 결과를 알 수 없는, 끝없는 의사 결정을 해야만 하고 있다. 그 결정이 옳은 것인지, 유익한 것인지, 필요한 것인지 그리고 시간이 지나고 이 판단에 후회가 생기진 않을 것인지... 알 수가 없다. 그래서 재미있다는 것일까? 더이상 무료해 지지 않는 것일까?
  쉬는날 아침이면 운동을 한다. 숨이 턱밑까지 차오르도록 남은 힘을 쏟아 붓고 나면 머릿속은 잠시나마 하얗게 지워지고, 잊고 지냈던 내 심장소리가 아직 힘차게 뛰고 있음을 내 귀로 확인 할 수 있게 된다. 참으로 기쁜 순간이다.
  다행스럽게도 아직 난, 해보고 싶은게 여전히 많다. 또 그렇게 부서지겠지만, 내가 지금 옳다고 생각하는 신념은 아직 굳건하다 믿고 있다. 전에도 그랬지만 이거 하나 믿고 간다. 그리고 여전히 그럴 수 밖에 없다. 앞으로도 그럴 수 밖에 없을 것이다. 내가 지금 알고 있는 것이 거기까지 밖에 없으므로 말이다.
  어제의 나에게, 1년전, 10년전 그리고 20년 30년전의 나에게 조언을 해줄 수 있다면 그냥 '열심히 살어' 이거 밖에 없다.
  참 열심히 살아줘서 잘 했다는 칭찬과 함께...

함수 발생기 자작 (D.I.Y. Function Generator)

  자작 작업중 함수 발생기가 필요하여 만들었다. 잘 만들어진 상용품을 구매해서 사용해도 되지만 사용하지 않던 자동차용 HUD(Head Up Display)를 개조하여 만들어 보기로 했다.
[그림 1] Smart HUD 2gn. 상용품

  해당 장치는 STM32F103 마이크로 컨트롤러를 장착하고 있는데 다행히 DAC(Digital to Analog Converter) 기능을 가지고 있어 함수 발생기 기능 구현에 안성맞춤이다. 터치는 없지만 LCD 디스플레이도 가지고 있어 더할나위 없다. MCU DAC 출력은 보통 GND부터 Vref까지 출력을 가지므로 보통 0~3.3V까지 출력을 낼 수 있다. -12V 부터 +12V까지 출력을 낼 수 있도록 인버터와 OP-AMP를 추가하여 [그림 2]와 같이 추가 회로를 구성 하였다.
[그림 2] ±12V 생성을 위한 인버터 및 Charge Pump 회로 제작

  브러시 DC모터를 이용한 가스벨브 제어용 PIC 컨트롤러를 재 프로그래밍 하여 AC 인버터로 개조하였다. 이후 Charge Pump 회로와 7812 및 7912를 추가하여 OP-AMP용 ±12V 전원 전압을 생성하고, 7805를 부착하여 로직 전원용으로 활용 하였다.
[그림 3] Smart HUD 2gn. 개조

  우선 [그림 3]과 같이 기성품 회로 수정을 하고 필요한 함수 발생기 기능을 구현하여 프로그래밍 한다.
[그림 4] Smart HUD 2gn. 개조

[그림 5] 자작한 전원 보드 부착

[그림 6] 키 패드 부착

[그림 7] 기본 동작 확인

  다 만들었으니, OP-AMP의 offset과 이득 값을 조절한다. 이후 오실로스코프를 통해 원하는 동작을 잘 하고 있는지 확인 한다.
[그림 8] 50Hz ±6.11V 사인파 발생

[그림 9] 50Hz ±6.11V 사인파 발생 확인 (5V/DIV, 5ms/DIV)

[그림 10] 50Hz ±6.11V 70% Duty 구형파 발생

[그림 11] 50Hz ±6.11V 70% Duty 구형파 발생 확인 (5V/DIV, 5ms/DIV)

[그림 12] 50Hz ±6.11V 톱니파 발생

[그림 13] 50Hz ±6.11V 톱니파 발생 확인 (5V/DIV, 5ms/DIV)

[그림 14] 50Hz ±6.11V 역 톱니파 발생

[그림 15] 50Hz ±6.11V 역 톱니파 발생 확인 (5V/DIV, 5ms/DIV)

[그림 15] 50Hz ±6.11V 삼각파 발생

[그림 16] 50Hz ±6.11V 삼각파 발생 확인 (5V/DIV, 5ms/DIV)

  간단하군... 흠, 이제 요놈이 필요한 작업으로 다시 시작...