Vydělávej až 160.000 Kč měsíčně! Akreditované rekvalifikační kurzy s garancí práce od 0 Kč. Více informací.
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Lekce 18 - Arduino - Práce s SD kartou

V minulé lekci, Arduino - Komunikace přes Bluetooth, jsme se naučili navázat komunikaci pomocí Bluetooth.

V tomto tutoriálu Arduina se naučíme připojit SD kartu. Vyzkoušíme si čtení i ukládání dat. Využijeme k tomu standardní modul čtečky SD karet, například tento. Velmi podobně se ale až na několik detailů zachází s téměř každým shieldem, který v sobě slot na SD kartu obsahuje.

Připojení SD karty k Arduinu

Samotnou SD kartu můžeme použít libovolnou, podmínkou je jen naformátování v systému FAT nebo FAT32. Kartu nebudeme formátovat pomocí nástrojů v operačním systému počítače. Místo toho k tomu použijeme formátovací program ze stránek SD Asociace. Máme tedy naformátováno a můžeme se pustit do práce. Na modulu máme piny GND, 5 V, MISO, SCK(/CLK), MOSI a CS:

  Arduino Mega Arduino Uno
MOSI 51 11
SCK 52 12
MISO 50 15
CS 53 4

Pro Arduino Mega zapojíme čtečku dle prvního sloupečku. Pro jiný model (např. Uno) použijeme druhý sloupeček. Pokud máme shield se slotem, bude s Arduinem Mega fungovat pouze pokud má vývody k pinům 50 - 53 a slot je na nich. Musíme si také zjistit, na který pin je přivedený CS.

Nejprve si ověříme funkčnost SD karty. Připojíme ji, otevřeme Arduino IDE a v menu klikneme na File -> Examples -> SD -> CardInfo. Knihovna pro SD kartu je již součástí IDE. V kódu hned nad setupem najdeme v příkladu řádek const int chipSelect = 4;.

Pro Arduino Mega přepíšeme hodnotu na 53. Pro shield použijeme pin, na kterém je CS. Pro ostatní Arduina ponecháme hodnotu beze změny. Kód nahrajeme do Arduina s připojenou kartou. Pomocí klávesové zkratky Ctrl + Shift + M otevřeme sériový monitor, ve kterém uvidíme výstup:

Initializing SD card...Wiring is correct and a card is present.

Card type: SD1

Volume type is FAT16

Volume size (bytes): 127041536
Volume size (Kbytes): 124064
Volume size (Mbytes): 121

Files found on the card (name, date and size in bytes):

Pokud by nastal nějaký problém, zobrazilo by se chybové hlášení:

Initializing SD card...initialization failed. Things to check:
* is a card is inserted?
* Is your wiring correct?
* did you change the chipSelect pin to match your shield or module?

V takovém případě zkontrolujeme vedení, kartu a ochranu proti přepisu. Pokud je karta nesprávně naformátovaná, zobrazí se následující výpis:

Initializing SD card...Wiring is correct and a card is present.

Card type: SDHC
Could not find FAT16/FAT32 partition.
Make sure you've formatted the card

V případě této chyby formátování zopakujeme. Nikdy ale nelze vyloučit, že karta je nějak poškozená. Vyplatí se tedy mít záložní a ověřit si i tu.

Pokud nám test vypsal charakteristiky karty správně, můžeme pokračovat.

Zápis dat na kartu

Pro demonstraci zápisu dat na kartu využijeme nám už známý modul DHT11. Na kartu budeme ukládat data, která nám tento modul poskytne.

Začneme tím, že naimportujeme všechny potřebné knihovny:

#include <dht11.h>
#include <SD.h>

Vytvoříme nám již známý DHT11:

dht11 cidlo;
int dht11Pin = 7;

A nakonec inicializujeme SD kartu:

const int chipSelect = 53; // Nezapomeneme patřičně upravit hodnotu dle typu Arduina

void setup()
{
  SD.begin(chipSelect);
}

Nyní se můžeme pustit do smyčky void loop(). Začneme tím, že si vytvoříme proměnné typu String k uložení dat:

void loop()
{
  cidlo.read(dht11Pin);
  String teplota = String(cidlo.temperature);
  String vlhkost = String(cidlo.humidity);
  String cas = String(millis());
  teplota += "   ";
  vlhkost += "   ";
  cas +=     "               ";

  String data = cas.substring(0,16) + teplota.substring(0,3) + vlhkost.substring(0,3);

Uložíme si do nich teplotu, vlhkost a také počet milisekund od spuštění. Důvodem, proč za String přidáváme ty mezery je to, že funkce substring() vezme z textového řetězce určitou část, např. z času vezmeme jen 0 až 16-tý znak (indexování od nuly). Proč to děláme si vyjasníme za chvíli. Nyní nám zbývá otevřít soubor pro zápis:

File soubor = SD.open("mereni.txt", FILE_WRITE);

Soubor otvíráme pomocí funkce SD.open. File je proměnná, do které se soubor uloží. Pojmenujeme si ji soubor. Otevřeme soubor mereni.txt a budeme zapisovat. Pokud soubor neexistuje, funkce jej vytvoří. Pokud existuje, bude připisovat data na jeho konec. Po zápisu dat soubor nezapomeneme zavřít:

  if(soubor)
  {
    soubor.println(data);
    soubor.close();
  }

  delay(1000);
}

Je velmi vhodné soubor vždy hned po zápisu dat zavřít a pamatovat si, že nikdy nemůžeme mít otevřeno více souborů současně.

Do našeho Arduina pak nahrajeme následující kód:

#include <dht11.h>
#include <SD.h>

dht11 cidlo;
int dht11Pin = 7;


const int chipSelect = 53;

void setup()
{
  SD.begin(chipSelect);
}

void loop()
{
  cidlo.read(dht11Pin);
  String teplota = String(cidlo.temperature);
  String vlhkost = String(cidlo.humidity);
  String cas = String(millis());
  teplota += "   ";
  vlhkost += "   ";
  cas +=     "               ";

  String data =cas.substring(0,16) + teplota.substring(0,3) + vlhkost.substring(0,3) ;

  File soubor = SD.open("mereni.txt", FILE_WRITE);

  if(soubor)
  {
    soubor.println(data);
    soubor.close();
  }

  delay(1000);
}

Spustíme zapojení, necháme jej chvíli běžet a poté kartu jednoduše vyjmeme a otevřeme v počítači:

Ukládání na SD kartu v Arduino - Arduino - Hardware

Vidíme, že na kartu se uložil soubor MERENI.TXT. A to přestože jsme v kódu uvedli mereni.txt. Není to chyba, je to vlastnost :-) V souboru vidíme, že délka (počet řádů čísla) naměřeného času narůstá, zatímco teplota a vlhkost jsou stabilní. Právě zvětšování hodnoty času je důvodem, proč jsme v kódu použili všechny ty mezery a funkci substring().

Čtení dat z karty

Zapisovat hodnoty už umíme. Nyní je tedy čas vyzkoušet si i čtení dat. Na SD kartě si v počítači vytvoříme soubor KECTENI.TXT a zapíšeme do něj toto:

Test čtení Arduinem z SD karty
Nový řádek
itnetwork.cz

Text poté vypíšeme na sériový port. Kód bude vypadat skoro stejně. Jen smažeme část s DHT11, tvoření řetězce, upravíme otevírání souboru a přepíšeme kód zápisu:

#include <SD.h>

const int chipSelect = 53;

void setup()
{

  Serial.begin(9600);
  SD.begin(chipSelect);
  File soubor = SD.open("kecteni.txt");

  if(soubor)
  {
    int znaky = 0;
    while(soubor.available())
    {znaky++;
      Serial.write(soubor.read());
    }
    Serial.println("");
    Serial.println("Soubor ma " + String(znaky) + "znaku, vcetne mezer a newline znacek");
  }

  else
  {
    Serial.println("nepodarilo se otevrit soubor");

  }
}
void loop()
{

}

V kódu nejprve připravíme SD kartu. Poté otevřeme soubor, ale tentokrát bez parametru FILE_WRITE, protože budeme jen číst. Arduino čte tak, že přečte jeden znak a přejde k dalšímu. A navíc nám dá jen ASCII hodnotu přečteného znaku. Proto nepoužíváme Serial.print(), ale write(). Lze ale snadno získat i string, stačí nahradit část v podmínce touto úpravou:

int znaky = 0;
    String precteno = "";
    while(soubor.available())
    {
      znaky++;
      precteno += char(soubor.read());
    }
    Serial.print(precteno);
    Serial.println("");
    Serial.println("Soubor ma " + String(znaky) + "znaku, vcetne mezer a newline znacek");

Pomocí funkce char() dostaneme z přečtené hodnoty znak, který jen připojíme k textovému řetězci. Program nahrajeme, otevřeme sériový monitor a výstup bude vypadat následovně:

Čtení z SD karty Arduina - Arduino - Hardware

Z výstupu je zřejmé, že bude lepší se vyvarovat použití diakritiky :-) Zdrojové kódy jsou opět k dispozici ke stažení v příloze.

V příští lekci, Arduino - Využití I2C sběrnice, si vysvětlíme princip a možnosti I2C sběrnice.


 

Měl jsi s čímkoli problém? Stáhni si vzorovou aplikaci níže a porovnej ji se svým projektem, chybu tak snadno najdeš.

Stáhnout

Stažením následujícího souboru souhlasíš s licenčními podmínkami

Staženo 247x (2.48 kB)
Aplikace je včetně zdrojových kódů

 

Předchozí článek
Arduino - Komunikace přes Bluetooth
Všechny články v sekci
Arduino - Hardware
Přeskočit článek
(nedoporučujeme)
Arduino - Využití I2C sběrnice
Článek pro vás napsal Adam Ježek
Avatar
Uživatelské hodnocení:
13 hlasů
Autor se převážně věnuje Arduinu a psaní tutoriálů z této oblasti, občas napíše příležitostně nějakou tu zprávičku. Většinu svého volného času momentálně věnuje Linuxu a/nebo Raspberry Pi. Také umí C#, HTML, CSS, PHP a Python.
Aktivity