SD-Logger III. - Mit is mentsünk?
Az adatgyűjtő rendszerek kritikus pontja az adatmentés helye. Erre jelen esetben az SD kártya a legalkalmasabb, hiszen az egységnyi adatra jutó ára ennek a tárolótípusnak a legkedvezőbb. Összehasonlítva az egyéb memóriákkal:
Memóriakép | Típus | Ár |
---|---|---|
Belső EEPROM 128 byte ... 4096 byte |
Chip árában beépítve | |
I2C EEPROM 1 kbit (128 byte) ... 1024 kbit (128 kbyte) |
150..1.000 Ft/db | |
128 MByte .. 128 GByte | 1.000 .. 16.000 Ft |
Hát, az ilyen összehasonlítás nem vezet sehova :(. A mentendő adat oldaláról egyszerűbb megközelíteni. Itt sok adatot mentenénk és PC-re átvinnénk. Így az SD kártyára esett a választás. Az adatgyűjtőn egyszerű SD kártyafoglalat került kialakításra. Így átalakítóval akár uSD is illeszthető a rendszerhez.
Az SD-kártya nagyon nagy előnye - amit itt ki is használunk, - hogy olyan adathordozó, ami mind mikrokontrolleres környezetben, mind PC-s világban használható.
A háttértárunk mikrokontrollerrel írható-olvasható, míg a PC oldalon az adatok kinyerésére két lehetőségünk van:
- soros/usb porton át letöltve,
- kártyaolvasóval közvetlenül.
A soros letöltés során az adatátvitel 115.200 bps, azaz kb. 15 kbyte/sec. Az SD kártyáról közvetlenül olvasva ez 1-10 Mbyte/sec! Azaz 1 Mbye adat esetén közvetlenül néhány sec alatt, sorosporton jónéhány perc alatt lehetséges a letöltés. Így lehetőségként felmerül, hogy az Arduino a PC felé kártyaolvasóként jelentkezzen be. Azonban ez más processzort és más környezetet igényelne (pl. AT90USB128 chippel ez megvalósítható). Így inkább a kártyaolvasóra lenne szükség. Természetesen, - ha van beépített olvasónk a laptopunkban, - akkor az is használható.
Az Arduino oldalán az SD alapú adatgyűjtőhöz minimum ATMega328 chipre van szükség. Ez lehet a Mega panelek ATMega1280 vagy ATMega256 chipje is. Az ATMega168 illetve ATMega8 chippel az SD kártya - a kis belső memória miatt - nem kezelhető! A kisebb chipes rendszerek chipcserével egyszerűen feljeszthetőek (link). Az SD kezelés önmagában kb. 1kbyte SRAM-ot igényel!
Kártyaelőkészítés
A frissen vásárolt SD kárytát le kell formázni. Ennek során kerül létrehozásra az a logikai adattárolási rendszer, ami a mentett adatok olvashatóságát biztosítja a PC illetve a mikrokontrolleres környezetben. Előfordul, hogy a kártyánk már gyárilag formázott. Ebben viszont sosem lehet megbízni, hogy milyen logikai rendszerben sikerült a gyárban elvégezni. Az SD kártyákat FAT16 vagy FAT32 rendszerben tudjuk használni. Fontos! A 32 MB-nál kisebb kártyák FAT12-ben kerülnek formázásra, azaz ezen a módon formázott kártyák mikrokontrolleres környezetben nem használhatóak!A formázásnál a kártya tartalma elveszik, így ha fényképek vagy MP3 gyűjtemény van rajta, akkor előtte menteni kell!
Fontos! Az SD kártyán nem lehet fizikai vagy logikai hiba (ún. Bad sector). A PC-s világgal ellentétben, nincs hibajavító-hibakezelő algoritmus!
A formázásra több lehetőség is kínálkozik. A legegyszerűbb az operációs rendszerbe beépítettet használni - igaz itt sokminden nem állítható, de nem is szükséges. Ha tudni akarjuk, mi van a háttérben, akkor hardware-közeli megoldásokat is találhatunk a gyártók oldalán vagy az sdcard.org oldalon. Például: https://www.sdcard.org/downloads/formatter_3/
Beszélgessünk a kártyával
Az SD kártyák kezelésére számos függvénykönyvtárat találhatunk az interneten szétszórva. Azonban a legegyszerűbb az Arduino eredetileg már beépített eljárásgyűjteményét használni. Az Arduinoban az 1.x kiadásokban ez a Library-SD - Examples alatt található. A régebbi (Arduino-00xx) rendszerek esetén ezeket még külön kellett összeszedegetni.
Ha ilyen külön fellelhető letölthető függvénykönytárat keresünk, akkor ezek a github oldalán, az vagy az adafruit lapjain is megtalálhatóak. Ezen eljárások használata azonban csak akkor javasolt, ha valamely program külön igényli! Sok inkompatibilis, verziófüggő kiadás kering mindenfelé, - melyek során a keretrendszer verziószáma, a fordítandó mintaprogram és járulékos függvénykönyvtárak kölcsönös függőségei is problémát okozhatnak.
Az Arduino Mega rendszerek esetén az SPI busz kezelése (amin át a kártya csatlakozik) eltérő. Ennek oka, hogy a korai rendszerek hardware kimenetei csak részben feleltethetőek meg az új rendszerekkel. Míg a soros kommunikáció, analóg kivezetések a helyükre kerülhettek, addig az SPI busz, az I2C/wire nincs fedésben. Ilyen "áthelyezett" esetekben van mód pl. szoftveres emulációra.
Az SPI esetén a paraméterek közt az SDCard.h állományban lehet ezt beállítani.
Arduino alatt a kártyák megszólítása az SDCardInfo programmal a legegyszerübb. Ez a minta semmit sem ír a kártyára, csak megpróbálja a kapott válaszokat értelmezni és a képernyőre kiirni. Előnye, hogy bármilyen SD kártyával együttműködik.
/* SD card test (c) TavIR http://www.tavir.hu This example shows how use the utility libraries on which the'' SD library is based in order to get info about your SD card. Very useful for testing a card when you''re not sure whether its working or not. The circuit: ** SD card attached to SPI bus as follows: ** MOSI - pin 11 on Arduino Uno/Duemilanove/Diecimila ** MISO - pin 12 on Arduino Uno/Duemilanove/Diecimila ** CLK - pin 13 on Arduino Uno/Duemilanove/Diecimila ** CS - depends on your SD card shield or module. (Pin 8) Tested via Arduino 1.0.2 Founded at arduino.cc forum Modified 12 March 2013 by TavIR / Robert Cseh This example code is in the public domain. */ // include the SD library: #include <SD.h> // set up variables using the SD utility library functions: Sd2Card card; SdVolume volume; SdFile root; // change this to match your SD shield or module; // SDLogger shield: pin 10 const int chipSelect = 10; void setup() { Serial.begin(9600); Serial.print("\\nInitializing SD card..."); // On the SD Logger shield, CS is pin 10. pinMode(10, OUTPUT); // change this to 53 on a mega // 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 is inserted?"); Serial.println("* Is your wiring correct?"); Serial.println("* did you change the chipSelect pin?"); return; } else { Serial.println("Wiring is correct and a card is present."); } // print the type of card Serial.print("\\nCard 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."); Serial.println("Make sure you''ve formatted the card"); return; } // print the type and size of the first FAT-type volume uint32_t volumesize; Serial.print("\\nVolume type is FAT"); Serial.println(volume.fatType(), DEC); Serial.println(); volumesize = volume.blocksPerCluster(); // clusters are collections of blocks volumesize *= volume.clusterCount(); // we''ll have a lot of clusters volumesize *= 512; // SD card blocks are always 512 bytes Serial.print("Volume size (bytes): "); Serial.println(volumesize); Serial.print("Volume size (Kbytes): "); volumesize /= 1024; Serial.println(volumesize); Serial.print("Volume size (Mbytes): "); volumesize /= 1024; Serial.println(volumesize); Serial.println("\\nFiles found on the card: "); root.openRoot(volume); // list all files in the card with date and size root.ls(LS_R | LS_DATE | LS_SIZE); } void loop(void) { }
A programkód elején találjuk meg a chipselect kezelését. Ez az a jelzőláb, amivel az adott eszköz felé jelezhetjük, hogy vele akarunk beszélgetni. Az SPI buszon az értékes kommunikációs csatornán nem történik eszközkiválasztás. - ott csak az adatcsere zajlik! (Az I2C/TWI buszon az adatcsere és az eszközkiválasztás is közös felületen történik - csökkentve a sávszélességet). Az SD Logger kártyán a kiválasztásra a D10-es kivezetést használja a shield, míg ha ethernet kártyát használunk, akkor az SD kiválasztása a D4 kivezetésen át zajlik.
Ha a programkódot megnéztük és átmásoltuk az Arduino keretrendszerbe, akkor a fedpanelbe helyezve az SD-kártyát, majd feltöltve a kódot - ellenőrihetjük a működést. Megnyitva a terminálablakot (jobb felső ikon) a sebességet jobbra lenn át kell állítani 9600 bps-re. A mintakód ilyen gyorsan küldi az adatokat. A képernyőn valami ilyesmit kell látnunk:
A FAT16 és FAT32 is szépen látszik. (Amin teszteltem, az egy 2 GB-s Kingston és egy 8 GB-s Samsung volt.)
Ha hibás vagy nem FAT16/FAT32 formázott kártyát sikerül tesztelni, akkor erre a program hibaüzenetet ad (Próbáld ki: vedd ki a kártyát és úgy tesztelj!).
A kártyák minden esetben válaszolnak a megszólításra: kivéve, ha hibásak vagy a chipselect kiválasztása nem a megfelelő lábon történik. Az alap megszólítás a kártya gyártójának lekérdezése. Ez a kártyákban fixen "drótozott", és még a logikai filerendszer alatti szinten mozog. Így lehet a kártya akár ext2/3, NTFS formázott is.
A legtöbb kártyahiba egyszerűen orvosolható egy formázással. Első kísérletként az operácós rendszer beépített formázójával érdemes megpróbálni. Ha nem sikerül, akkor a cikk elején emlegetett speciális formázóprogramokkal kell megpróbálni a "kezelését".
Bascom-AVR
A Bascom-AVR keretrendszerben a követlmények azonosak, mint az Arduino esetén: ATMega328, ATMega1280 vagy ATMega2560 chip. A szoftver oldala azonban már kérdéses...
Bascom-AVR alatt kétféle SD kártya kezelési megoldás létezik: az AVR-DOS és a KokkeKat FAT. Az AVR-DOS a klasszikus és a kiforrottabb. Fontos! Ha a szoftverrel pénzt keresünk, akkor az AVR-DOS könyvtárrendszer jogdíjköteles!
A kártya előkészítése az Arduinonál megismert módon történik és FAT16 vagy FAT32 szerkezetű lehet. A Bascom-AVR hardware-közeli megoldása miatt programkódban is több beállítási lehetőségünk van. A részleteket a bascom súgó illetve az eredeti forráskód is szépen körbejárja. Itt most lássuk a könyvtárszerkezet kilistázását:
''********************************************* ''* Title: Test_DOS_Drive * ''* About: Tesing filesystem via AVR-DOS * ''* and ATMega chips * ''* Filename: Test_DOS_Drive.bas * ''* Compiler: Bascom-AVR 2.0.7.5 * ''* * ''* Author: Robert Cseh * ''* E-mail: avr /kukac/ tavir /pont/ hu * ''* Homepage: http://www.tavir.hu * ''********************************************* $regfile = "m328pdef.dat" $crystal = 16000000 '' Adjust HW Stack, Soft-Stack and Frame size to 128 minimum each!!! $baud = 9600 Open "Com1:" As Binary As #1 Config Clock = Soft Enable Interrupts Config Date = Mdy , Separator = . Dim Btemp1 As Byte Print #1 , "Wait for Drive" ''Include here you driver for Compactflash/HardDisk or other ''$include "Config_MMCSD_HC.bas" $include "Config_MMC.bas" If Gbdriveerror = 0 Then '' Include AVR-DOS Configuration and library $include "Config_AVR-DOS.BAS" Print #1 , "Init File System ... "; Btemp1 = Initfilesystem(1) '' Partition 1 '' use 0 for drive without Master boot record If Btemp1 <> 0 Then Print #1 , "Error: " ; Btemp1 ; " at Init file system" Else Print #1 , " OK" Print #1 , "Filesystem: " ; Gbfilesystem Print #1 , "FAT Start Sector: " ; Glfatfirstsector Print #1 , "Root Start Sector: " ; Glrootfirstsector Print #1 , "Data First Sector: " ; Gldatafirstsector Print #1 , "Max. Cluster Nummber: " ; Glmaxclusternumber Print #1 , "Sectors per Cluster: " ; Gbsectorspercluster Print #1 , "Root Entries: " ; Gwrootentries Print #1 , "Sectors per FAT: " ; Glsectorsperfat Print #1 , "Number of FATs: " ; Gbnumberoffats End If Else Print #1 , "Error during Drive Init: " ; Gbdriveerror End If End
A feltöltés után a program futni kezd és megmutatja a kártya tartalmát:
Fontos! A Bascom-AVR alatt, ha nagyméretű kártyát akarunk kezelni (>2GB), akkor a program elején a $include "Config_MMCSD_HC.bas" sort kell engedélyezni. A teljes mintakódot a feltelepített Bascom-AVR: Samples és AVRDOS könyvtárában találjuk.
Kapcsolódó leírások:
Kapcsolódó áramkörök:
TavIR-Facebook