13. díl - Arduino a SD karta

Hardware PC Arduino 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.

Ukládání na SD kartu v Arduino

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í:

Čtení z SD karty Arduina

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.


 

Stáhnout

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

 

  Aktivity (1)

Článek pro vás napsal Adam Ježek
Avatar
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.

Jak se ti líbí článek?
Celkem (1 hlasů) :
55555


 


Miniatura
Předchozí článek
Arduino - Jazyk 2
Miniatura
Všechny články v sekci
Arduino
Miniatura
Následující článek
Arduino - Komunikace přes Bluetooth

 

 

Komentáře

Avatar
Petr Mutina
Člen
Avatar
Petr Mutina:

Málem jsem už rozebral celý Arduino, kde je chyba, ale nakonec jsem si toho všiml. :D Máš v té tabulce prohozený piny "MISO" a "MOSI". Viz.: http://arduino.cc/…eference/SPI

 
Odpovědět  +2 7.1.2015 13:30
Avatar
Adam Ježek
Tým ITnetwork
Avatar
Odpovídá na Petr Mutina
Adam Ježek:

Díky, editace odeslána ke schválení

Odpovědět 7.1.2015 19:00
Pokud chceš odpovědět, klikni na odpovědět. Pokud chceš vložit zdroják, klikni na vložit zdroják (</>)
Avatar
Neaktivní uživatel:

Není na tomto návodu něco špatně? Podle specifikací k SD kartě mají mít signálové cesty max. 3.6 V, ale Arduino pracuje s 5V logikou (leda by mělo výstupy s otevřeným kolektorem). Zapojení odkazovaných modulů bohužel řeší stabilizátorem pouze napájení... Čekal bych mezi Arduinem a SD modulem ještě i převodník napěťových úrovní 5V <-> 3.3V.

Odpovědět 15.9.2015 19:13
Neaktivní uživatelský účet
Avatar
Adam Ježek
Tým ITnetwork
Avatar
Odpovídá na Neaktivní uživatel
Adam Ježek:

Nejspíše bude nějaký odpor na snížení napětí přímo v modulu, já jí používám normálně na 5V a stále funguje

Odpovědět 15.9.2015 19:35
Pokud chceš odpovědět, klikni na odpovědět. Pokud chceš vložit zdroják, klikni na vložit zdroják (</>)
Avatar
Odpovídá na Neaktivní uživatel
Michal Žůrek (misaz):

v akademické rovině je to problém a máš pravdu, v praxi však taky k diodám nedávám žádný rezistor a fungují stále. To bude podobné.

Odpovědět 15.9.2015 21:09
Nesnáším {}, proto se jim vyhýbám.
Avatar
Neaktivní uživatel:

A máš právě ten v článku odkazovaný modul na SD kartu, nebo jiný typ na mikro SD kartu? Právě moduly s mikro SD kartou totiž obsahují v signálové cestě obvod LVC125A - jde o jakýsi čtyřnásobný multinapěťový buffer. Nestudoval jsem to podrobně, ale co když právě on tahle rozdílná napětí řeší?

Odpovědět 16.9.2015 4:42
Neaktivní uživatelský účet
Avatar
Adam Ježek
Tým ITnetwork
Avatar
Odpovídá na Neaktivní uživatel
Adam Ježek:

Odkaz je na hledani na ebayi, tam sou vsechny, ale prevazuji pro klasickou SD.
A jak uz rekl misaz, funguje to i bez toho.

Odpovědět 16.9.2015 7:45
Pokud chceš odpovědět, klikni na odpovědět. Pokud chceš vložit zdroják, klikni na vložit zdroják (</>)
Avatar
Petr Mutina
Člen
Avatar
Petr Mutina:

Nechci být detailista, ale překontroluj si ještě jednou tu tabulku. Co bych dal za to, kdyby mělo ne-Mega Arduino 15 digitálních pinů! :D

 
Odpovědět  +1 3.10.2015 12:34
Avatar
Adam Ježek
Tým ITnetwork
Avatar
Odpovídá na Petr Mutina
Adam Ježek:

Ale já už to opravoval v lednu, o pár komentářů vejš to je :D

Odpovědět 3.10.2015 12:37
Pokud chceš odpovědět, klikni na odpovědět. Pokud chceš vložit zdroják, klikni na vložit zdroják (</>)
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 9 zpráv z 9.