공부/인공지능

라벨 560mAh 배터리를 테스터로 쟀더니 약 200mAh — 문패 배터리 오독 해부

TechToast 2026. 11. 2. 10:38
반응형

문패 배터리를 밤새 충전했는데 아침에 잔량이 93%로 떠 있었습니다. 100%가 아닙니다. 충전 회로도 깨지고 보드 ADC도 고장 난 건가 싶어서 멀티미터와 USB 전력 테스터를 끌어다 붙였는데, 결론부터 말씀드리면 하드웨어는 할 일을 하고 있었고 틀린 쪽은 전부 제가 잡은 가정들이었습니다.

 

이 기기는 1편에서 e-paper로 바꾼 바로 그 문패입니다. 제 워크스테이션이 그린 비트맵을 문패가 받아서 문에 띄우고, 자기 배터리 전압은 보드 ADC로 읽는 구조죠. 1편을 쓰고 나서 잔량 표시가 자꾸 이상해서 파고들었고, 하나씩 실측으로 고쳐간 과정을 아래 순서 그대로 적어봅니다.

 

먼저 무너진 가정, "완충 = 4.2V"

처음엔 보드 ADC를 의심했습니다. 멀티미터로 배터리 전압을 직접 재서 비교해보니 보드가 약 1% 높게 읽고 있었죠. 보정 계수는 ×0.989 쪽이어야 하는데, 코드에는 "완충 = 4.18V"라는 가정으로 계수가 반대 방향인 ×1.0087로 들어가 있었습니다. 높게 읽히는 전압을 더 밀어올리고 있으니 아무리 완충을 해도 93%에서 멈춰 보였던 겁니다.

 

그런데 진짜 범인은 보정 계수보다 그 아래 가정이었습니다. 리튬 폴리머 표준 완충 전압은 4.2V지만, 이 보드의 충전 회로는 약 4.10V에서 실제로 충전을 종료합니다. 물리적으로 도달하지 않는 값을 분모로 써놓고 100%를 기다리고 있었던 셈이죠. 여기서 전압 보정과 100% 기준점을 분리해서 잡았습니다. 보정은 ADC 오차인 ×0.989로 잡고, 100%는 이 보드 충전 회로의 실제 완충 전압인 약 4.10V로 정의했어요. 한 가지가 아니라 두 가지가 겹쳐 있던 문제였고, 기준점을 분리한 게 오독을 끝낸 결정적인 변화였습니다.

라벨 560mAh를 테스터로 쟀습니다

USB 전력 테스터로 충전 전력을 관찰하니 1W, 즉 5V에서 약 200mA 수준이었습니다. 배터리 라벨에는 560mAh라고 적혀 있었는데, 충전 전류 기준으로 실제 용량은 약 200mAh로 추정됩니다. 500ml 대형 병을 기대하고 열었더니 종이컵 분량만 들어 있던 격이죠. 라벨값 기준으로 15~20mA라 계산해둔 평균 소모 전류도 6~7mA로 다시 잡아야 했습니다. 보드도 펌웨어도 아닌, 셀 용량 부풀림, 그러니까 라벨 과장이 범인이었습니다.

 

전압으로 잔량을 추정하는 방법 자체도 반환 사유가 있었습니다. 리튬 셀은 중간 전압 구간이 평평해서, 연료계기가 반쯤 남은 채로 한참 버티다가 텅 비기 직전에 뚝 떨어지는 것처럼 전압만 보고 잔량을 맞히는 건 거의 화투였습니다. "최근 전압 기울기"로 지속시간을 계산하면 6.7시간으로 예측됐는데, 실제 완충 유지와 크게 빗나가더군요. 추정식은 "현재 잔량 × 지난 완충 지속시간"으로 단순하게 바꾸었습니다.

 

여기까지도 가정은 하나 더 있었습니다. 막 충전을 끝낸 배터리에는 표면 전하 때문에 전압이 실제보다 높게 나옵니다. 따른 지 얼마 안 된 맥주 거품처럼 속보다 많이 차 보이는 거죠. 이 순간의 판독은 추정 47% vs 실측 90%까지 벌어져서, 충전 직후 읽기는 별도 보정이 필요하다는 걸 여기서 배웠습니다.

그래도 실측으로 좋아진 것들

배터리 고장만 의심하느라고 놓쳤지만, 절전 쪽은 실제로 크게 개선됐습니다. 예전엔 Arduino 단독으로 슬립에 들어갔고, 지금은 arduino+espidf 하이브리드(PM_ENABLE, tickless idle, CPU 80MHz/대기 40MHz, WiFi MAX_MODEM)로 들어갑니다. 방전 속도가 260mV/h에서 23~29mV/h로 떨어져 약 10배 좋아졌어요.

 

완충 1회 사용 시간도 새 기준으로 실측했습니다. 구버전 기준 3.2시간이던 문패가 41시간까지 버텼고, 관측 창은 10/8 09:59부터 10/10 02:56까지, 창 평균은 -12.5mV/h였습니다. 문패 자체는 서버가 렌더한 400×300 흑/적 비트맵(30KB)을 롱폴링으로 받는 구조를 그대로 유지했고, 웹은 5초마다 서버만 조회하고 문패와 통신하지 않습니다. 12시간에 서버 조회 732회 vs 문패 갱신 7번으로 세어보니 구조는 의도대로였습니다. 저를 괴롭히던 깜빡임은 문패가 아니라 그림 목록 전체를 통째로 재렌더하고 있던 웹 쪽 문제였고, 그 부분만 고쳤습니다.

철문과 안테나, 그리고 보드 2.0

문패가 문에 붙는 기기인지라 배터리만 고칠 게 없었습니다. 문 위치의 RSSI는 -75~-85dBm으로 약해서 누적 통신 실패가 104회, 자가 복구 재부팅까지 따라오고 있었죠. 자석에 이끌리듯 안테나를 철판에 바싹 붙이는 건 2.4GHz에서는 반대 행동이었습니다. 철판 1cm 안으로 들어가면 공진이 틀어지고 철이 전파를 먹어치웁니다. 파장이 약 125mm니 1/4파장인 31mm 정도로 슬리브 다이폴(전체 약 62mm)을 만들고 철판에서 2cm 이상 떼어내는 게 예의입니다. 반면 자석 베이스 막대 안테나는 철문을 오히려 접지면으로 써서 잘 됐습니다. 철판 자체를 접지면 삼는 모노폴의 원리 그대로였어요. 공유기 쪽은 TWT 설정이 꺼진 게 아님을 확인했고, DTIM 1→3이 권장됐습니다. 깨어나는 시점을 늦춰서 문패가 자는 시간을 늘리는 설정입니다.

 

보드 2.0의 칩 선택은 의외로 싱겁습니다. C5와 C6는 이 용도에서 성능 차이가 사실상 없고(둘 다 Wi-Fi 6 TWT), 차이는 보드에서 납니다. 결정적 기준은 두 개였어요. 외부 안테나 커넥터가 있는지(철문 문제 때문입니다), 배터리 단자는 뭔지(칩이 아니라 보드 제조사가 정하는 영역입니다).

 

후보 안테나 배터리 단자 가격
Waveshare ESP32-C5-WIFI6-KIT N32R8-U 외부 안테나 동봉 MX1.25 약 2만원
DFRobot C5-U 내장 안테나 PH2.0 (변환 케이블 필요) 16,800원

 

여기엔 함정이 하나 있습니다. JST-GH는 걸쇠가 있고 MX1.25는 걸쇠가 없어서 구분이 필요하고, 시판 변환 케이블 중에는 +/-가 반대인 제품이 섞여 있습니다. 꽂기 전에 멀티미터로 극성을 확인하는 게 필수예요. 반대로 꽂히면 보드가 상합니다.

공개하기 전, 그리고 아직 찜찜한 부분

프로젝트 코드를 공개 저장소로 정리하다가 낭패를 볼 뻔했습니다. 미리 찍어둔 사진 5장 중 4장에 GPS 메타데이터가 들어 있었고, 명패 사진에는 성함·학과·호실·시간표가 그대로 담겨 있었어요. 전부 흐림 처리에 EXIF를 제거한 뒤 올렸고, 공유기 관리자 화면 캡처는 비밀번호가 보여서 통째로 뺐습니다. git 작성자 이메일은 GitHub noreply로 설정해뒀어요. "공개용 사진"과 "공개 안 될 메타데이터"는 별개 문제라, 올리기 전에 EXIF부터 보는 루틴을 만들었습니다. 코드는 github.com/yangzepa/roomdisplay 공개 저장소에 있습니다.

 

정직하게 남은 한계도 적어둡니다. 잔량 추정은 여전히 전압 기반이라 오차가 큽니다. 보드마다 충전 종료 전압이 달라서(이 보드는 약 4.10V) "완충 = 4.2V" 가정을 그대로 쓰면 같은 펌웨어라도 잔량이 틀립니다. 전류를 직접 재는 인라인 카운터(셸런트)는 아직 못 붙였고요. 문 위치 RSSI -75~-85dBm도 여전해서 통신 실패와 자가 재부팅이 사라지지 않았습니다. 보드 2.0은 구매 전 단계라 실측 검증은 다음 과제예요. 다음엔 외부 안테나를 단 새 보드로 RSSI 개선을 실측하고, DTIM 3를 적용하고, 충전 종료 전압 자동 캘리브레이션을 넣어볼 계획입니다.

 

하드웨어 고장인 줄 알았던 것들이 전부 측정 가정의 문제였고, 멀티미터와 테스터가 하나씩 바로잡아줬습니다. 여러분의 e-paper 기기 잔량이 100%를 못 채우고 멈춰 있다면, 보드를 의심하기 전에 충전 종료 전압부터 직접 재보시길 권해드려요. 가정은 믿지 마시고 전압은 직접 재십시오.

반응형