Lekce 13 - Arduino a SD karta
V tomto díle si k Arduinu připojíme SD kartu. Na ukázku použijeme SD card module. Pokud máte nějaký shield, který v sobě má slot na SD kartu, tak ten lze také použít, ale je tu pár detailů, ty zmíním později.
SD kartu můžeme použít kteroukoli, která je formátována na FAT nebo FAT32. Ovšem nebudeme formátovat pomocí nástrojů v OS, ale použijeme SD formatter (Více zde). Takže, máme modul, máme SD kartu naformátovanou na FAT32 pomocí SDformatteru. Co dále?
Připojení
Na modulu máme piny GND, 5V (snad netřeba vysvětlovat), MISO, SCK(/CLK), MOSI, CS. Bohužel je nemůžeme připojit jak se nám zlíbí. Pokud vám piny MISO, SCK, MOSI připomínají piny z lekce s programováním ATmegy, tak máte pravdu, musíme použít tyto.
MEGA | ne-MEga | |
MOSI | 51 | 11 |
SCK | 52 | 12 |
MISO | 50 | 15 |
CS | 53 | 4 |
Pokud máte MEGA, zapojte dle prvního sloupečku. Pokud ne (např. UNO), použijte druhý. Pokud máte shield se slotem, tak nejspíše s Arduinem MEGA fungovat nebude (pokud má vývody k pinům 50-53 a je na nich slot, tak bude). Zjistěte si, na který pin je přiveden CS.
Než začneme, ověříme si funkčnost SD karty. Připojte ji, otevřete IDE a File -> Examples -> SD -> CardInfo. SD knihovna je již součástí IDE. V kódu hned nad setupem najdete řádek
const int chipSelect = 4;
Pokud máte MEGA, přepište hodnotu na 53. Pokud máte shield, použijte pin, na kterém je CS. Ostatních se to netýká. Kód nahrajte do Arduina s připojenou kartou, otevřete Serial Monitor (Ctrl+shift+M) a pokud uvidíte něco jako
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):
SYSTEM~1/ 2015-01-03 10:57:36
INDEXE~1 2015-01-03 10:57:36 76
MERENI.TXT 2015-01-03 15:11:00 30240
KECTENI.TXT 2015-01-03 15:21:24 1925
máte vyhráno. Pokud něco jako
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?
zkontrolujte vedení, kartu, ochranu proti přepisu. Pak vás může překvapit třeba ještě chyba typu
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
to se vraťte na začátek článku a přečtete si, co jsem psal o formátování.
Pokud vám byla vypsána velikost, souborový systém, popřípadě soubory, nic nám nebrání pokračovat.
Zápis
Co si připojit k Arduino DHT11, které již známe a ukládat data z něj na SD kartu?
Takže začneme tím, že naimportujeme knihovny:
#include <dht11.h>
#include <SD.h>
Vytvoříme jíž známé DHT11:
dht11 cidlo;
int dht11Pin = 7;
A nyní inicializujeme SD kartu:
const int chipSelect = 53; //nezapomeneme patřičně upravit
void setup()
{
SD.begin(chipSelect);
}
Pustíme se do loopu. Začneme tím, že si vytvoříme string dat k uložení:
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 teplotu, vlhkost a do cas uložíme počet milisekund od spuštění. Možná vás překvapí, proč za string přidávám to velké místo a funkce substring(). Jde o to, že funkce substring() vezme ze stringu určitou část, např. z času vezmeme jen 0 až 16-tý znak(indexování od nuly). Záměr uvidíte za chvíli. Nyní nám zbývá otevřít soubor pro zápis:
File soubor = SD.open("mereni.txt", FILE_WRITE);
To uděláme pomocí funkce SD.open. File je proměnná, do které se soubor uloží, dáme jí jméno soubor. Otevřeme soubor mereni.txt a budeme zapisovat. Pokud soubor neexistuje, vytvoří jej. Pokud existuje, připíše do něj. A pokud se otevření podaří, tak do něj zapíšeme a zavřeme.
if(soubor)
{
soubor.println(data);
soubor.close();
}
delay(1000);
}
Je důležité mít na paměti soubor co nejrychleji uzavřít a že nikdy nemůžeme mít otevřeno více souborů naráz.
Do Arduina tedy nahrajeme toto:
#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, necháme chvíli běžet a poté kartu jednoduše vyjmeme a otevřeme v počítači.

Toto bude zhruba výsledek. Podívejte se, jak je rozdílná délka času, ale teplota a vlhkost jsou stále ve stejném sloupečku - proto ty mezery a substring. Všimněte si, že ačkoliv jsme Arduinu řekli, že chceme mereni.txt, dostali jsme MERENI.TXT.
Čtení
No dobrá, zapisovat umíme. Ale co třeba něco přečíst? Vytvořme si na SD kartě soubor KECTENI.TXT a zapišme do něj třeba toto:
Test čtení Arduinem z SD karty
Nový řádek
itnetwork.cz
A text poté vypíšeme na sériový port. Kód bude vypadat skoro stejně, jen smažeme část s DHT11, tvoření stringu, 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 připravíme SD kartu, 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
tohoto znaku. Proto nepoužíváme Serial.print(), ale write(). Lze ale snadno
získat i string, stačí nahradit část v ifu:
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í char() dostaneme z přečtené hodnoty znak, který jen připojíme ke stringu. Program nahrajeme, otevřeme Serial Monitor a výstup by měl být následující:

Jak vidíte, tak není zrovna ideální používat háčky a čárky.
Pokud vám něco nefunguje, zkontrolujte zapojení, CS pin,... jako předtím.
Zdrojové kódy jsou opět k dispozici ke stažení v příloze.
Měla 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 205x (2.48 kB)
Aplikace je včetně zdrojových kódů
Komentáře


Zobrazeno 9 zpráv z 9.