Shranjevanje podatkov na SD kartico

S senzorjem temperature LM35 bomo merili temperaturo v prostoru. Merilni rezultati se bodo prikazovali na serijskem monitorju, hkrati pa se bodo shranjevali na micro SD kartico. Podatke, shranjene na mikro SD (Secure Digital) kartici bomo uvozili v Excel in prikazali merilne rezultate na grafu.

Modul za pomnilniško kartico micro SD bomo priključili na Arduino Uno. Uporabili bomo pomnilniško kartico micro SD, 16 GB, SDHC (Secure Digital High Capacity).

Slika 1: Modul za pomnilniško micro SD kartico (vir: aliexpress)

Kratek opis SPI komunikacije:

Modul vsebuje 6 priključkov (slika 2), GND, Vcc, MISO, MOSI, SCK in CS. Z Arduino Uno komunicira preko SPI (Serial to Peripheral Interface) vodila. Vodilo SPI je strojno-programska komunikacija, ki jo je sredi 80. let 20. stoletja razvila Motorola, kasneje pa so jo povzeli tudi drugi industrijski proizvajalci elektronskih sklopov. Naprave na vodilu SPI delujejo v režimu nadrejen/podrejen (ang. master/slave), kjer nadrejena naprava skrbi za pretok podatkov po vodilu oz. krmili tok podatkov.

Slika 2: Oznaka priključkov modula za pomnilniško micro SD kartico (vir: aliexpress)

Vodilo SPI omogoča dvosmerno komunikacijo z eno ali več podrejenimi napravami. Pri tem uporablja štiri signalne linije:

Torej, na vodilu SPI imamo eno samo nadrejeno napravo. To pomeni, da centralna naprava vzpostavlja vse komunikacije s podrejenimi napravami. Kadar nadrejena SPI naprava želi poslati ali pridobiti podatke podrejene naprave, to stori tako, da najprej označi podrejeno napravo tako, da povleče pripadajočo SS linijo na nizko logično stanje in aktivira takt ure s frekvenco, ki je primerna tako za nadrejeno, kot tudi za podrejeno napravo. Nadrejena naprava generira podatke na MOSI signalni liniji, medtem ko jih vzorči na MISO signalni liniji. Podatkovni biti MOSI in MISO linij se spremenijo ob pozitivni fronti SCLK signala in se vzorčijo ob negativni fronti.

Slika 3: Prikaz SPI komunikacija (vir: https://cdn.sparkfun.com/assets/c/7/8/7/d/52ddb2dcce395fed638b4567.png)

Priključitev modula za pomnilniško kartico micro SD na razvojno ploščo Arduino Uno:

Uporabili bomo privreti knjižnici Arduino IDE za SD kartico in SPI komunikacijo (SD.h in SPI.h). Za naš uporabljen modul pomnilniške micro SD kartice in plošče Arduino Uno moramo priključiti modul na ustrezne pine Arduino Uno, kot prikazuje zgornja tabela, sicer naprava ne bo delovala. CS (chip Select) linijo moramo priključiti na pin 8 Arduino Uno.

V programu bomo uporabili ustrezne ukaze iz knjižnice, ki nam bodo na serijski monitor izpisale:

Slika 4: Podatki na serijskem monitorju, inicializacija uspešna

Slika 5: Podatki na serijskem monitorju, inicializacija ni uspela

Poglejmo sedaj program, ki bo poleg inicializacije meril temperaturo v °C in °F, izmerjene vrednosti prikazoval na serijskem monitorju in jih shranjeval na micro SD kartico. Na micro SD kartico naj se shranjujejo merilni podatki v kolonah in sicer naj bo merilni podatek v °C z vejico ločen od merilnega podatka v °F.

Program:

/*

 * Merjenje temperature s senzorjem LM35. Prikaz merilnih podatkov v °C in °F na serijskem monitorju

 * in shranjevanje merilnih podatkov na micro SD kartico.

 * Inicializacija SD kartice.

 * Avtor: Milan Ivič, februar 2016.

 */

 #include <SPI.h>        //Knjižnica za SPI komunikacijo.

 #include <SD.h>         //Knjižnica za SD kartico.

 //Spremenljivke, ki uporabljajo funkcije iz SD knjižnice:

 Sd2Card card;

 SdVolume volume;

 SdFile root;

 float tempC;             //Spremenljivka za temperaturo v °C.

 float tempF;             //Spremenljivka za temperaturo v °F.

 int tempPin = A0;        //Izhodni pin temp. senzorja LM35 je priključen na analogni vhod A0.

 //MicroSD kartica uporablja pin 8 za CS (chipSelect). To velja le za Arduino Uno.

 const int chipSelect = 8;

 File Temp;                   //Ime datoteke na micro SD kartici.

 void setup()

 {

   //Vkjučitev serijske komunikacije:

   Serial.begin(9600);

   Serial.print("\nInicializiranje SD kartice...\n");       //Sekvenca \n pomeni izpis v naslednjo vrstico.

   /*

    * Četudi pin 10 ni uporabljen za CS pin, strojna oprema SS pin pri ploščici

    * Arduino Uno zahteva, da je ta pin prosti in določen kot izhod. V nasprotnem

    * primeru knjižnica SD.h ne bo delovala

   */

   pinMode(10, OUTPUT);

   SD.begin(chipSelect);

 

   //Izvedemo inicializacijo da ugotovimo, ali kartica deluje pravilno:  

   if (!card.init(SPI_HALF_SPEED, chipSelect))         //Blok if stavka se izvede, če inicializacija ni uspela.

   {

     Serial.println("Inicializacija ni uspela, preverite naslednje:");

     Serial.println("Ali je kartica vstavljena?");

     Serial.println("Ali ste kartico pravilno povezali z Arduino Uno?");

     Serial.println("Ali se izbrani pin za chipSelect (CS) ujema z Arduino Uno?\n\n");

     return;

   }

   else        //Inicializacija uspešna.

   {

     Serial.println("Povezava je pravilna, SD kartica je zaznana.");

   }

   //Izpiši tip SD kartice:

   Serial.print("\nTip SD kartice: ");

   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("Nepoznano!");

   }

   //Preverimo zbirčni sistem, ta je lahko FAT16 ali FAT32:

   if (!volume.init(card))

   {

     Serial.println("Ni zaznana FAT16/FAT32 partician.\nSte prepričani, da ste formatirali SD kartico?");

     return;

   }

 

   //Izpis tipa in velikosti zbirčnega sistema:

   uint32_t volumesize;

   Serial.print("\Zaznan je FAT");

   Serial.println(volume.fatType(), DEC);

   Serial.println();

   volumesize = volume.blocksPerCluster();

   volumesize *= volume.clusterCount();

   volumesize *= 512;                                //Blok SD kartice vedno znaša 512 bajtov.

   Serial.print("Velikost (bajti): ");

   Serial.println(volumesize);

   Serial.print("Velikost (Kbajti): ");

   volumesize /= 1024;

   Serial.println(volumesize);

   Serial.print("Velikost (Mbajti): ");

   volumesize /= 1024;

   Serial.println(volumesize);

   Serial.println("\nNajdena datoteka na SD kartici (Ime, datum in velikost v bajtih): ");

   root.openRoot(volume);

   //Seznam vseh datotek na SD kartici z datumom in velikostjo:

   root.ls(LS_R | LS_DATE | LS_SIZE);

   Serial.print("\n\n");                            //Dve prazni vrstici.

 }

 void loop()

 {

   tempC = analogRead(A0);

   tempC = (5.0*tempC*100)/1024.0;                  //LM35 ima občutljivost 10 mV/°C, karakteristika je linearna.

   tempF = ((tempC*9)/5 + 32);                      //Pretvorba v °F (stopinje Fahrenheita).

  

   /*

     Odpiranje tekstovne datoteke z imenom Temp na micro SD kartici. Če je datoteka s tem imenom že kreirana, jo odpremo, da lahko vanjo

     zapisujemo. Če datoteke s tem imenom ni na micro SD kartici, se kreira.

   */

   Temp = SD.open("Temp.txt", FILE_WRITE);

   Serial.print("Temperatura: ");

   Serial.print(tempC);

   Serial.print(" ");

   Serial.print((char)42);

   Serial.print("C     ");

   Serial.print(tempF);

   Serial.print(" ");

   Serial.print((char)42);

   Serial.print("F");

   Serial.println();

   //Zapiši na micro SD kartico:

   Temp.print(tempC);

   Temp.print(",");

   Temp.println(tempF);

   Temp.close();                //Zapri tekstovno datoteko z imenom Temp na micro SD kartici.

 

   Temp.close();

   delay(30000);    //Počakaj 30 s.

 }

Ko končamo z meritvami temperature, micro SD kartico vstavimo v računalnik in odpremo datoteko Temp. Z vejicami ločeno so zapisane temperature v °C in v °F, kot prikazuje slika 6.

Slika 6: Merilni podatki na micro SD kartici

Sedaj odpremo Excel. Nato izberemo Datoteka > Odpri in v oknu, ki se odpre namesto Vse Exselove datoteke izberemo Vse datoteke:

Slika 7: Za odpiranje datoteke v Excelu izberemo Vse datoteke

Poiščemo našo datoteko Temp, ki se nahaja na micro SD kartici in kliknemo na Odpri. Pojavi se novo okno, kjer kliknemo na gumb Naprej. V novem oknu, ki se odpre pod izbiro Ločila izberemo Vejica:

Slika 8: V čarovniku za uvoz besedila pod Ločila izberemo Vejica

V tretjem koraku čarovnika za uvoz besedila pod Oblika podatkov v stolpcih izberemo Besedilo in kliknemo na gumb Dokončaj:

Slika 9: V čarovniku za uvoz besedila pod Oblik podatkov v stolpcih izberemo Besedilo

V dveh stolpcih imamo zapisane merilne podatke o izmerjenih temperaturah. Prvi stolpec prikazuje podatke v °C, drugi pa v °F.

Slika 10: Merilni podatki, ločeni v dveh stolpcih (Excel).

Nato označimo prvi stolpec (A) ter z bljižnično tipko Ctrl+H pike zamenjamo z vejico. Enako storimo za stolpec B:

Slika 11: Merilnim podatkom smo piko zamenjali z vejico

Sedaj lahko vstavimo graf, ki prikazuje spreminjanje temperature. V našem primeru se je temperatura izmerila vsakih 30 s.

Slika 12: Prikaz izmerjenih temperaturnih vrednosti na grafu