“센서 값은 시리얼로 보면 되죠?” I2C EEPROM을 써본 뒤

profile_image
작성자 기록회로지안
댓글 0건 조회 9회

책상 위에서 센서 값을 확인할 때는 시리얼 모니터만으로도 충분해 보였습니다. 문제는 아두이노를 베란다 화분 옆에 설치하고 USB 케이블을 뽑은 순간부터였습니다. 밤사이 측정된 토양 수분 값은 볼 수 없었고, 전원이 잠깐 끊기면 직전 기록까지 함께 사라졌습니다.

그래서 마이크로SD 카드 대신 먼저 시험해 본 것이 I2C EEPROM을 이용한 센서 데이터 로거였습니다. 제가 사용한 구성은 아두이노 나노 호환 보드, 24LC256 계열 EEPROM 모듈, 온습도 센서, 토양 수분 센서였습니다. 한 달 가까이 실제로 기록해 보니 간단하고 조용하게 동작한다는 장점과 함께, 쓰기 수명과 저장 용량을 반드시 계산해야 한다는 단점도 분명했습니다.

“USB만 빼면 끝”이라던 센서 프로젝트가 기록을 잃었다

시리얼 모니터는 저장 장치가 아니었습니다

처음 만든 코드는 10초마다 센서 값을 읽고 시리얼 포트로 출력하는 단순한 구조였습니다. 컴퓨터가 연결된 동안에는 그래프도 잘 그려졌고 오류도 없어 보였습니다. 하지만 독립 전원으로 전환하자 측정은 계속되는데 나중에 확인할 방법이 없는 이상한 장치가 됐습니다. 사물인터넷 프로젝트라고 부르기에는 통신도 저장도 없는 상태였던 셈입니다.

와이파이 모듈을 붙여 서버로 보내는 방법도 검토했지만, 베란다 무선 신호가 약했고 네트워크가 끊겼을 때의 처리까지 추가해야 했습니다. 반면 EEPROM은 이미 사용 중인 I2C 통신 버스에 선 두 가닥만 공유하면 됐습니다. 아두이노의 기본 개념과 활용 범위가 낯설다면 지식백과의 아두이노 설명을 먼저 읽어 보면 보드와 입출력 구조를 이해하는 데 도움이 됩니다.

제가 EEPROM을 먼저 선택한 이유

  • 배선이 간단했습니다. SDA와 SCL을 기존 센서와 함께 연결하고 전원과 접지만 추가하면 됐습니다.
  • 갑작스러운 전원 차단에도 기록이 남았습니다. 플래시 계열 비휘발성 메모리라 USB 전원이 끊겨도 이미 완료된 데이터는 유지됐습니다.
  • 소음과 기계적 요소가 없습니다. 카드 삽입 불량이나 소켓 접촉 문제를 걱정하지 않아도 됐습니다.
  • 작은 데이터에 잘 맞았습니다. 날짜 전체를 문자열로 저장하지 않고 정수 형태로 압축하니 센서 몇 개의 단기 기록에는 충분했습니다.

반대로 장기간의 고해상도 기록, 이미지 저장, 파일 단위 관리가 필요하다면 microSD가 더 편합니다. EEPROM은 엑셀에서 바로 열 수 있는 CSV 파일을 만들지 못하기 때문입니다. 저는 ‘화분에 물을 준 시점 전후로 수분 값이 어떻게 변했는가’를 확인하는 것이 목적이어서 작은 저장 공간과 단순한 회로를 우선했습니다.

사용 팁: 센서 연결을 끝낸 뒤 EEPROM을 추가하지 말고, 먼저 I2C 주소 스캐너로 현재 버스의 주소를 기록해 두세요. 새 모듈을 붙인 뒤 다시 스캔하면 주소 충돌과 배선 오류를 훨씬 빨리 구분할 수 있습니다.

24LC256을 연결해 보니 배선보다 데이터 형식이 더 중요했다

주소 확인과 풀업 저항부터 점검했습니다

제가 사용한 EEPROM 모듈은 기본 주소가 0x50으로 잡혀 있었습니다. 다만 같은 24LC256 계열이라도 모듈 기판에서 A0, A1, A2 핀을 어떻게 처리했는지에 따라 주소가 달라질 수 있습니다. 데이터시트를 보지 않고 인터넷 예제의 주소를 그대로 복사하면 장치가 응답하지 않는 상황을 만날 수 있습니다.

배선은 5V 아두이노 환경에서 VCC, GND, SDA, SCL 순으로 확인했습니다. 모듈에 풀업 저항이 이미 실장돼 있었기 때문에 외부 저항을 추가하지 않았습니다. 센서 모듈마다 풀업이 중복되면 합성 저항값이 지나치게 낮아질 수 있으므로, 전원을 끈 상태에서 SDA와 VCC 사이 저항을 측정해 보는 편이 안전합니다. 긴 케이블을 사용한다면 통신 속도를 낮추고 배선을 짧게 정리하는 것이 체감상 더 효과적이었습니다.

문자열 대신 8바이트 레코드로 저장했습니다

초기에는 ‘2026-08-24,27.4,61.2,438’ 같은 문자열을 저장하려 했습니다. 사람이 읽기에는 편하지만 구분자와 소수점까지 공간을 차지하고, 길이가 달라져 다음 데이터의 위치를 계산하기 불편했습니다. 결국 측정 경과 시간 4바이트, 온도 2바이트, 토양 수분 2바이트로 구성한 고정 길이 레코드를 사용했습니다. 온도는 실제 값에 100을 곱해 정수로 바꿨습니다.

32KB 용량을 8바이트 레코드로 나누면 이론상 4096회의 측정값을 담을 수 있습니다. 10분에 한 번 기록하면 약 28일 분량입니다. 다만 저장 상태를 표시하는 헤더와 오류 검사용 값을 별도로 두었기 때문에 실제 사용 가능한 횟수는 조금 줄었습니다. 이 계산을 먼저 하지 않았다면 며칠 뒤 주소가 끝에 도달해 과거 데이터를 덮어쓰는 문제를 알아차리지 못했을 것입니다.

  1. 전원을 끈 상태에서 VCC와 GND의 단락 여부를 멀티미터로 확인했습니다.
  2. EEPROM만 연결해 I2C 스캐너를 실행하고 0x50 응답을 확인했습니다.
  3. 특정 주소에 0x55와 0xAA를 기록한 뒤 전원을 껐다 켜서 다시 읽었습니다.
  4. 한 개 레코드를 저장하고 바이트 단위로 출력해 엔디언과 자료형 크기를 확인했습니다.
  5. 센서까지 연결한 뒤 100회 연속 기록과 재부팅 복원을 시험했습니다.

임베디드 코드는 라이브러리 호출만 된다고 끝나는 작업이 아니었습니다. 저장 주소 계산, 오류 반환값, 전원 차단 시점 같은 조건을 함께 다뤄야 했습니다. 하드웨어 제어 코드의 개발 환경이 어떤 역할을 하는지 더 넓게 보고 싶다면 디바이스 드라이버 통합개발환경의 개요도 참고할 만합니다.

저장 방식제가 느낀 장점실사용에서 불편했던 점
I2C EEPROM배선과 코드가 단순하고 대기 전력 관리가 쉬움용량이 작고 쓰기 주기를 계산해야 함
microSD대용량이며 CSV 파일로 바로 관리 가능파일 손상과 전원 차단 처리에 더 신경 써야 함
Wi-Fi 전송원격 확인과 장기 분석이 편함통신 음영과 서버 장애에 대비해야 함

한 달 써보니 좋았던 점과 곤란했던 순간

전원이 꺼진 원인까지 데이터로 보였습니다

가장 만족스러웠던 부분은 물을 준 직후의 수분 변화가 아니라 장치가 언제 멈췄는지를 추적할 수 있었다는 점입니다. 레코드마다 측정 순번과 부팅 횟수를 함께 저장했더니, 멀티탭 접촉 문제로 재부팅된 시점을 쉽게 찾을 수 있었습니다. 시리얼 모니터만 보고 있었다면 센서가 잠시 오작동했다고 판단했을 가능성이 큽니다.

데이터를 읽어 PC로 옮기는 과정은 예상보다 번거로웠습니다. EEPROM에는 파일 시스템이 없으므로 별도의 덤프 명령을 만들어야 했습니다. 저는 시리얼 창에서 ‘D’를 입력하면 저장된 레코드를 CSV 형태로 출력하고, ‘E’를 연속 두 번 입력해야 전체 삭제가 실행되도록 했습니다. 실수로 한 글자를 보내 기록을 지우는 일을 막기 위한 장치였습니다.

쓰기 지연과 수명은 무시할 수 없었습니다

EEPROM은 데이터를 쓰고 내부 처리를 마칠 때까지 시간이 필요합니다. 처음에는 기록 함수 직후 곧바로 다음 명령을 보내 일부 값이 누락됐습니다. 고정 지연을 길게 넣으면 쉽게 해결되지만 전체 루프가 멈추기 때문에, 실제 코드에서는 장치가 다시 응답하는지 확인하는 ACK 폴링 방식을 사용했습니다. 센서를 읽는 주기가 수분 단위라면 짧은 지연도 문제가 되지 않지만, 빠른 진동이나 오디오 신호를 기록하려는 용도로는 맞지 않습니다.

또 하나의 핵심은 쓰기 수명입니다. 같은 주소에 상태 값을 매초 갱신하는 코드를 오래 돌리면 특정 셀만 집중적으로 소모됩니다. 저는 ‘현재 저장 위치’를 매번 EEPROM에 덮어쓰지 않고, 부팅할 때 유효 레코드를 검색하도록 바꿨습니다. 기록 간격도 10초에서 10분으로 늘렸고, 센서 값이 의미 있게 달라졌을 때만 추가 기록하는 조건을 넣었습니다.

  • 좋았던 점: 인터넷 없이 동작하고 재부팅 후에도 기록이 남아 현장형 센서 연결에 적합했습니다.
  • 아쉬운 점: 저장 공간을 직접 계산해야 하며 파일 이름이나 폴더 개념이 없습니다.
  • 뜻밖의 장점: 데이터 구조를 작게 설계하면서 자료형, 바이트 순서, 체크섬을 제대로 공부하게 됐습니다.
  • 뜻밖의 단점: 잘못된 주소 계산 하나로 오래된 기록을 조용히 덮어쓸 수 있어 디버깅 로그가 꼭 필요했습니다.

제가 모듈을 구입했을 때는 저가형 EEPROM 보드가 센서 하나와 비슷한 부담으로 살 수 있는 수준이었지만, 판매처에 따라 정품 칩 여부와 실장 상태의 편차가 있었습니다. 가격만 보고 여러 개를 주문하기보다 한 개로 반복 쓰기, 전원 재인가, 주소 끝 경계 테스트를 해 본 뒤 같은 판매처에서 추가하는 편이 낫습니다. 납땜이 거칠거나 칩 표면 마킹이 불분명한 모듈은 중요한 기록용으로 쓰지 않았습니다.

측정값만 저장하지 말고 부팅 횟수, 오류 코드, 유효성 표시도 함께 남겨 보세요. 센서 수치보다 장치가 왜 멈췄는지 알려 주는 정보가 현장에서는 더 유용할 때가 많습니다.

전원이 기록 도중 꺼지면 마지막 값은 믿어도 될까?

제가 가장 자주 받은 질문을 직접 시험했습니다

답부터 말하면 쓰기 완료 전에 전원이 끊긴 마지막 레코드는 그대로 믿으면 안 됩니다. 이미 기록이 끝난 이전 레코드는 유지되지만, 쓰기 사이클 도중 차단된 바이트는 이전 값과 새 값이 섞이거나 의도하지 않은 값이 될 수 있습니다. 저도 USB 케이블을 일부러 반복해서 뽑는 시험에서 마지막 온도 값만 비정상적으로 커지는 현상을 확인했습니다.

처음에는 레코드 끝에 0xA5 한 바이트를 붙여 완료 여부를 표시했습니다. 그러나 우연히 기존 데이터가 같은 값을 가지고 있으면 잘못된 레코드를 정상으로 판단할 여지가 있었습니다. 이후에는 측정 데이터와 함께 16비트 CRC를 저장하고, 부팅 후 CRC가 일치하는 레코드까지만 유효한 것으로 처리했습니다. 복잡한 데이터베이스 기능 없이도 전원 차단에 대한 신뢰도가 눈에 띄게 높아졌습니다.

안전한 기록 순서는 세 단계로 나눴습니다

  1. 빈 슬롯을 선택합니다. 기존 정상 레코드를 먼저 지우지 않고 다음 주소에 새 데이터를 씁니다.
  2. 본문과 검증값을 기록합니다. 센서 값, 경과 시간, 부팅 번호를 쓴 뒤 CRC를 마지막에 저장합니다.
  3. 다시 읽어 확인합니다. 기록한 바이트를 즉시 읽어 CRC를 검사하고, 성공했을 때만 RAM의 다음 주소를 이동합니다.

페이지 쓰기를 사용할 때는 페이지 경계도 주의해야 합니다. 한 번의 전송이 메모리 내부 페이지 끝을 넘어가면 주소가 예상과 다르게 순환하는 칩이 있으므로, 사용하는 EEPROM 데이터시트의 페이지 크기에 맞춰 데이터를 나눠야 합니다. 제 8바이트 레코드는 시작 주소를 8의 배수로 고정해 경계 계산을 단순화했습니다. 더 큰 구조체를 그대로 저장하려는 분이라면 컴파일러가 넣는 패딩까지 확인하는 편이 좋습니다.

배터리나 어댑터 전압이 천천히 떨어지는 환경에서는 브라운아웃 감지도 유용했습니다. 전압이 불안정한 상태에서 억지로 새 기록을 시작하지 않고, 측정을 건너뛴 뒤 안정된 전원이 돌아오기를 기다리도록 구성했습니다. 대용량 커패시터만 추가해 해결하려 하면 충전 전류와 방전 시간까지 다시 계산해야 하므로 소프트웨어 검증을 함께 쓰는 쪽이 현실적이었습니다.

  • 마지막 레코드의 CRC가 틀리면 해당 레코드만 폐기하고 이전 정상 위치에서 이어 씁니다.
  • 측정값의 허용 범위를 검사해 CRC가 우연히 맞는 비정상 데이터도 한 번 더 걸러냅니다.
  • 전체 메모리가 차면 가장 오래된 슬롯부터 덮는 순환 버퍼를 사용하되, 덮어쓰기 횟수를 분산합니다.
  • 실외 프로젝트라면 정상 전원 차단뿐 아니라 케이블 흔들림, 순간 정전, 센서 분리 상태도 시험합니다.

이 방식으로 바꾼 뒤에는 마지막 한 건이 손상되더라도 그전까지의 온습도와 토양 수분 기록은 안정적으로 복원됐습니다. 독자님의 장치가 며칠 동안 사람 없이 동작해야 한다면 ‘저장이 됐는가’보다 저장 도중 멈춰도 다시 일어설 수 있는가를 먼저 시험해 보세요. 그 질문 하나가 단순한 아두이노 실습을 실제로 쓸 수 있는 임베디드 개발 프로젝트로 바꿔 줍니다.

“센서 값은 시리얼로 보면 되죠?” I2C EEPROM을 써본 뒤

댓글목록

등록된 댓글이 없습니다.