Arduino ile SD Kart Kullanımı

SD Kart Nedir?

Son zamanlarda, bu yöntem çeşitli nedenlerden dolayı tepki çekmektedir. Bunun en önemli nedenlerinden biri de genellikle bu tür kısıtlamalardan sadece ilgili medyayı yasal yollarla temin eden kullanıcıların etkilenmesi ve buna rağmen korsan yayılımın engellenememesidir. Ayrıca teknik olarak DRM sisteminin tam anlamıyla başarılı olmasının imkansızlığı ortada olmasına rağmen, dijital medyayı dağıtan şirketler bu yöntemi kullanmaya hala devam etmektedir.

sd kart, Arduino ile SD Kart Kullanımı

SD Kartların Yapısı

SD kart dahili bir denetleyici içerir. SD 1.1 standardına göre kartların depolama kapasitesi 8 MB ile başlayıp FAT16 dosya sisteminin sınırı olan 2 GB’a kadar katlanarak çıkmaktadır. SD 2.0 veya SDHC olarak bilinen standart ile beraber ise kapasite 32 GB’a ulaşmıştır. SD 3.0 veya SDXC olarak bilinen standart ile beraber ise en yüksek kapasite teorik olarak 2 TB’a erişmiştir. Ayrıca bazı kart modellerinin üzerinde bir adet yazma koruma tırnağı mevcuttur bu tırnak sayesinde sadece okuma işlemi yapılabilmektedir. Ayrıca daha ufak cihazlar için miniSD geliştirilmiştir. 20 mm × 21,5 mm × 1,4 mm ölçüleri ile ortalama SD-Card’ın yarısı kadardır. Küçük bir çevirici yardımı ile tüm normal SD Kart yuvalarına takılabilmektedir. Bu ufak kartlar 32 MB ila 2 GB arasında bir kapasiteye sahiptirler. MicroSD-kartlar ise SD Card ve miniSD den daha ufaktırlar. 11 mm × 15 mm × 1 mm ölçüleri ile 2005’te dünyanın en küçük Flash-RAM-hafıza kartıdır. SD kartlar farklı hızlarda olup hız değerleri CD-ROM sürücülerde olduğu gibi X harfiyle belirtilir ve 1X=150kB/s’dir.

SD, SDHC ve SDXC Kart

SD Kart maksimum 2GB veri depolayabilir, SDHC ise 32 GB. SDXC ise 2TB kadar veri depolayabilir.

sd kart, Arduino ile SD Kart Kullanımı

MiniSD ve MiniSDHC

Varsayılan SD Kart’ın küçültülmüş halidir, neredeyse yarı boyutundadır.

sd kart, Arduino ile SD Kart Kullanımı

MicroSD, MicroSDHC ve MicroSDXC

MicroSD Kartlar, TransFlash kart olarakta bilinmekte. Şuan boyut olarak en küçük kartlardır. Yeni telefon ve cihazlarda sıklıkla kullanılmaktadır, bu gün biz de bu kartı kullanacağız. MicroSD Kartların maksimum depolama kapasitesi 2GB dır. MicroSDHC kartların ise 32GB. MicroSDXC kartların kapasitesi 2TB kadar çıkmaktadır.

sd kart, Arduino ile SD Kart Kullanımı

SD Kartların Transfer Hızı

Piyasaya ilk sürüldüğünde, ortalama 3,6 MB/s okuma ve 0,8 MB/s yazım hızına sahip iken, günümüz kartları 2 MB/s ile veri aktarabilmektedir. High-speed olarak nitelendirilen kartlar ise 40 MB/s hızında okuma ve yazım yapabilmektedir. En yüksek değerler, üreticiye ve kullanılan cihaza göre değişebilir. Çoğunlukla aktarım hızı doğrudan verilmez, bunun yerine CD okuma hızı baz alınarak verilir (= ortalama 150 kB/s ilk single speed veya 1x sürücüler). Bu yazım metodu CD-Yazıcılar ve diğer yazılabilir medyalar için de bir standart halini almıştır. Örneğin; High-speed SD card 50x = ortalama 7,5 MB/s yazım hızına denk gelir. 267X’e kadar SD Kart’lar mevcuttur.

High Speed SD kartlar aşağıda verildiği gibi “hız sınıfı dereceleri”‘ne sahiptir. Bunlar öngörülen en düşük yazma hızlarıdır.

  • Class 2: 16 Mbit/s (2 MB/s)
  • Class 4: 32 Mbit/s (4 MB/s)
  • Class 6: 48 Mbit/s (6 MB/s)
  • Class 10: 80 Mbit/s (10 MB/s)
sd kart, Arduino ile SD Kart Kullanımı

Depolama Entegreleri

Hafıza (Memory) nedirBir önceki yazılarımızda ROM ve RAM olarak hafıza/depolama entegrelerinden bahsetmiştik. Buradan ilgili yazıya ulaşabilirsiniz.

Neden Depolamaya İhtiyaç Duyarız?

Bir çok projede verilerin kaydedilip işlenmesi, örneklerin çıkarılması önemli bir rol oynar. Örneğin GPS verileri, Sıcaklık verileri gibi. Çoğu mikroişlemci ‘nin hafızası yani EPROM’u düşük kapasitelere sahiptir. İhtiyacınız durumunda, isterseniz bir ROM çeşidi isterseniz bir SD Kart yardımı ile bu hafızayı yükseltebilirsiniz.

Bir SD Kart Okuma Modülüne Sahip Olmasaydık?

Bu modül olmadan SD Kartınızı doğrudan kartınıza bağlayabilirsiniz. Fakat bu yöntem ile kartınızın ömrünü kısaltabilir hatta tamamen bozabilirsiniz. SD kartların tamamı 3.3V ile çalışır. Ayrıca modül üstünde bulunan “level shifter” entegresi ile kartınızı sağlıklı bir biçimde kullanabilirsiniz. Kendiniz bir logic level shifter kullanmak isterseniz 74125 işinizi görecektir. 74125 quad buffer olarak adlandırılır. Bu entegrede 4 level shifter bulunmakta, E pini Enable anlamıan gelmekte. Kullanmayı düşünüyorsanız; 1,4 ve 10. pin, 7. pin ile GND’ye bağlamalısınız. Arduino kartınız üzerinden bir dijital pin ise, D pinine yani data in pinine bağlanmalıdır. O pini ise yani data out pini, SD Kartınıza bağlamalısınız kısacası yol şöyle oalcaktır; Arduino Pin 10 –> Buffer Pin 2 –> Buffer Pin 3 –> SD Kart Pin 2. Daha detaylı anlamak için veri tablosunu inceleyebilirsiniz.

Modül Hakkındaki Bilgiler

Micro sd kartlarla iletişim kurmanın iki yöntemi vardır; SPI modu ve SDIO modu. SDIO modu çok daha hızlıdır ve cep telefonlarında, dijital kameralar gibi hızın önemli olduğu cihazlarda kullanılır. Ancak daha komplikedir ayrıca bir koruma kilidi mevcuttur. Bu nedenle Arduino projeleri üzerinde çalışan kişiler tarafından SDIO modu tercih edilmemektedir. Bunun yerine, her SD kart modülü ile uyumlu ve basit, herhangi bir mikrodenetleyici ile kullanması kolay olan SPI modu tercih edilmektedir. Arıca seri haberleşme protokolleri hakkındaki yazımızı okuyarak SPI hakkında daha çok bilgiye sahip olabilirsiniz.

sd kart, Arduino ile SD Kart Kullanımı

VCC pini modül için güç sağlar ve Arduino’daki 5V pine bağlanmalıdır.

GND Arduino GND pinine bağlanmalıdır.

MISO (Master In Slave Out) , Micro SD Kart Modülünden SPI çıkışıdır.

MOSI (Master Out Slave In) , Micro SD Kart Modülüne SPI girişidir.

SCLK (Seri Saat) pini, Arduino tarafından üretilen, seri haberleşmeyi sağlayan, veri iletimini senkronize eden saat darbelerini kabul eder.

SS (Slave Select) pini, Arduino (Master) tarafından SPI veri yolundaki belirli cihazları etkinleştirmek ve devre dışı bırakmak için kullanılır.

SD Kartı Hazırlamak

Mikro SD kartı modüle takmadan ve Arduino’ya bağlamadan önce kartı düzgün bir şekilde biçimlendirmelisiniz. MicroSD kart, arduino kütüphanesi için gerekli olan ve neredeyse tüm diğer SD kütüphaneleri için kart FAT16 veya FAT32 formatında biçimlendirilmelidir. Kartı biçimlendirmek için SDA tarafından yayınlanan resmi SD kart biçimlendirici programı kullanmanızı tavsiye ediyoruz. Formatlayıcıyı indirin ve bilgisayarınızda çalıştırın, doğru sürücüyü seçin ve doğrudan FORMAT’a tıklayın.

sd kart, Arduino ile SD Kart Kullanımı

Devre Şeması

sd kart, Arduino ile SD Kart Kullanımı

Başlamak için mikro SD kart modülünü breadboard’a takın. Modüldeki VCC pinini Arduino’daki 5V pinine, GND pinini GND ‘ye bağlayın.

Micro SD kartlar çok fazla veri aktarımı gerçekleştirdiğinden dolayı, SPI pinlerine bağlayarak en iyi performansı alabilirsiniz.

Her Arduino Kartında buna göre bağlanması gereken farklı SPI pinleri olduğunu unutmayın. UNO / Nano gibi Arduino kartları için bu pinler; 13 SCLK, 12 MISO ve 11 MOSI‘dir. Ayrıca ‘chip / slave select’ SS hattı için dördüncü bir pine ihtiyacınız olacaktır. Genellikle bu pin 10’dur, ancak istediğiniz herhangi bir pini kullanabilirsiniz.

 MOSIMİSOSCKCS
Arduino Uno11121310
Arduino Nano11121310
Arduino Mega51505253

Arduino Kodu - CardInfo ve Veri Okuma-Yazma

Arudino IDE üzerinde, SD adında bir kütüphane mevcut, bir çok test ve okuma yazma işlemi için bunu kullanacağız. CardInfo örneği için bunu örnekler alt menüsünde görebilirsiniz. Devre şemasını bağlantılarını doğru bağladıysanız ve kartı FAT formatında yazdıysanız ufak bir test kodu ile kartı test edebilirsiniz.

CardInfo

#include <SPI.h>
#include <SD.h>

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

const int chipSelect = 10;

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?");
    while (1);
  } else {
    Serial.println("Wiring is correct and a card is present.");
  }

  // print the type of card
  Serial.println();
  Serial.print("Card 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");
    while (1);
  }

  Serial.print("Clusters:          ");
  Serial.println(volume.clusterCount());
  Serial.print("Blocks x Cluster:  ");
  Serial.println(volume.blocksPerCluster());

  Serial.print("Total Blocks:      ");
  Serial.println(volume.blocksPerCluster() * volume.clusterCount());
  Serial.println();

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

  volumesize = volume.blocksPerCluster();    // clusters are collections of blocks
  volumesize *= volume.clusterCount();       // we'll have a lot of clusters
  volumesize /= 2;                           // SD card blocks are always 512 bytes (2 blocks are 1KB)
  Serial.print("Volume size (Kb):  ");
  Serial.println(volumesize);
  Serial.print("Volume size (Mb):  ");
  volumesize /= 1024;
  Serial.println(volumesize);
  Serial.print("Volume size (Gb):  ");
  Serial.println((float)volumesize / 1024.0);

  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) {
}

Bağlantılar ve biçimlendirme işlemi doğru ise seri port çıktısı bu şekilde olacaktır;

sd kart, Arduino ile SD Kart Kullanımı

Veri Okuma ve Yazma

SD kartı başarıyla çalıştırdığınızı düşünürsek, bir sonraki denemeye geçelim. Aşağıdaki kod, bir dosyadan veri yazma ve okuma ile ilgili temel bir açıklama içerir. Ayrıntılı dökümüne başlamadan önce taslağı deneyin.

#include <SPI.h>
#include <SD.h>

File myFile;

// change this to match your SD shield or module;
const int chipSelect = 10;

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


  Serial.print("Initializing SD card...");

  if (!SD.begin()) {
    Serial.println("initialization failed!");
    return;
  }
  Serial.println("initialization done.");

  // open the file. note that only one file can be open at a time,
  // so you have to close this one before opening another.
  myFile = SD.open("test.txt", FILE_WRITE);

  // if the file opened okay, write to it:
  if (myFile) {
    Serial.print("Writing to test.txt...");
    myFile.println("testing 1, 2, 3.");
    // close the file:
    myFile.close();
    Serial.println("done.");
  } else {
    // if the file didn't open, print an error:
    Serial.println("error opening test.txt");
  }

  // re-open the file for reading:
  myFile = SD.open("test.txt");
  if (myFile) {
    Serial.println("test.txt:");

    // read from the file until there's nothing else in it:
    while (myFile.available()) {
      Serial.write(myFile.read());
    }
    // close the file:
    myFile.close();
  } else {
    // if the file didn't open, print an error:
    Serial.println("error opening test.txt");
  }
}

void loop()
{
  // nothing happens after setup
}

Kod Açıklaması

Kod, dahili SD kütüphanesi ve SPI arayüzü üzerinden SD kart ile kolayca iletişim kurmamızı sağlayan SPI kütüphanesini dahil etmekle başlar.

#include <SPI.h>
#include <SD.h>

 

Kütüphaneler dahil edildikten sonra, yaptığımız bir sonraki şey, SD kart modülünün chipSelect (CS) Arduino pinini bildirmektir. CS pini, Arduino dijital pinlerinden biri olarak sabitlenmeyen tek pindir. SPI arabirimini kullandığımız ve bu pinler zaten SPI kütüphanesinde bildirildiğinden diğer SPI pinlerini bildirmemize gerek yok. Pini bildirdikten sonra, SD kartta veri depolamak için kullanılacak bir myFile nesnesi oluşturalım.

const int chipSelect = 10;
File myFile;

 

Ardından, setup () bölümünde: Sonuçları ekranda göstermek için seri iletişimi başlatırız. Şimdi, SD.begin() fonksiyonunu kullanarak SD kartı başlatacağız ve başlatma başarılı olursa “ if ” ifadesi gerçekleşir ve “String” başlatma yapılır. Başarısız ise “ başlatma başarısız! ”Yazdırılır ve program sona erer.

Serial.begin(9600);
  Serial.print("Initializing SD card...");
  if (!SD.begin()) {
    Serial.println("initialization failed!");
    return;
  }
  Serial.println("initialization done.");

 

Ardından, SD.open() işlevi “ test.txt ” adlı dosyayı açacaktır. Diğer FILE_WRITE parametresi dosyayı okuma-yazma modunda açar.

myFile = SD.open("test.txt", FILE_WRITE);

 

Dosya açıldıktan sonra, ekranda “test.txt yazdırılıyor” görmeliyiz. Ardından myFile.println() işlevini kullanarak “test 1, 2, 3” metnini yazacağız. Bundan sonra, dosyaya yazılan verilerin kaydedilmesini sağlamak için close() işlevini kullanmamız gerekir.

if (myFile) {
    Serial.print("Writing to test.txt...");
    myFile.println("testing 1, 2, 3.");
    myFile.close();
    Serial.println("done.");
  } else {
    Serial.println("error opening test.txt");
  }

 

Şimdi, yazma işleminin başarılı olup olmadığını kontrol etmek için SD.open() işlevini kullanacağız, ancak bu sefer “ test.txt ” dosyası zaten oluşturulmuş olduğu için, işlev sadece dosyayı açar. Sonra myFile.read() işlevini kullanarak ekran da göreceğiz. read() işlevi aslında bir seferde yalnızca bir karakter okur, bu nedenle tüm karakterleri okumak için “while” döngüsünü ve myFile.available() işlevini kullanmamız gerekir. Sonunda da dosyayı kapatmamız gerekiyor.

myFile = SD.open("test.txt");
  if (myFile) {
    Serial.println("test.txt:");
    while (myFile.available()) {
      Serial.write(myFile.read());
    }
    myFile.close();
  } else {
    Serial.println("error opening test.txt");
  }

 

Bu, dosyaların nasıl okunacağını ve yazılacağını göstermek için sadece bir demo taslağı olduğundan, kodu birden çok kez çalıştırmanın bir anlamı yoktur. Böylece tüm kod bir loop() koymak yerine sadece bir kez çalışan setup() işlevine yerleştirilmiştir.

void loop() 
{
}

 

EKSTRA: Kullanışlı Fonksiyonlar

  • Dizeler, değişkenler vb. yazmak için seri nesneler gibi print () ve println () işlevlerini kullanabilirsiniz.
  • Read() yalnızca bir karakter döndürür. Tam satır veya sayı okumaz!
  • close() Tüm verilerin kalıcı olarak yazıldığından emin olmak için işiniz bittiğinde dosya (lar)! Bu, kullanılan RAM miktarını azaltır.
  • Dosyaları bir dizinde açabilirsiniz. Örneğin, dizinde bir dosya açmak istiyorsanız, SD.open(“/myfiles/example.txt”) kullanabilirsiniz. Kodu kendi dosyalarınıza göre düzenleyiniz.
  • SD kart kütüphanesi ‘uzun dosya adlarını’ desteklemiyor. Bunun yerine, dosya adları için 3 biçimini kullanın ve dosya adlarını kısa tutun! Örneğin datalog.txt ismi idealdir ancak “Sensörümün günlük dosyası.txt” gibi isimler iyi değildir!
  • Ayrıca dosya adlarının ‘büyük / küçük harf’ duyarlılığına sahip olmadığını unutmayın, bu nedenle datalog.txt dosyası DataLog.Txt dosyası ile aynıdır ve DATALOG.TXT dosyası ile aynıdır

SD nesnesiyle kullanabileceğiniz kullanışlı işlevler:

  • Sadece bir dosyanın var olup olmadığını kontrol etmek istiyorsanız, exists(“filename.txt”) kodunu kullanın.
  • remove(“unwanted.txt”) kodu ile bir dosyayı silebilirsiniz dikkatli olun! Bu gerçekten tamamen siler ve silinen verileri geri getirecek bir ‘Geri Dönüşüm Kutusu‘ yoktur.
  • mkdir(“/mynewdir”) kullanarak bir alt dizin oluşturabilirsiniz. Zaten bu kodu daha önce kullandıysanız, SD.exists() kodunu öncelikli olarak kullanabilirsiniz.

File nesneleriyle kullanabileceğiniz birkaç işlev vardır:

  • Bir dosyada seek() kodu, okuma / yazma imlecini yeni bir konuma taşıyacaktır. Örneğin seek(0) çok kullanışlı olabilir, imleci dosyanın başlangıcına götürecektir.
  • Aynı şekilde, dosyada nerede olduğunuzu söyleyen position() kodunu çağırabilirsiniz.
  • Bir dosyanın boyutunu bilmek istiyorsanız, size() kodunu kullanabilirsiniz.
  • Dizinler / klasörler özel dosyalardır, isDirectory() kodunu çağırarak bir dosyanın dizin de olup olmadığını belirleyebilirsiniz.
  • Bir dizininiz olduğunda, openNextFile() kodunu kullanarak dizindeki tüm dosyaları getirebilirsiniz.
  • Bir dosyanın adını bilmeniz gerekebilir (örneğin, bir dizinde openNextFile () öğesini çağırdıysanız, 8.3 biçimlendirilmiş karakter dizisine bir işaretçi döndürecek olan name () öğesini doğrudan Serial.print () yapabilirsiniz.
sd kart, Arduino ile SD Kart Kullanımı

SD Kart İle Sıcaklık Verilerini Kaydetmek

Arduino ve SD kart kullanarak bir veri kaydedici(data logger) oluşturmak çok kolaydır, bu konuda DHT11 sensörü ile basit bir sıcaklık ve nem veri kaydedicisi yapıyoruz. DHT11 sensörü bağıl nemi ve sıcaklığı algılamak için kullanıyoruz. SD kartı nem ve sıcaklık değerlerini her 1 saniyede bir kaydetmek için kullanacağız. Sıcaklık ve nem değerleri SD kartta saklanan .TXT metin dosyasına kaydedilecek.

Devre Şeması

sd kart, Arduino ile SD Kart Kullanımı

Fritzing Çizimi Karışık Geldiyse:

sd kart, Arduino ile SD Kart Kullanımı

SD Kart Modülünüz Olmaksızın Sadece Adaptör İle

sd kart, Arduino ile SD Kart Kullanımı

Arduino Kodu

// Arduino data logger with SD card and DHT11 humidity and temperature sensor
 
#include         // Include SPI library (needed for the SD card)
#include          // Include SD library
#include         // Include DHT sensor library
 
File dataFile;
 
#define DHTPIN 4            // DHT11 data pin is connected to Arduino pin 4
#define DHTTYPE DHT11       // DHT11 sensor is used
DHT dht(DHTPIN, DHTTYPE);   // Initialize DHT library
 
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("Initializing SD card...");
  if (!SD.begin()) {
    Serial.println("initialization failed!");
    while (1);
  }
  Serial.println("initialization done.");
  delay(2000);
}
 
uint16_t line = 1;
 
void loop() {
  delay(1000);
  // Read humidity
  byte RH = dht.readHumidity();
  //Read temperature in degree Celsius
  byte Temp = dht.readTemperature();
  
  dataFile = SD.open("DHT11Log.txt", FILE_WRITE);
  
  // if the file opened okay, write to it:
  if (dataFile) {
    Serial.print(line);
    Serial.print(":    Sıcaklık = ");
    Serial.print(Temp);
    Serial.print("°C,    Nem = ");
    Serial.print(RH);
    Serial.println("%");
    // Write data to SD card file (DHT11Log.txt)
    dataFile.print(line++);
    dataFile.print(":    Sıcaklık = ");
    dataFile.print(Temp);
    dataFile.print("°C,    Nem = ");
    dataFile.print(RH);
    dataFile.println("%");
    dataFile.close();
    
  }
  // if the file didn't open, print an error:
  else
    Serial.println("error opening DHT11Log.txt");
}

Son Görüntüler

sd kart, Arduino ile SD Kart Kullanımı
sd kart, Arduino ile SD Kart Kullanımı
sd kart, Arduino ile SD Kart Kullanımı