아두이노 EEPROM을 활용한 전원 종료 시 설정 값 및 마지막 데이터 보존법
아두이노 프로젝트를 진행하다 보면 전원이 꺼져도 특정 설정 값이나 마지막 상태를 기억하고 싶을 때가 많습니다. 예를 들어, 스마트 조명의 밝기 설정, 로봇의 마지막 위치, 또는 센서의 보정 값 등이 해당될 수 있습니다. 전원이 다시 켜졌을 때 이전에 설정했던 값들을 그대로 유지하여 사용자가 다시 설정할 필요 없이 프로젝트를 바로 이어서 사용할 수 있다면 사용자 경험이 훨씬 좋아질 것입니다. 이때 활용할 수 있는 것이 바로 아두이노의 EEPROM(Electrically Erasable Programmable Read-Only Memory)입니다.
EEPROM은 전원이 공급되지 않아도 데이터를 보존하는 비휘발성 메모리의 일종입니다. RAM(Random Access Memory)이 전원이 끊기면 저장된 모든 데이터를 잃어버리는 휘발성 메모리인 것과 대조적입니다. 아두이노 보드에 내장된 EEPROM은 프로그램 코드를 저장하는 플래시 메모리와는 또 다른 영역으로, 사용자가 직접 데이터를 쓰고 읽을 수 있도록 제공됩니다. 이 글에서는 아두이노 EEPROM을 효과적으로 사용하여 프로젝트의 설정 값과 데이터를 안전하게 보존하는 방법에 대해 자세히 알아보겠습니다.
EEPROM은 무엇이며 왜 중요할까요
EEPROM은 Electrically Erasable Programmable Read-Only Memory의 약자로, 전기적으로 지우고 다시 프로그래밍할 수 있는 읽기 전용 메모리입니다. 이름에서 알 수 있듯이, 한번 기록된 데이터는 전원이 없어도 유지되며, 필요할 때 다시 지우고 새로운 데이터를 기록할 수 있습니다. 아두이노에 내장된 EEPROM은 보통 수백 바이트에서 수 킬로바이트 정도의 작은 용량을 제공하지만, 설정 값이나 적은 양의 데이터를 저장하기에는 충분합니다.
아두이노 프로젝트에서 EEPROM이 중요한 이유는 다음과 같습니다.
- 데이터 영속성 전원이 끊겨도 데이터가 사라지지 않으므로, 프로젝트의 마지막 상태나 사용자가 설정한 값들을 기억할 수 있습니다.
- 사용자 편의성 증대 매번 전원을 켤 때마다 설정을 다시 할 필요가 없어 사용자가 프로젝트를 더욱 편리하게 사용할 수 있습니다.
- 프로젝트의 안정성 향상 예기치 않은 전원 차단에도 중요한 데이터를 보존하여 프로젝트의 연속성과 안정성을 높일 수 있습니다.
실생활에서 EEPROM 활용 사례
EEPROM은 우리 주변의 다양한 전자제품에서 찾아볼 수 있으며, 아두이노 프로젝트에서도 무궁무진하게 활용될 수 있습니다.
- 스마트 홈 기기 스마트 조명의 마지막 밝기, 색상 설정, 스마트 플러그의 타이머 설정, 온도 조절 장치의 희망 온도 등이 전원 종료 후에도 보존됩니다.
- 로봇 및 자동화 시스템 로봇의 마지막 동작 상태, 특정 구간까지의 이동 횟수, 공장 자동화 라인의 생산량 카운터 등이 저장되어 재부팅 시에도 작업을 이어서 수행할 수 있습니다.
- 측정 장비 센서의 보정 값, 마지막으로 측정된 최고 또는 최저 값, 특정 알림 임계값 등이 저장되어 정확한 측정을 유지하고 이전 데이터를 참조할 수 있습니다.
- 개인 맞춤형 장치 개인용 웨어러블 기기의 사용자 프로필, 게임 콘솔의 점수 기록, 맞춤형 디스플레이의 설정 등이 저장되어 개인화된 경험을 제공합니다.
- 카운터 및 타이머 전원이 꺼져도 누적 카운트나 타이머의 진행 상황이 리셋되지 않고 유지됩니다.
이처럼 EEPROM은 프로젝트에 ‘기억력’을 부여하여 훨씬 더 스마트하고 유용하게 만들어 줍니다.
아두이노 내장 EEPROM의 이해
대부분의 아두이노 보드에 사용되는 ATmega 마이크로컨트롤러는 내장 EEPROM을 가지고 있습니다. 아두이노 우노(ATmega328P)의 경우 512바이트의 EEPROM을 제공하며, 메가(ATmega2560)는 4KB의 EEPROM을 제공합니다. 용량은 크지 않지만 대부분의 설정 값을 저장하기에는 충분합니다.
EEPROM의 수명과 한계
EEPROM은 비휘발성 메모리이지만, 무한정 데이터를 쓰고 지울 수 있는 것은 아닙니다. 일반적으로 EEPROM 셀은 약 10만 번의 쓰기 주기를 가집니다. 즉, 한 주소에 10만 번 정도 데이터를 쓰면 해당 셀이 더 이상 데이터를 안정적으로 저장하지 못하게 될 수 있습니다. 이는 EEPROM을 사용할 때 가장 중요하게 고려해야 할 사항 중 하나입니다. 읽기 작업에는 이러한 제한이 없습니다.
기본적인 EEPROM 읽기 쓰기 함수
아두이노 IDE는 EEPROM 라이브러리를 통해 EEPROM에 쉽게 접근할 수 있는 함수들을 제공합니다.
EEPROM.write(address, value)특정 주소(0부터 시작)에 1바이트의 데이터를 씁니다.
EEPROM.read(address)특정 주소에서 1바이트의 데이터를 읽어옵니다.EEPROM.update(address, value)이 함수는EEPROM.write()와 유사하지만, 현재 저장된 값과 쓰려는 값이 다를 경우에만 쓰기 작업을 수행합니다. 이는 EEPROM의 쓰기 수명을 보존하는 데 매우 유용하므로,EEPROM.write()대신EEPROM.update()를 사용하는 것이 좋습니다.
다양한 데이터 형식 저장하기
EEPROM은 기본적으로 1바이트(8비트) 단위로 데이터를 저장합니다. 하지만 아두이노 라이브러리는 EEPROM.put()과 EEPROM.get() 함수를 제공하여 더 큰 데이터 형식(정수, 실수, 구조체 등)을 쉽게 저장하고 읽을 수 있도록 도와줍니다.
바이트와 정수 저장하기
1바이트 데이터는 EEPROM.write() 또는 EEPROM.update()를 사용하여 직접 저장할 수 있습니다. int(2바이트), long(4바이트) 같은 정수형은 여러 바이트를 차지하므로, EEPROM.put()과 EEPROM.get()을 사용하는 것이 가장 편리합니다.
예시: 정수 저장 및 읽기 (개념 코드)
#include <EEPROM.h>
int settingValue = 12345;
int address = 0; // 저장할 EEPROM 시작 주소
void setup() {
Serial.begin(9600);
// EEPROM에 정수 쓰기
EEPROM.put(address, settingValue);
Serial.println("Setting value written to EEPROM.");
// EEPROM에서 정수 읽기
int readValue;
EEPROM.get(address, readValue);
Serial.print("Setting value read from EEPROM: ");
Serial.println(readValue);
}
void loop() {
// 아무것도 하지 않음
}
실수와 문자열 저장하기
float(4바이트)와 double(4 또는 8바이트) 같은 실수형도 EEPROM.put()과 EEPROM.get()을 사용하여 저장할 수 있습니다. 문자열은 각 문자가 1바이트이므로, 문자 배열로 선언한 후 EEPROM.put()을 사용하거나, 각 문자를 반복문을 통해 개별적으로 저장할 수 있습니다. 단, 문자열의 끝을 나타내는 널 종료 문자(‘