아두이노 강좌 #42 SD Card 카드 인식, 파일 쓰기, 파일 읽기
Lucy Archive
Lucy 2023
2020. 9. 27. 01:43

Arduino SD-CARD Basic1Arduino SD-CARD Basic1

Arduino Uno : SD Card Basic

이번 포스트에서는

아두이노에서 SD-Card의 연결 확인, 파일 쓰기, 파일 읽기에 대한 기초적인 코드를 소개

합니다. 아두이노에서 SD 카드를 사용하기 전 필요한 내용은 이전 포스트에 정리하였으니 필요하신 분은 하단의 관련 포스트를 참조해주세요.

하드웨어 연결

본 포스트의 코드는 Arduino Uno 보드와 Ethernet Shield2를 연결하여 Ethernet Shield2의 SD-Card를 사용하는 기준입니다. Ethernet Shield2의 SD-Card CS(Chip Select)핀은 4번입니다.

Arduino Uno Ethernet ShieldEthernet Shiled의 SD-Card CS핀


SD-Card 기본 사용법

아두이노로 SD-Card는 주로 아래와 같이 활용 될 것으로 생각해서,, 용도별 기초적인 코드를 소개합니다. 아래 소개한 코드들은 [각주:1]아두이노에서 기본적으로 제공되는 예제를 기본으로 SRAM 사용 용량을 줄이기 위해 수정한 코드입니다.

  • SD-Card 카드 인식
  • SD-Card 파일 쓰기
  • SD-Card 파일 읽기


SD-Card 연결 확인

코드

SD-Card를 사용하는 경우 SD-Card가 올바로 인식되었는지 확인하는 코드입니다. 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <SPI.h>
#include <SD.h>
 
#define SS 4
//Arduino Ehternet Shield 는 SS -> 4pin
//Adafruit SS -> 10pin
//Sparkfun SD Shield SS -> 8
 
void setup()
{
  Serial.begin(9600);
  while(!Serial){
    //wait for serial port to connect
  }
 
  Serial.println(F("Initializing SD card..."));  
  
  if (!SD.begin(SS)) {
    Serial.println(F("Card Initializing failed, or not present"));
    // don't do anything more:
    while (1);
  }
  Serial.println(F("Card initializing complete."));
}
 
void loop() {
}
cs

SD.begin(SS) 코드 설명

16번 줄의 SD.begin(SS)은 SD 라이브러리와 SD-Card를 초기화하기 위해 사용되는 SD 클래스의 begin 메소드입니다. 함수의 정의는 아래와 같습니다. SD 카드 및 라이브러리 초기화가 정상으로 진행된 경우 True를 반환합니다.

Syntax

  • SD.begin()
  • SD.begin(CSPIN)

Parameters

  • CSPIN(optional) : SDCard의 CS 핀 번호, 생략하는 경우 보드별 기본 SS핀

Returns

  • True : 성공
  • False : 실패


SD-Card 파일 쓰기

아두이노에서 SD 파일에 쓰기 위해 아래와 같은 순서로 진행해야 합니다. 파일을 책장에 꽂혀있는 노트라 생각하시면 쉽게 이해 할 수 있습니다.

  • SD 카드 연결 (책장이 있는지 확인)
  • 파일 열기 (노트를 꺼내서 펼치기)
  • 파일 쓰기 (노트에 내용 쓰기)
  • 파일 닫기 (노트를 덥고 책장에 넣기)

코드

SD 카드가 정상적으로 연결되면 hello.txt 파일을 열고 파일 제일 마지막 부분에 File Write Test 문자열 추가 후 저장합니다. hello.txt 파일이 없는 경우 새 파일을 생성 후 문자열을 저장합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <SPI.h>
#include <SD.h>
 
#define SS 4
#define FILENAME F("hello.txt")
#define STATEMENT F("File Write Test")
 
void setup() {
  Serial.begin(9600);
  while (!Serial) {
    ; 
  }
  
  Serial.print("Initializing SD card...");
  if (!SD.begin(SS)) {
    Serial.println(F("Card Initializing failed, or not present"));
    while (1);
  }
  Serial.println(F("Card initializing complete."));
 
  File dataFile = SD.open(FILENAME, FILE_WRITE);
 
  if (dataFile) {
    dataFile.println(STATEMENT);
    dataFile.close();
    Serial.println(F("File Writing is complete.."));
  }
  else {
    Serial.print(F("error opening"));
        Serial.println(FILENAME);
  }
  while (1);
}
 
void loop() {
}
cs

SD.open() 코드 설명

21LineSD.open() 함수는 SD 카드의 파일을 여는 함수입니다. 파일 열기가 성공하면 FILE 클래스의 객체를 반환하고, 실패하면 0을 반환합니다.

Syntax

  • SD.open(filepath)
  • SD.open(filepath, mode)

Parameters

  • filepath : 파일명 또는 경로를 포함한 파일명
  • mode(optional) : default - FILE_READ
  • FILE_READ : 파일 읽기 모드로 열기, 커서는 파일의 처음
  • FILE_WRITE : 파일 읽기/쓰기 모드로 열기, 커서는 파일의 끝, 파일 존재하지 않는 경우 새 파일로 열기

Returns : 출력한 데이터의 크기를 비트 단위로 반환

  • 참조하는 File Class의 객체를 반환
  • 파일을 열 수 없는 경우 0을 반환

Example

  • SD.open("Folder1/TEXT.TXT", FILE_READ); Folder1 폴더 아래 TEXT.TXT 파일을 읽기 모드로 열기

File.println() 코드 설명

24LinedataFile.println() 은 File 클래스 객체 dataFile에 데이터를 쓰는 함수입니다. Serial.println()는 시리얼 포트로 데이터를 출력하는 것과 같이 dataFile.println()은 파일에 데이터를 출력합니다. 여기서 dataFile 은 File 클래스로 21번 줄에 선언이 되어 있습니다. dataFIle 은 SD.open(FILENAME, FILE_WRITE) 함수의 반환된 hello.txt 파일 자체를 지칭합니다.

Syntax

  • file.println()
  • file.println(data)
  • file.println(data, BASE)

Parameters

  • file : SD.open()으로 반환된 File 클래스 객체
  • data(optional) : 출력할 데이터 (char, byte, int, long or string)
  • BASE(optional) :
    • BIN : 2진수로 출력
    • OCT : 8진수로 출력
    • DEC : (Default)
    • HEX : 16진수로 출력

Returns :

  • 작성한 데이터의 크기를 byte 단위로 반환
  • 반환 값을 읽는 것은 옵션

※ File에 데이터를 입력하기 위해 File.print(), File.write() 도 함께 사용 될 수 있습니다.

File.close() 코드 설명

25Line의 dataFile.close()는 파일을 닫는 함수입니다. 파일을 닫는 행위는 이 파일에 접근하지 못하게 보호하는 역할을 한다고 생각하시면 됩니다. 노트 작성 후 책상위에 그대로 올려 놓으면 누군가 와서 볼 수도 있고, 내가 원치 않는 내용을 기입할 수 있기 때문입니다.

Syntax

  • file.close()

Parameters

  • file : SD.open()으로 반환된 File 클래스 객체

Returns : None


SD-Card 파일 읽기

아두이노에서 SD 카드에 저장된 파일을 읽기는 아래와 같은 순서로 진행됩니다. 

  • SD 카드 연결 확인
  • 파일 열기
  • 파일 읽을 데이터 있는지 확인
  • 파일 읽기
  • 파일 닫기

코드

SD 카드가 정상적으로 연결되면 hello.txt 파일을 열고, 파일의 데이터를 시리얼 포트로 출력 후 파일을 닫습니다. 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <SPI.h>
#include <SD.h>
 
#define CS_PIN 4
#define FILENAME F("hello.txt")
 
void setup() {
  Serial.begin(9600);
  while (!Serial) {
    ;
  }
  
  Serial.print(F("Initializing SD card..."));
 
  /* 카드 연결 확인 : 시작 */
  if (!SD.begin(CS_PIN)) {
    Serial.println(F("Card failed, or not present"));
    while (1);
  }
  Serial.println(F("card initialized."));
  /* 카드 연결 확인 : 끝 */
 
  /* FILENAME 파일 읽기 모드로 열기*/
  File dataFile = SD.open(FILENAME);
 
  /* 파일 읽어서 시리얼 포트로 출력 */ 
  if (dataFile) {
    Serial.println(F("=====File Read Start!========"));
    while(dataFile.available()){
      char temp = dataFile.read();
      Serial.print(temp); // dataFile 내용 시리얼 통신으로 보내기
    }
    dataFile.close();
    Serial.println(F("=====File Read Succeed!======"));
  }
  else {
    Serial.println(F("error opening datalog.txt"));
  }
}
 
void loop() {
}
cs

File.available() 코드 설명

29Line의 dataFile.available() 함수는 dataFile에 읽을 수 있는 데이터가 있는지 확인하는 함수입니다. 시리얼 통신 코드에서 Serial.available() 함수가 시리얼 수신 버퍼에 데이터가 있는지 확인 하는 것과 같은 개념입니다. file에 읽을 수 있는 데이터가 있는 경우 읽을 수 있는 데이터의 크기를 반환합니다.

Syntax

  • file.available()

Parameters

  • file : SD.open() 으로 반환된 File 클래스 객체

Returns : 읽을 수 있는 데이터의 크기를 int 형으로 반환

File.read() 코드 설명

30Line의 dataFile.read() 함수는 dataFile에서 Byte 크기 단위로 데이터를 읽고 커서를 이동하는 함수입니다. 시리얼 통신에서 Serial.read() 가 시리얼 수신 버퍼에서 데이터를 1Byte 읽어 오는 것과 같은 개념입니다.

Syntax

  • file.read()
  • file.read(buf,len)

Parameters

  • file : SD.open() 으로 반환된 File 클래스 객체
  • buf : Char 또는 Byte 타입의 배열
  • len : buf의 데이터 크기
Returns
  • file.read() : 1Byte 타입 데이터 읽기
  • file.read(buf,len) : buf에 len 길이의 Byte(또는 Char) 타입 데이터 저장

요약

이번 포스트에서는 아두이노에서 SD-CARD 인식 방법, 파일 쓰기, 파일 읽기를 위한 기초적인 코드를 소개하였습니다. 내용을 요약하면 아래와 같습니다.

  • 카드 인식
    • SD.begin() 함수로 SD 카드 연결 확인
  • 파일 쓰기
    • SD.begin() 함수로 SD 카드 연결 확인
    • file.open() 함수로 파일을 열기
    • file.print() / file.println() / file.write() 함수로 데이터 쓰기
    • file.close() 파일 닫기
  • 파일 읽기
    • SD.begin() 함수로 SD 카드 연결 확인
    • file.open() 함수로 파일을 열기 - 커서가 데이터의 맨 앞으로 이동
    • file.available() 읽을 수 있는 데이터 크기 확인
    • file.read() / file.read(buf,len) 등으로 데이터를 읽어 오기
    • file.close() 파일 닫기

이후 포스트에서는 파일 수정, 파일 삭제, 파일 내 데이터 검색, 디렉터리 리스트 보는 기초적인 코드를 소개할 예정입니다. 끝까지 읽어 주셔서 감사합니다.😊 

관련포스트

👉 아두이노 SD-Card 관련글 목록 보기

👉 아두이노 관련글 전체 목록 보기

  1. Arduino SD Library : https://www.arduino.cc/en/reference/SD [본문으로]