SD kártya eltávilítása és újrainicializálása

Processing/Wiring (illetve C) nyelvű programozási fogások, tippek. (AVR-Duino, Arduino, EthDuino, Diecimila, Severino, Nano, LilyPad)
bagizoltan
Bitmanipulátor
Hozzászólások: 128
Csatlakozott: 2015. december 8. kedd, 19:52

SD kártya eltávilítása és újrainicializálása

Hozzászólás Szerző: bagizoltan »

Sziasztok!

SD kártya kezelésben kérnék segítséget.
CATALEX MicroSd kártyafoglalatot szeretnék használni. A letöltött példaprogram tökéletesen fut. A példa programban az Arduino Uno R3 8-as lábáról kapja a kártya foglalat a tápfeszültséget. A csak a setup-ban csinált valamit. Ebből az áttekinthetőség miatt a csatolt kódrészletben csak az inicializálást és egy file létezésének ellenőrzését hagytam benne. A loop-ban nem történik semmi.

Annyit szerettem volna változtatni a példa programon, hogy miután lefutott a setup rész, lekapcsolom a tápfeszt, azaz LOW-ba teszem azt a kimenetet, amiről a kártya a tápfeszt kapja. Kis idő múlva (2 sec) újra bekapcsolom a tápfeszét, és újra végrehajtok mindent elölről, de most már a loop-ban ciklikusan ismételgetve. Pontosabban csak egy inicializálást akartam csinálni, de már az sem fut le. Arra szerettem volna használni az SD-kártyát, hogy naponta néhány alkalommal ráírok valamit. Közben bármikor kivenném a kártyát és PC-n leolvasom, törlöm , és visszadugom a helyére. Ezért szeretném két írás között kikapcsolni a tápfeszt! Ha közben a program épp írni akarna rá, akkor nem sikerül végrehajtani az SD.begin()-t, így a program tovább fut és majd pár óra múlva újra megpróbálja.
Meg tudná mondani valaki, Miért nem lehet ki-be kapcsolgatni a tápfeszt és újra kiadni az SD-begin()-t?

Köszönettel!

Bagi

Itt az általam módosított kód aminek csak a loop része nem működik:
#include <SD.h>

void setup()
{
Serial.begin(9600);
Serial.print("SD kartya inicializalas...");
pinMode(8, OUTPUT);
digitalWrite(8, HIGH);
if (!SD.begin(10)) {
Serial.println("sikertelen inicializalas!");
return;
}
Serial.println("sikeres inicializalas.");
if (SD.exists("example.txt")) {
Serial.println("example.txt letezik.");
} else {
Serial.println("example.txt nem letezik.");
}
digitalWrite(8, LOW);
delay(2000);
}

void loop()
{
digitalWrite(8, HIGH);
if (!SD.begin(10)) {Serial.println("sikertelen inicializalas!");}
else {Serial.println("sikeres inicializalas.");}
digitalWrite(8, LOW);
delay(5000);
}
Avatar
Robert
Elektronbűvölő
Hozzászólások: 10191
Csatlakozott: 2005. december 9. péntek, 7:00

Re: SD kártya eltávilítása és újrainicializálása

Hozzászólás Szerző: Robert »

A tápfesz ráadás és a chip inicializálás közé tegyél be néhány*100msec várakozást. Az SD kártya önmaga is életre kell hogy kelljen, nem azonnal ébred fel.
Hiányzik az sd.flush() - függőben levő írások befejezése.
A 10-es lábra nem mondtad meg, hogy output legyen! (setup() részen)

Valamint erre a funkcióra inkább az oldalt levő két érntkező/kapcsoló szolgál: Van-e benn SD kártya illetve írásvédett-e az SD kártya.
A korrekt megoldás:
If (benn van a kártya) { if (nem írásvédett a kártya) {na itt írhatok ki, és jelzem LEDdel, hogy ne huzogasd a kártyát;}}
bagizoltan
Bitmanipulátor
Hozzászólások: 128
Csatlakozott: 2015. december 8. kedd, 19:52

Re: SD kártya eltávilítása és újrainicializálása

Hozzászólás Szerző: bagizoltan »

Szia!

Kipróbáltam szinte mindent amit mondtál! Alább találod a módosított programot, ami szintén nem működik. A forrás alá bemásoltám a futási eredményt is a serial monitorból!
SD.flush()-ra hibát dobott a fordító, szerintem ez csak file névvel létezik pl.: filenev.flush(). Mivel file-t nem nyitottam, nyilván értelmetlen a programban.
Van itt valami, ami nem úgy működik ahogyan feltételezem! Lehetséges, hogy az SD.begin() csak a setup-ban adható ki?

Ezt a pár sort a válaszodban nem értem pontosan:
Valamint erre a funkcióra inkább az oldalt levő két érntkező/kapcsoló szolgál: Van-e benn SD kártya illetve írásvédett-e az SD kártya.
A korrekt megoldás:
If (benn van a kártya) { if (nem írásvédett a kártya) {na itt írhatok ki, és jelzem LEDdel, hogy ne huzogasd a kártyát;}}
Mi az a két érintkező? EWzt is le lehet valahogyan kérdezni? Erre való függvényt nem találtam az SD osztályban!


Köszönöm!

Bagi


A forrás:

Kód: Egész kijelölése

#include <SD.h>

void setup()
{ 
  Serial.begin(9600);
  Serial.print("SD kartya inicializalas...");
  pinMode(10,OUTPUT);
  pinMode(8, OUTPUT);
  digitalWrite(8, HIGH);
  if (!SD.begin(10)) {
    Serial.println("sikertelen inicializalas!");
    return;
  }
  Serial.println("sikeres inicializalas.");
  if (SD.exists("example.txt")) {
    Serial.println("example.txt letezik.");
    } else {
    Serial.println("example.txt nem letezik.");
  }
  digitalWrite(8, LOW);
  delay(1000);
}

void loop()
{
  digitalWrite(8, HIGH);
  delay(1000);
  if (!SD.begin(10)) {Serial.println("sikertelen inicializalas!");}
  else {Serial.println("sikeres inicializalas.");}

  digitalWrite(8, LOW);
  delay(1000);  
}
Eredmény:
SD kartya inicializalas...sikeres inicializalas.
example.txt letezik.
sikertelen inicializalas!
sikertelen inicializalas!
Avatar
Robert
Elektronbűvölő
Hozzászólások: 10191
Csatlakozott: 2005. december 9. péntek, 7:00

Re: SD kártya eltávilítása és újrainicializálása

Hozzászólás Szerző: Robert »

A szabványos SD foglalaton ott a két érintkező. Miért kéne függvénykönyvtár rá? Bár igaz a LED.on() és a LED.off() meg a LED.init() is megvan a D13 LEDre :)

A digitalWrite(8, HIGH); után tegyél be egy delay()-t!


Google-ban reinit SD Aruino->
http://forum.arduino.cc/index.php?topic=66415.0
Az SD kártya lezárása a root.close() utasítással lenne....
Tesztelni nem tudtam....
http://www.tavir.hu - a gazda :)
bagizoltan
Bitmanipulátor
Hozzászólások: 128
Csatlakozott: 2015. december 8. kedd, 19:52

Re: SD kártya eltávilítása és újrainicializálása

Hozzászólás Szerző: bagizoltan »

Szia!
Elolvastam alaposabban! Sajnos az ottani fórumozónak ugyanaz a problémája mint nekem. A végén azt írja, hogy megoldódott, de nem világos, hogy mitől?!
Közben kipróbáltam, hogy a setup-ban lévő részt átépítettem a loop-ba. Természetesen az van amit vártam: egyszer lefut, de többször nem! Várakozásokat természetesen beépítettem az általad javasolt helyekre.

Letöltöttem az Sdfat lib-et is, mert az általad talált fórumon valaki azt írta, hogy talán ez működik. Sajnos nagyon más a példa programok kinézete, így még nem értem a működésüket. Nagyon C++-os, és ebjektum orientált! Bőven 15-20K körül vannak a legkisebb példák is :-(
A csatolt példák minden esetre működnek, de olyat még nem találtam, ahol többször is megnyit egy kártyát. Sebaj, még keresem!

Más:
Bocs, de még mindig nem értem amit az érintkezőkről írtál. Van egy kártyám sok érintkezővel! Eddig OK! Bedugom a foglalatba, amin már csak a szokásos kivezetések vannak: Vcc, Gnd, Miso, Mosi Cs, Clk (CATALEX modul). Hol van még itt érintkező? Nem látok az SD modulon semmi plusz kivezetést!?

Köszi

Bagi
Avatar
Robert
Elektronbűvölő
Hozzászólások: 10191
Csatlakozott: 2005. december 9. péntek, 7:00

Re: SD kártya eltávilítása és újrainicializálása

Hozzászólás Szerző: Robert »

Belenézve a sd.h és sd.cpp-be:

Kód: Egész kijelölése

boolean SDClass::begin(uint8_t csPin) {
  /*

    Performs the initialisation required by the sdfatlib library.

    Return true if initialization succeeds, false otherwise.

   */
  return card.init(SPI_HALF_SPEED, csPin) &&
         volume.init(card) &&
         root.openRoot(volume);
} 
Azaz: az init-kor megnyitottad már a kártyát. És NINCS bezérva, hogy eltávolíthasd. Ezért nem is tutod újrainicializálni. Ehhez a root-ot be kellene csukni. Viszont ez a funkció nincs implementálva itt.
A rendszerben kicserélhető _önálló_ SD kezelésre (TinyFAT vagy egyéb), amiben ez benne van....
http://www.rinkydinkelectronics.com/library.php?id=37 - TinyFAT (max 2GB)
Itt a teljes INIT megtörténik (alacsony szintű kártyainit is!)
http://www.tavir.hu - a gazda :)
Avatar
Robert
Elektronbűvölő
Hozzászólások: 10191
Csatlakozott: 2005. december 9. péntek, 7:00

Re: SD kártya eltávilítása és újrainicializálása

Hozzászólás Szerző: Robert »

SD-pino.jpg
Itt alul a 2 érintkező: WP - Write Protect és a CD (Vagy CP) - Card Detect (Card Present)

És kezelés szerint neked a CP kellene, azaz a card present.
SD schematic.png
De az előző miatt, hogy nem implementált a kártya leválasztása - ez sem segít rajtad....


DE van az Adafruit SD eljáráskönyvtár, és ebben (SD.cpp):

Kód: Egész kijelölése

void SDClass::end() 
{ 
  root.close(); 
} 
Ez kell neked!
Forrás: https://github.com/adafruit/SD
Nincs meg a kellő jogosultságod a hozzászóláshoz csatolt állományok megtekintéséhez.
http://www.tavir.hu - a gazda :)
bagizoltan
Bitmanipulátor
Hozzászólások: 128
Csatlakozott: 2015. december 8. kedd, 19:52

Re: SD kártya eltávilítása és újrainicializálása

Hozzászólás Szerző: bagizoltan »

Szia!

Megtaláltam a megoldást kísérletezgetéssel! Alább a kód lényeges részei (bocs, de van benne az ügy szempontjából lényegtelen LCD kezelés is, lusta voltam kigyomlálni)! A lényeg az, hogy a setup részben meghívom az SD.begin()-t. Ez után még a tápfeszt is lekapcsolom.
A loop-ban felkapcsolom a tápfeszt, újra meghívom az SD.begin()-t, ami persze hibát dob, így már le sem vizsgálom a visszatérési értékét. Ezt követően megnyitom (vagy létrehozom) a file-t. Beleírok, lezárom és a végén lekapcsolom a tápfeszt.
A kártya bármikor kivehető és visszarakható. A megkezdett file folytatódik. Attól sem akad ki, ha egy file írási ciklus netán kimaradna, mert éppen nincs benne a kártya. Arra nyilván vigyázni kell, hogy ne pont akkor dugjam be vagy húzzam ki, amikor éppen írnám.

Ami megoldotta a problémát, az a loop-ba bekerülő SD.begin() és az, hogy a tápfesz be és kikapcsolásakor várok 100msec-et. Ezek nélkül nem működik, ami abban nyilvánul meg, hogy az új adatokat nem írja hozzá a file-hoz mindaddig, amíg egy reset-el újra nem indítom az Arduino Uno-t.

A végleges programban arra gondoltam, hogy lesz egy nyomógomb, amit megnyomok a kártya kivétele előtt, és újra megnyomom amikor visszaraktam. A program ezen idő alatt békén hagyja a kártyát. Azt nem tudom eldönteni, hogy a tápfeszt le és felkapcsoljam-e az egyes írások között, vagy csak akkor, amikor épp kiveszem a kártyát. Árthat a kártyának a folyamatos fel és lekapcsolgatás?

Egyébként kipróbáltam tápfesz kapcsolgatás nélkül is, ekkor is jól működik, tehát a trükk az SD.begin() meghívása minden file nyitás előtt! Azt nem tudom, a kártyának árthat-e, ha bekapcsolt tápfesz esetén húzogatom ki.

Köszönöm a kivezetés képeket! Már értem mit nem értettem! A CATALEX modulon ezek nincsenek kivezetve, és nem is hozzáférhetők, mert a kártya foglalat borító lemeze letakarja a saját érintkezőit.

Köszi a segítséget!

Bagi

És itt a kódrészlet:
Megjelöltem a lényeges részeket!

Kód: Egész kijelölése

void setup() {
  pinMode(2, INPUT);
  Wire.begin();  // I2C busz használat indítása
  getTime(); 
  temperature=getTemperature();
  date_format();
  time_format();
  pinMode(SD_POWER, OUTPUT);
  //------------------------------------------
  digitalWrite(SD_POWER, HIGH);  
  delay(100);
  if (SD.begin(10)) {error="SD Ok!";}
  else {error="No SD";}
  delay(100);
  digitalWrite(SD_POWER, LOW);
  //-----------------------------------------
  lcd.begin(16,2); //LCD inicializálása
  lcd.backlight();      //háttérvilágítás bekapcsolása
  lcd.print(error);
  delay(3000);
  lcd.noBacklight();
}

void loop() {
  if (digitalRead(2)==LOW) {lcd.backlight();light_ido=millis();}
  if (millis()>rogz_ido+10000){
    getTime(); 
    temperature=getTemperature();
    digitalWrite(SD_POWER, HIGH);
    delay(100);
    date_format();
    time_format();
  //-----------------------------------------
    SD.begin(10);
    if (!SD.exists(filenev)) {
      temp_adat = SD.open(filenev, FILE_WRITE);
      temp_adat.println("Datum;Ido;Homerseklet;");
      error="C";
    }
    else {  
      temp_adat = SD.open(filenev, FILE_WRITE);
      error="O";    
    }      
    temp_adat.print(datum+";"+ido+";");
    temp_adat.print(temperature);
    temp_adat.println(";");
    temp_adat.flush();
    temp_adat.close();
    delay(100);
    digitalWrite(SD_POWER, LOW);
  //-----------------------------------------
    lcd.backlight();
    lcd.setCursor(14,1);
    lcd.print(error);
    rogz_ido=millis();
    light_ido=millis();
  } 
  if (millis()>light_ido+5000){
    lcd.setCursor(14,1);
    lcd.print(" ");
    lcd.noBacklight();
  }
  if (millis()>lepes+1000) {
    getTime();            //kiolvassuk az időt a DS3132-ből a "masodperc, perc, ora, het_napja, nap, honap, ev" változókba
    if (elozoperc!=perc) {
      date_format();
      time_format();
      lcd.setCursor(0,0); 
      lcd.print(datum);
      lcd.print(" ");
      lcd.print(ido);
      
      temperature=getTemperature();
      lcd.setCursor(0,1);   
      lcd.print(temperature);
      lcd.print(" C");
      elozoperc=perc;
    }
    lepes=millis();
  }
}
Avatar
Robert
Elektronbűvölő
Hozzászólások: 10191
Csatlakozott: 2005. december 9. péntek, 7:00

Re: SD kártya eltávilítása és újrainicializálása

Hozzászólás Szerző: Robert »

Amit próbálj ki:
Mi van ha _másik_ kártyát teszel vissza? Lehet totális adatvesztés belőle!
http://www.tavir.hu - a gazda :)
Avatar
SzLacus
Tranzisztorgyógyász
Hozzászólások: 175
Csatlakozott: 2012. május 20. vasárnap, 6:00

Re: SD kártya eltávilítása és újrainicializálása

Hozzászólás Szerző: SzLacus »

Én még nem láttam olyan szerkezetet, amiben az SD eltávolítása előtt, vagy berakása után bármit nyomogatni kellett volna, hogy az SD használatba kerüljön. Így aztán azt sem értem, miért kéne a tápot kapcsolgatni. Nem jut eszembe semmi előny amit a kapcsolgatással el lehet érni.
A kártya detektálása kapcsoló nélküli foglalatban is lehetséges. Például micro SD foglalaton nem találkoztam még kapcsolóval. Ott a kártyán nincsenek egyvonalban a csatlakozó pontok, így segítve a detektálást.
A szelekt vonalat a kártya felhúzza. Ezt kell nézned, és ha jelen van a kártya akkor kimenetre váltani a szelektet, és használni.
Az írás közben pont kiveszik, esetre szerintem úgy tudsz felkészülni, hogy az írás végén ellenőrzöd az eredményességet. Ha egyezik, akkor kiment, és már nem zavar, ha kiveszik a kártyát. De rárakhatod a ledet a foglaltság jelzésre, csak attól még ki vehetik a kártyát, és veszhet az adat.
bagizoltan
Bitmanipulátor
Hozzászólások: 128
Csatlakozott: 2015. december 8. kedd, 19:52

Re: SD kártya eltávilítása és újrainicializálása

Hozzászólás Szerző: bagizoltan »

Köszi!
Kipróbálgatom az ötleteket! Ha születik érdemi eredmény, visszajelzek!
Bagi
Avatar
wappler.tibor
DrótVégénSzéndarab
Hozzászólások: 47
Csatlakozott: 2016. november 18. péntek, 1:21

Re: SD kártya eltávilítása és újrainicializálása

Hozzászólás Szerző: wappler.tibor »

Sziasztok!

Egy kicsit kapcsolódik a témához a kérdésem.
A Logger modulhoz (SD+RTC) milyen osztályú, sebességű SD kártyát érdemes venni?
Milyen sebességgel tudjuk írni- olvasni ? (Minél gyorsabb az SD kártya annál drágább, nincs felesleges zsetonom.)
--
üdv : wt
--
üdv : wt
Avatar
Robert
Elektronbűvölő
Hozzászólások: 10191
Csatlakozott: 2005. december 9. péntek, 7:00

Re: SD kártya eltávilítása és újrainicializálása

Hozzászólás Szerző: Robert »

A legvacakabb SD is bőven sok. :)
Class 1 :)

AVR (igaz Bascom) teszteltem a SD kezelést. Ott 40 kbyte/sec-t tudott.

Itt teszteltek http://openbci.com/forum/index.php?p=/d ... ting-speed :
512kByte / 36 sec ->14k/sec
http://www.tavir.hu - a gazda :)
Avatar
wappler.tibor
DrótVégénSzéndarab
Hozzászólások: 47
Csatlakozott: 2016. november 18. péntek, 1:21

Re: SD kártya eltávilítása és újrainicializálása

Hozzászólás Szerző: wappler.tibor »

Kedves Róbert, nagyon köszönöm a választ.
Remélem, hogy nem csak nekem nyújtott információt és remélem, hogy nem túrtam nagyon szét a témát.
--
üdv : wt
Avatar
csabeszq
Bitfaragó
Hozzászólások: 678
Csatlakozott: 2012. szeptember 5. szerda, 6:00

Re: SD kártya eltávilítása és újrainicializálása

Hozzászólás Szerző: csabeszq »

> Ott 40 kbyte/sec-t tudott.

Most játszom az STM32-vel, az eleve 3.3V-os és 24 MHz-ig képes SPI jelet kiadni. Ha ehhez hozzáveszed, hogy DMA-zni is képes, akkor bőven mbyte/s körüli átviteli sebességek jönnek ki. Ebből még a FAT fájlrendszer kezelését le kellene vonni.

Jelenleg 700 HUF körül mozog egy 72 MHz-es blue pill panel 32+3 IO porttal. Lassan felejteni kezdem az AVR-t, mert egy ESP számítási kapacitásban, vagy egy STM32 IO tekintetében magasan veri az AVR-t.
Válasz küldése