[매드] 아두이노 강좌 - 30. SD카드 모듈 동작

안녕하세요~ 매드 입니다.

벌써 30강이네요! (WiFi 동작으로 삽질한것 빼면 ... 30강 안됨 ㅎ)

시간 참 빨리 갑니다. ㅎㅎ 이것저것 가볍게 기본동작만 다루면서 진행하다보니 어느새 30강이 되었네요 ㅎㅎ

이제 슬슬 제가 다룰 수 있는 것들도 몇개 안남은 것 같습니다.

고급강좌부터는 지금까지 했던 것들을 응용해서 하나씩 자세히 다뤄보도록 할텐데요 ㅎㅎ 빠르면 이번달 말이나 다음달부터 진행하지 않을까 생각해보네요 ㅎㅎ

그럼 이번시간에는 SD카드 모듈 동작에 대해서 다뤄보도록 하겠습니다.


30-1. SD카드란?
<SD카드 종류(출처:구글사진)>

SD카드는 위와 같은 종류들이 있습니다. 최근에 많이 사용하는 건 MicroSD카드 정도가 되겠네요. 이런 SD카드는 서로 어느정도 호환이 되기 때문에 기존에 사용하던 프로그램이 있다면 일반적으로 거의 동일하게 사용하실 수 있습니다.

SD카드의 등장은 90년대쯤 등장했는데요. 유명한 제조사로는 SanDisk, 삼숭, 하이닉스 등이 있겠네요~ ㅎㅎ

요즘에 저장장치로 워낙 많은 곳에서 사용하다보니 요정도는 알고가면 좋겠다 싶어서 조금 자세히 알아보겠습니다.

SD카드의 설계에 따라 몇가지로 분류할 수 있는데요.

SLC(Single Level Cell)
  . 한 개의 소자가 1비트를 가짐
  . 수명:최고 10만회
  . 속도 50~100k(cycle당)
MLC(Multi Level Cell)
  . 한개의 소자가 2비트를 가짐
  . 수명:최고 1만회
  . 속도:5~10k(cycle당)
TLC(Triple Level Cell)
  . 한개의 소자가 3비트를 가짐
  . 수명:최고1000회
  . 속도:1~3k(cycle당)

위 내용에서 용량만 보면 TLC가 단연 최고 입니다. 같은 면적으로 SLC보다 3배까지 더 저장이 가능한것이니까요. 하지만!?!? 속도랑 특히 수명을 보시면 기하급수적으로 줄어드시는 것을 볼 수 있습니다. 사실 최근에 용량은 커지는데 가격은 내려가는 이유가 이런 기술때문이라고 할 수 있구요. 때문에 새로이 발생하는 문제가 영상 저장장치들에서 메모리카드가 금방금방 망가지는 문제가 있습니다.(흑흑)

이런것을 해결하기 위해 몇가지 기술들로 노력중인데.. 머.. 금방 해결되겠죠??

<출처:나무위키>
SD카드에는 읽고쓰는 속도에따라 클래스가 나뉘는데요. 최근에 보통 보실 수 있는 속도는 Class10 정도가 됩니다. 아마 이정도 쓰시면 FullHD 영상을 저장하시는것 까지는 문제 없으시리라 봅니다. 이외에도 가격이 올라갈수록 읽고쓰는 속도가 다르다는건 당연한거겠죠~?

이 메모리 내부에도 우리가 PC에 연결하여 일반 하드디스크 처럼 쓸 수 있는 것은 내부에 파일시스템으로 포맷해서 사용하기 때문인데요. 주로 FAT32 파일시스템을 쓰고 있다고 보시면 됩니다. 이외에도 NTFS, EXT4 등등이 있는데요. 요건 파일시스템이라고 따로 검색해보시면 각각의 장단점을 아실 수 있으실 것 같네요!

우선은 여기까지만 알면 오늘 다루는 SD카드는 문제가 없을 것 같네요.
SD카드를 좀더 자세하고 깊게 다루실려면 FAT32파일 시스템에 대해서 공부하셔야 합니다.


30-2. SD카드 모듈 연결

<SD카드 아두이노 연결(출처:구글사진)>

SD카드는 아두이노와 SPI 통신으로 연결됩니다. 아두이노의 여러 통신들 중 가장 빠른 통신이 SPI 통신이기 때문인데요. 이를 사용하여 SD카드에 데이터를 쓰거나 읽게 되는 것이지요.

이외에도 SD카다는 SDIO라는 방식으로도 제어할 수 있지만 SPI 통신 방식이 워낙 보편적으로 사용되고 쉬워서 최근에는 대부분이 SPI 방식으로 통신한다고 보시면 될 것 같습니다.

SPI통신은 하나의 마스터와 여러개의 슬래이브를 같은 통신라인으로도 사용할 수 있는데요. 이런 것들이 아마도 많은 사람들이 사용하게 만드는 장점인 것 같네요.


30-3. 펌웨어 코드

/*
  SD card test

 This example shows how use the utility libraries on which the'
 SD library is based in order to get info about your SD card.
 Very useful for testing a card when you're not sure whether its working or not.

 The circuit:
  * SD card attached to SPI bus as follows:
 ** MOSI - pin 11 on Arduino Uno/Duemilanove/Diecimila
 ** MISO - pin 12 on Arduino Uno/Duemilanove/Diecimila
 ** CLK - pin 13 on Arduino Uno/Duemilanove/Diecimila
 ** CS - depends on your SD card shield or module.
  Pin 4 used here for consistency with other Arduino examples


 created  28 Mar 2011
 by Limor Fried
 modified 9 Apr 2012
 by Tom Igoe
 */
// include the SD library:
#include <SPI.h>
#include <SD.h>

// set up variables using the SD utility library functions:
Sd2Card card;
SdVolume volume;
SdFile root;

// change this to match your SD shield or module;
// Arduino Ethernet shield: pin 4
// Adafruit SD shields and modules: pin 10
// Sparkfun SD shield: pin 8
const int chipSelect = 4;

void setup() {
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }


  Serial.print("\nInitializing SD card...");

  // we'll use the initialization code from the utility libraries
  // since we're just testing if the card is working!
  if (!card.init(SPI_HALF_SPEED, chipSelect)) {
    Serial.println("initialization failed. Things to check:");
    Serial.println("* is a card inserted?");
    Serial.println("* is your wiring correct?");
    Serial.println("* did you change the chipSelect pin to match your shield or module?");
    return;
  } else {
    Serial.println("Wiring is correct and a card is present.");
  }

  // print the type of card
  Serial.print("\nCard type: ");
  switch (card.type()) {
    case SD_CARD_TYPE_SD1:
      Serial.println("SD1");
      break;
    case SD_CARD_TYPE_SD2:
      Serial.println("SD2");
      break;
    case SD_CARD_TYPE_SDHC:
      Serial.println("SDHC");
      break;
    default:
      Serial.println("Unknown");
  }

  // Now we will try to open the 'volume'/'partition' - it should be FAT16 or FAT32
  if (!volume.init(card)) {
    Serial.println("Could not find FAT16/FAT32 partition.\nMake sure you've formatted the card");
    return;
  }


  // print the type and size of the first FAT-type volume
  uint32_t volumesize;
  Serial.print("\nVolume type is FAT");
  Serial.println(volume.fatType(), DEC);
  Serial.println();

  volumesize = volume.blocksPerCluster();    // clusters are collections of blocks
  volumesize *= volume.clusterCount();       // we'll have a lot of clusters
  volumesize *= 512;                            // SD card blocks are always 512 bytes
  Serial.print("Volume size (bytes): ");
  Serial.println(volumesize);
  Serial.print("Volume size (Kbytes): ");
  volumesize /= 1024;
  Serial.println(volumesize);
  Serial.print("Volume size (Mbytes): ");
  volumesize /= 1024;
  Serial.println(volumesize);


  Serial.println("\nFiles found on the card (name, date and size in bytes): ");
  root.openRoot(volume);

  // list all files in the card with date and size
  root.ls(LS_R | LS_DATE | LS_SIZE);
}


void loop(void) {

}


SD카드를 처음 넣고 SPI 연결한 후 펌웨어 SD 기본 예제를 불러오면 위와 같은 기본 코드가 생성됩니다.(ㅋㅋ 그냥 IDE에 있는거에요~)

자.. 그럼 실제 동작은 영상으로 확인하시는 걸로!!

다음주에는 무얼 해야하나... 고민하면서!! 그럼 다음주에 뵈요~~


댓글 쓰기

0 댓글