본문 바로가기
  • 재미있는 펌웨어와 코딩
ESP32/펌웨어

ESP32 환경설정 저장 - Preferences

by 윤재윤호 2023. 10. 5.

ESP32에서 환경변수 저장은 EEPROM을 사용하지 않고 내부의 Flash 메모리에 저장합니다.
EEPROM을 사용할 때 보다 자유롭고 더 많은 데이터를 저장할 수 있습니다.

ESP32에는 아주 편한 Preferences 클래스가 있습니다.

네임스페이스 안에 키와 값이 쌍으로 연결되는 구조 입니다.

네임스페이스1 {

   키1 : 값,

   키2 : 값,

   키3 : 값

}

 

네임스페이스2 {

   키1 : 값,

   키2 : 값,

   키3 : 값

}

 

마치, 윈도우의 INI파일과 같이 사용하면 됩니다.

Preferences에 여러개의 네임스페이스가 존재 할 수 있습니다. 그러므로 환경변수를

그룹별로 저장이 가능합니다.


먼저, 예제 부터 보겠습니다.
아래의 코드는 제가 좀 더 쉽게 사용하기 위하여 두 개의 함수를 만들었습니다.

와이파이에 접속하기 위해서 SSID 와 PASSWORD를 저장하고 읽어오는 코드 입니다.
소스코드

#include <Preferences.h>
#include <nvs_flash.h>

// INI 쓰기
void SetIni( String sNamespace, String sKey, String sValue ) {
  Preferences preferences;
  preferences.begin( sNamespace.c_str(), false );
  preferences.putString( sKey.c_str(), sValue.c_str() );
  preferences.end();
}

// INI 읽기
String GetIni( String sNamespace, String sKey, String sDefaultValue ) {
  Preferences preferences;
  String sValue;
  preferences.begin( sNamespace.c_str(), false );
  sValue = preferences.getString( sKey.c_str(), sDefaultValue.c_str() );
  preferences.end();
  return sValue;
}

void setup() {
  Serial.begin( 115200 );

  Serial.print( "ssid : " );
  Serial.println( GetIni( "wifi-config", "ssid", "none" ) );
  Serial.print( "password : " );
  Serial.println( GetIni( "wifi-config", "password", "none" ) );
}

void loop() {
  if( Serial.available() ) {
    switch( Serial.read() ) {
      case '1' : 
        SetIni( "wifi-config", "ssid", "iptime" );
        SetIni( "wifi-config", "password", "12345678" );
        Serial.println( "OK" );
        break;
      case '2' : 
        SetIni( "wifi-config", "ssid", "hello" );
        SetIni( "wifi-config", "password", "abcd1234" );
        Serial.println( "OK" );
        break;
      case 'e' :
        nvs_flash_erase(); // erase the NVS partition and...
        nvs_flash_init(); // initialize the NVS partition.
        Serial.println( "OK" );
        break;
      default : break;
    }
  }
}

 

Preferences를 사용하기 위하여 헤더 파일을 정의 합니다.

nvs_flash.h 는 모든 환경 변수를 삭제 하기 위함입니다.

#include <Preferences.h>
#include <nvs_flash.h>

 

네임스페이스라는 그룹안에 키와 값을 저장하는 코드 입니다.

// INI 쓰기
void SetIni( String sNamespace, String sKey, String sValue ) {
  Preferences preferences;
  preferences.begin( sNamespace.c_str(), false );
  preferences.putString( sKey.c_str(), sValue.c_str() );
  preferences.end();
}

 

네임스페이스라는 그룹안에 같은 이름의 키에 저장된 값을 읽어오는 코드 입니다.

만약, 존재하지 않는 키 일 때 기본값을 리턴 합니다.

// INI 읽기
String GetIni( String sNamespace, String sKey, String sDefaultValue ) {
  Preferences preferences;
  String sValue;
  preferences.begin( sNamespace.c_str(), false );
  sValue = preferences.getString( sKey.c_str(), sDefaultValue.c_str() );
  preferences.end();
  return sValue;
}

 

처음에 부팅시 ssid 와 password를 읽어오면 당연히 값이 none 입니다.

Serial.print( "ssid : " );
Serial.println( GetIni( "wifi-config", "ssid", "none" ) );
Serial.print( "password : " );
Serial.println( GetIni( "wifi-config", "password", "none" ) );

아무런 값이 없음

 

예제 코드를 실행 후 시리얼창에서 '1' 문자를 송신하면 새로운 값을 저장 합니다.

문자 1을 전송

 

그리고 나서 재부팅을 하시면 새롭게 저장된 값이 표시 되는것을 확인 할 수 있습니다.

저장된 자격증명 표시

 

시리얼창에서 'e' 문자를 전송하면 모든 값이 초기화 됩니다. (모든 네임스페이스를 삭제)

nvs_flash_erase(); // erase the NVS partition and...
nvs_flash_init(); // initialize the NVS partition.

 

preferences.remove("ssid"); 는 키를 지웁니다.

preferences.clear(); 는 네임스페이스의 모든 내용을 지웁니다.

 

그 외, 문자열 뿐만 아니라 다양한 값을 지원합니다.

 

데이터 저장 방식

Char  putChar(const char* key, int8_t value)
Unsigned Char putUChar(const char* key, int8_t value)
Short putShort(const char* key, int16_t value)
Unsigned Short  putUShort(const char* key, uint16_t value)
Int putInt(const char* key, int32_t value)
Unsigned Int  putUInt(const char* key, uint32_t value)
Long  putLong(const char* key, int32_t value)
Unsigned Long putULong(const char* key, uint32_t value)
Long64  putLong64(const char* key, int64_t value)
Unsigned Long64 putULong64(const char* key, uint64_t value)
Float putFloat(const char* key, const float_t value)
Double  putDouble(const char* key, const double_t value)
Bool  putBool(const char* key, const bool value)
String  putString(const char* key, const String value)
Bytes putBytes(const char* key, const void* value, size_t len)

 

데이터 읽는 방식

Char  getChar(const char* key, const int8_t defaultValue)
Unsigned Char getUChar(const char* key, const uint8_t defaultValue)
Short getShort(const char* key, const int16_t defaultValue
Unsigned Short  getUShort(const char* key, const uint16_t defaultValue)
Int getInt(const char* key, const int32_t defaultValue)
Unsigned Int  getUInt(const char* key, const uint32_t defaultValue)
Long  getLong(const char* key, const int32_t defaultValue)
Unsigned Long getULong(const char* key, const uint32_t defaultValue)
Long64  getLong64(const char* key, const int64_t defaultValue)
Unsigned Long64 gettULong64(const char* key, const uint64_t defaultValue)
Float getFloat(const char* key, const float_t defaultValue)
Double  getDouble(const char* key, const double_t defaultValue)
Bool  getBool(const char* key, const bool defaultValue)
String  getString(const char* key, const String defaultValue)
String  getString(const char* key, char* value, const size_t maxLen)
Bytes getBytes(const char* key, void * buf, size_t maxLen)