SD kártya irás

Processing/Wiring (illetve C) nyelvű programozási fogások, tippek. (AVR-Duino, Arduino, EthDuino, Diecimila, Severino, Nano, LilyPad)
Avatar
robresti
Újonc
Újonc
Hozzászólások: 11
Csatlakozott: 2012. július 18. szerda, 6:00

SD kártya irás

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

Sziasztok,

SD kártya írásnál, SD.h gondoltam használni. (Kezdésnek ez a legegyszerűbb, gondolom)
dataFile.println(dataString); (Ez ugyebár a DataString tartalmát kiírja a kártyára)

Kérdésem, hogy:
Sd kártya írásánál, megvan egy szám (100 000x), hogy egy memóriacella hányszor írható újra. (Utána elvileg csak olvasható marad az adott rekesz)

Mekkora a mérete a DataStringnek ami leginkább kíméli, a kártyát?
A kártya formázásánál megadott foglalási egység ha jól gondolom?
Ha a foglalási egységnél kisebb a DataStringem mérete akkor feleslegesen többször írom újra ugyanazt a rekszt, mire új reksz jön sorra?

(Ha pl.1024 bájt a foglalási egység (1kb), és 1 bájt a DataStringem mérete.) Akkor 1024-szer írom újra az adott memóriarekeszt, majd csak ezután vált új rekeszre?
Ha 1kb a DataSringem mérete, akkor pedig csak egyszer írja a cellát, és lép a következő cellára.

Így működik valahogy, vagy teljesen máshogy?
Avatar
Robert
Elektronbűvölő
Hozzászólások: 10213
Csatlakozott: 2005. december 9. péntek, 7:00

Re: SD kártya irás

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

Teljesen máshogy.
Az SD nem kötött memóriacellás. Forog szépen körbe, ezt az SD vezérlője intézi.
Avatar
robresti
Újonc
Újonc
Hozzászólások: 11
Csatlakozott: 2012. július 18. szerda, 6:00

Re: SD kártya irás

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

Dataloggert építgetek, 3 int változót írok ki kezdésnek.
Eddig féltem a kártya miatt minden ciklusban kiírni az adatokat.

Akkor kártya szemszögéből nézve teljesen mindegy, hogy ciklusonként (30ms-onként) írok rá 6 byte mennyiséget.
Vagy ütemezve 5 másodpercenként 1 kb-ot?

Mind a két esetben ugyanannyi a kártya élettartalma?
Valakinek van tapasztalata mennyi a kártya várható élettartalma Datalogger alkalmazásban 0-24h-ban működve?
Avatar
kapu48
Elektronbűvölő
Hozzászólások: 3375
Csatlakozott: 2008. augusztus 29. péntek, 6:00

Re: SD kártya irás

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

Szerintem innen mindent megtudsz:

Adafruit Data Logger Shield
https://learn.adafruit.com/adafruit-dat ... d?view=all
Avatar
Robert
Elektronbűvölő
Hozzászólások: 10213
Csatlakozott: 2005. december 9. péntek, 7:00

Re: SD kártya irás

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

Magyarul is van (bővebb)
http://tavir.hu/sdlogger-1
Avatar
robresti
Újonc
Újonc
Hozzászólások: 11
Csatlakozott: 2012. július 18. szerda, 6:00

Re: SD kártya irás

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

Átolvastam, de vaksi vagyok vagy nem tudom.
Mert a lentire nem kaptam választ belőlük.

Kártya szemszögéből nézve teljesen mindegy, hogy ciklusonként (30ms-onként) írok rá 6 byte mennyiséget.
Vagy ütemezve 5 másodpercenként 1 kb-ot?

Jól gondolom, hogy igen a válasz?
Avatar
Robert
Elektronbűvölő
Hozzászólások: 10213
Csatlakozott: 2005. december 9. péntek, 7:00

Re: SD kártya irás

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

30 ms / 6 byte : sűrűn írsz, a kártya frissíti az adatokat. Ha NINCS pufferelés (Arduino flush() parancs).
1 secenként írsz: ritkábban ír a kártyára.

A 30 msecenként megnyitom a file-t, bezárom a file-t - erőforrásigényes. Ha meg nyitva van a file (és pl. áramszünet: adatvesztés, mert nincsen még kiírva az adat.
Avatar
furbyhun
DrótVégénSzéndarab
Hozzászólások: 44
Csatlakozott: 2015. február 14. szombat, 21:18

Re: SD kártya irás

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

Sziasztok!

Dataloggert építgetek, és két megoldással próbálkoztam a tárolásnál:

1. Minden analóg portról olvasás után fájlnyitás, adatkiírás, fájlzárás. Ezzel másodpercenként alig több, mint 50-szer tud mintavételezni, nekem picit lassú.
2. Olvasom a az analóg portot, kiírom az SD-re az adatot, és majd a programból való kilépéskor, vagy ha az aktuális órának vége van, lezárom a fájlt (óránként új fájlt kezdek, a feldolgozó program korlátozott képességei miatt) Ez gyorsabb, jóval több, mint 100 mintavétel van másodpercenként.

Mindkét megoldásnál probléma, hogy a mintavétel nem egyenletes. Nem azonos számú mintavétel történik másodpercenként, pedig ez lényeges lenne, mert később ez alapján kell majd a feldolgozó programnak csúcsok közti időt számolnia. És azt vettem észre, hogy amikor kevesebb a mintavétel, akkor nagyon alacsony szintű, de fals jel jön az analóg bemeneten, és a piros LED a panelen olyankor hosszabban világít. Vajon ilyenkor ír a kártyára, azért lassul le? Miért nem egyenletes?

Köszi a segítséget előre is!
Avatar
Robert
Elektronbűvölő
Hozzászólások: 10213
Csatlakozott: 2005. december 9. péntek, 7:00

Re: SD kártya irás

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

Kód? :twisted:
Avatar
furbyhun
DrótVégénSzéndarab
Hozzászólások: 44
Csatlakozott: 2015. február 14. szombat, 21:18

Re: SD kártya irás

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

Hát íme tokkal-vonóval az a változat, ami azonnal kiírja az adatot és lezárja a fájlt:

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

/* EKG Holter (C) Bence Miklós */
// könyvtárak
#include <Wire.h>
#include "RTClib.h"
#include <SPI.h>
#include <SD.h>

RTC_DS1307 rtc;

// konstansok
const int buttonPin = 5;      // a nyomógomb láb deklarálása
const int redLedPin =  3;     // a piros LED kivezetésének deklarációja
const int greenLedPin =  4;   // a zöld LED kivezetésének deklarációja
const int buttonDelay=2000;   // ennyi ms-ig kell lenyomva tartani a gombot az állapotváltáshoz
const int chipSelect = 10;    // a CS láb a 10-es digitális port az SPI buszon 
const int analogPin = 0;      // a 0-s analóg port lesz a bemenet

// változók
int buttonState = HIGH;       // a nyomógomb állapotának nyilvántartására használt változó
int prevButtonState = HIGH;   // a nyomógomb előző állapotának nyilvántartására használt változó
int nowChanged = LOW;         // ebben azt tároljuk, hogy épp most léptünk-e át a rögzítés előttiből rögzítés állapotba (mivel akkor figyelmen kívül kell hagyni a gomb elengedését)
int systemState = 0;          // a rendszer állapota, 0=rögzítés előtti várakozás, 1=rögzítés, 2=rögzítés befejeződött, kapcsold ki a tápfeszt
long oldmillis;               // az előző időpillanat tárolásásra, amikor a nyomógombon lefutó élet észleltünk
String dataString;            // a fájlba írandó adat
int sensor;                   // a beolvasott digiatlizált jelszint
int hourNumber = 1;           // az óra sorszáma, ahol tartunk
int prevSecond;               // az előző másodperc sorszáma
int actSecond;                // az aktuális másodperc     
int prevHour;                 // az előző óra
int actHour;                  // az aktuális óra
File dataFile;                // fájlváltozó, mint a Pascalban :)
DateTime now;                 // a most beolvasott időpont 

void setup() {
  
#ifdef AVR
  Wire.begin();                         // I2C busz inicializálás
#else
  Wire1.begin();                        // Shield I2C pins connect to alt I2C bus on Arduino Due
#endif
  rtc.begin();                          // kapcsolódunk az RTC panelhez
  pinMode(redLedPin, OUTPUT);       // beállítjuk kimenetként a LEDek pinjeit
  pinMode(greenLedPin, OUTPUT);
  if (rtc.isrunning()) {                // ha fut az óra
    pinMode(buttonPin, INPUT);        // beállítjuk bemenetként a nyomógomb pinjét
    digitalWrite(buttonPin, HIGH);     
    pinMode(10, OUTPUT);
    if (SD.begin(chipSelect)) {         //ha van SD kártya is
    } else {                            // ha nincs SD kártya,
      digitalWrite(redLedPin, HIGH);    // morzézunk egy S betűt
      delay(150);
      digitalWrite(redLedPin, LOW);
      delay(100);
      digitalWrite(redLedPin, HIGH);    
      delay(150);
      digitalWrite(redLedPin, LOW);
      delay(100);
      digitalWrite(redLedPin, HIGH);    
      delay(150);
      digitalWrite(redLedPin, LOW);
      systemState = 3;                  // és leáll a program
    }  
  } else {                              // ha nem fut az RTC
      digitalWrite(redLedPin, HIGH);    // morzézunk egy R betűt
      delay(150);
      digitalWrite(redLedPin, LOW);
      delay(100);
      digitalWrite(redLedPin, HIGH);    
      delay(300);
      digitalWrite(redLedPin, LOW);
      systemState = 3;                  // és leáll a program  
  }
}  
void loop() {
  buttonState = digitalRead(buttonPin); //  mindenképp beolvassuk a gomb állapotát
  if (systemState == 0) {               // ha bekapcsolás után, de rögzítési állapot előtt vagyunk
    digitalWrite(greenLedPin, HIGH);    // világít a zöld LED
    if (buttonState == LOW && prevButtonState == HIGH) { // ha lefutó él érkezik a nyomógombon
      oldmillis = millis();             // eltároljuk az idejét
      prevButtonState = LOW;            // és az előző állapotot átállítjuk
    } 
    if (buttonState ==  HIGH && prevButtonState == LOW && millis()-oldmillis < buttonDelay) { // 2 mp-nél korábbi felengedés
      prevButtonState = HIGH;           // elkönyveljük, h újra felengedett, más teendőnk nincs
    }
    if (buttonState == LOW && prevButtonState == LOW && millis()-oldmillis  > buttonDelay) { // 2 mp-nél hosszabb gombnyomás
      digitalWrite(greenLedPin, LOW);   // kioltjuk a zöld LEDet
      nowChanged =HIGH;                 // jelezzük, h most változott, az első felfutó élnél nem kell eseményjelzés a fájlba!
      oldmillis = millis();             // megjegyezzük az állapotváltás időpontját
      systemState = 1;                  // váltunk rögzítési folyamat állapotba
      now = rtc.now();
      prevSecond = now.second();
      prevHour = now.hour();
     }
  }
  if (systemState == 1) {               // ha rögzítési állapotban vagyunk
     
  //ide kerül majd az analóg bemenetről olvasás, és a fájlba írás, esetleges késleltetés (az értékes adat 0..1023 közötti, és másodpercenként lesz egy időbélyeg, ami jóval nagyobb
    sensor = analogRead(analogPin);     // beolvassuk az adatot
    dataString = String(sensor);        // karakterlánccá alakítjuk
    now = rtc.now();
    actHour = now.hour();               // kiolvassuk, hány óra
    if (actHour != prevHour) {          // ha ugrott az előző kiolvasás óta, 
      hourNumber = hourNumber++;                     // akkor növeljük a fájlnév sorszámát tartalmazó változót,
      prevHour = actHour;               // és eltesszük előző óraként
    }  
    switch (hourNumber) {               // megnyitjuk a megfelelő fájlt írásra
     case 1:
          dataFile = SD.open("1.txt", FILE_WRITE); 
          break;
     case 2:
          dataFile = SD.open("2.txt", FILE_WRITE); 
          break;
     case 3:
          dataFile = SD.open("3.txt", FILE_WRITE); 
          break;
     case 4:
          dataFile = SD.open("4.txt", FILE_WRITE); 
          break;
     case 5:
          dataFile = SD.open("5.txt", FILE_WRITE); 
          break;
     case 6:
          dataFile = SD.open("6.txt", FILE_WRITE); 
          break;
     case 7:
          dataFile = SD.open("7.txt", FILE_WRITE); 
          break;
     case 8:
          dataFile = SD.open("8.txt", FILE_WRITE); 
          break;
     case 9:
          dataFile = SD.open("9.txt", FILE_WRITE); 
          break;
     case 10:
          dataFile = SD.open("10.txt", FILE_WRITE); 
          break;
     case 11:
          dataFile = SD.open("11.txt", FILE_WRITE); 
          break;
     case 12:
          dataFile = SD.open("12.txt", FILE_WRITE); 
          break;
     case 13:
          dataFile = SD.open("13.txt", FILE_WRITE); 
          break;
     case 14:
          dataFile = SD.open("14.txt", FILE_WRITE); 
          break;
     case 15:
          dataFile = SD.open("15.txt", FILE_WRITE); 
          break;
     case 16:
          dataFile = SD.open("16.txt", FILE_WRITE); 
          break;
     case 17:
          dataFile = SD.open("17.txt", FILE_WRITE); 
          break;
     case 18:
          dataFile = SD.open("18.txt", FILE_WRITE); 
          break;
     case 19:
          dataFile = SD.open("19.txt", FILE_WRITE); 
          break;
     case 20:
          dataFile = SD.open("20.txt", FILE_WRITE); 
          break;
     case 21:
          dataFile = SD.open("21.txt", FILE_WRITE); 
          break;
     case 22:
          dataFile = SD.open("22.txt", FILE_WRITE); 
          break;
     case 23:
          dataFile = SD.open("23.txt", FILE_WRITE); 
          break;
     case 24:
          dataFile = SD.open("24.txt", FILE_WRITE); 
          break;
     case 25:
          dataFile = SD.open("25.txt", FILE_WRITE); 
          break;
    }    

    if (dataFile) {                     // ha sikerült
      dataFile.println(dataString);     // kiírjuk az adatot
      now = rtc.now();
      actSecond = now.second();         //kiolvassuk a másodpercet 
      if (actSecond != prevSecond) {    // ha ugrott az előző kiolvasás óta
        dataString = String(now.unixtime()); // időbélyeget is írunk a fájlba
        dataFile.println(dataString);
        prevSecond = actSecond;         // és az aktuális mp-et eltesszük előzőként
      }  
      dataFile.close();                 // és lezárjuk a fájlt
    }
    
    if (buttonState == LOW && prevButtonState == HIGH) { //lefutó él a nyomógombon
      oldmillis = millis();
      prevButtonState = LOW;
    } 
    if (buttonState ==  HIGH && prevButtonState == LOW && millis()-oldmillis < buttonDelay && nowChanged == LOW) { // 2 mp-nél korábbi felengedés, de csak nem közvetlenül állapotváltás után
      prevButtonState = HIGH;           // elkönyveljük a felengedett állapotot
      dataString = "1024";              // az adat helyére 1024 kerül
      switch (hourNumber) {               // megnyitjuk a megfelelő fájlt írásra
       case 1:
          dataFile = SD.open("1.txt", FILE_WRITE); 
          break;
       case 2:
          dataFile = SD.open("2.txt", FILE_WRITE); 
          break;
       case 3:
          dataFile = SD.open("3.txt", FILE_WRITE); 
          break;
       case 4:
          dataFile = SD.open("4.txt", FILE_WRITE); 
          break;
       case 5:
          dataFile = SD.open("5.txt", FILE_WRITE); 
          break;
       case 6:
          dataFile = SD.open("6.txt", FILE_WRITE); 
          break;
       case 7:
          dataFile = SD.open("7.txt", FILE_WRITE); 
          break;
       case 8:
          dataFile = SD.open("8.txt", FILE_WRITE); 
          break;
       case 9:
          dataFile = SD.open("9.txt", FILE_WRITE); 
          break;
       case 10:
          dataFile = SD.open("10.txt", FILE_WRITE); 
          break;
       case 11:
          dataFile = SD.open("11.txt", FILE_WRITE); 
          break;
       case 12:
          dataFile = SD.open("12.txt", FILE_WRITE); 
          break;
       case 13:
          dataFile = SD.open("13.txt", FILE_WRITE); 
          break;
       case 14:
          dataFile = SD.open("14.txt", FILE_WRITE); 
          break;
       case 15:
          dataFile = SD.open("15.txt", FILE_WRITE); 
          break;
       case 16:
          dataFile = SD.open("16.txt", FILE_WRITE); 
          break;
       case 17:
          dataFile = SD.open("17.txt", FILE_WRITE); 
          break;
       case 18:
          dataFile = SD.open("18.txt", FILE_WRITE); 
          break;
       case 19:
          dataFile = SD.open("19.txt", FILE_WRITE); 
          break;
       case 20:
          dataFile = SD.open("20.txt", FILE_WRITE); 
          break;
       case 21:
          dataFile = SD.open("21.txt", FILE_WRITE); 
          break;
       case 22:
          dataFile = SD.open("22.txt", FILE_WRITE); 
          break;
       case 23:
          dataFile = SD.open("23.txt", FILE_WRITE); 
          break;
       case 24:
          dataFile = SD.open("24.txt", FILE_WRITE); 
          break;
       case 25:
          dataFile = SD.open("25.txt", FILE_WRITE); 
          break;
      }    
      if (dataFile) {                   // ha sikerült
        dataFile.println(dataString);   // kiírjuk a jelzésnek megfelelő 1024-et
        dataFile.close();               // és lezárjuk a fájlt
      }  
    }
    if (buttonState ==  HIGH && prevButtonState == LOW && millis()-oldmillis < buttonDelay && nowChanged == HIGH) { // 2 mp-nél korábbi felengedés, közvetlenül állapotváltás után
      prevButtonState = HIGH;           // elkönyveljük, hogy a gombot felngedték
      nowChanged = LOW;                 // jelezzük, hogy most már nem az első felengedés jön az állapotváltás után, lehet figyelni az eseményeket
    }
    if (buttonState == LOW && prevButtonState == LOW && millis()-oldmillis  > buttonDelay && nowChanged == LOW) { // 2 mp-nél hosszabb gombnyomás, de csak ha nem az állapotváltás utáni túl hosszú
      systemState = 2;                  // váltunk rögzítés utáni állapotba
    }
  }
    if (systemState == 2) {             // ha rögzítés után vagyunk, kikapcsolás szükséges: a piros LED villogása jelzi
    digitalWrite(redLedPin, HIGH);
    delay(500);
    digitalWrite(redLedPin, LOW);
    delay(500);
  } 
}
Avatar
furbyhun
DrótVégénSzéndarab
Hozzászólások: 44
Csatlakozott: 2015. február 14. szombat, 21:18

Re: SD kártya irás

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

Nincs ötlet az előzővel kapcsolatban akkor? Esetleg a fő ifek helyett case a működési állapotok elkülönítésére...talán gyorsabb lesz, de az egyenetlenségre ez nem megoldás...
Avatar
Robert
Elektronbűvölő
Hozzászólások: 10213
Csatlakozott: 2005. december 9. péntek, 7:00

Re: SD kártya irás

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

Az írások közt ne delay() legyen .

Kvázikód:

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

setup()
oldmilils=millis()

loop()

if millis()-oldmillis >=1000
{
itt van a kártyaírás;
oldmillis=millis();
}
Avatar
furbyhun
DrótVégénSzéndarab
Hozzászólások: 44
Csatlakozott: 2015. február 14. szombat, 21:18

Re: SD kártya irás

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

Hmm, pontosan ezt csináltam a másodpercenkénti íráskor....otthon, ha hazaértem, elküldöm azt a kódot is, annak a futtatásakor lényegesen nagyobb egyenetlenségeket tapasztaltam, viszont sokkal gyorsabb ugye.
Avatar
Robert
Elektronbűvölő
Hozzászólások: 10213
Csatlakozott: 2005. december 9. péntek, 7:00

Re: SD kártya irás

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

A gopmbnyomásfigyelés 2 sec, az írás 1 sec-enként van.
Megnyitogatom, zárom, stb - nem az igazi.

Nagyobb adattömb (~10 secre való adatot raknék bele, és 10 secenként írnék file-ba).
Miért kell ennyi file?

hourNumberből csinálj stringet. és nem kell a sok case/else.
Nem az adatolvasásos lassú? analogread és egyebeket amikor olvasod?


Soros debug nincsen? Kellene. Tudnál a részfeladatokra időt mérni...
millis() - millisstart()

Így látnád melyik részponton van elúszás.
Avatar
furbyhun
DrótVégénSzéndarab
Hozzászólások: 44
Csatlakozott: 2015. február 14. szombat, 21:18

Re: SD kártya irás

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

Én is így akartam, h ne legyen case, csak az sd.open nem fogadott el változót, csak konstanst paraméterként, így lett ez. Azért van ennyi fájl, mert a delphiben a teechart objektum nem fizetős verziója csak ennyi adat megjelenítésére képes, és ha óránként képződik egy adatfájl, max. 200 Hz mintavétellel, ez fér bele legfeljebb (egész pontosan 199 Hz a határ, kiteszteltem :D). Nem tudom, az adatolvasás mitől lehet lassú? Az az érdekes, h nem egyenletes, megnéztem, a bekopizott program olyan 34-47 mintát vesz másodpercenként. Amit most ideteszek, az úgy csinálja, h folyamatosan kiírja az adatot, de csak óra végén, vagy a programból való kilépéskor zárja le a fájlt, ez nagyjából 500 mintát tud másodpercenként, de pár másodpercenként belassul.

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

/* EKG Holter (C) Bence Miklós */
// könyvtárak
#include <Wire.h>
#include "RTClib.h"
#include <SPI.h>
#include <SD.h>

RTC_DS1307 rtc;

// konstansok
const int buttonPin = 5;      // a nyomógomb láb deklarálása
const int redLedPin =  3;     // a piros LED kivezetésének deklarációja
const int greenLedPin =  4;   // a zöld LED kivezetésének deklarációja
const int buttonDelay=2000;   // ennyi ms-ig kell lenyomva tartani a gombot az állapotváltáshoz
const int chipSelect = 10;    // a CS láb a 10-es digitális port az SPI buszon 
const int analogPin = 0;      // a 0-s analóg port lesz a bemenet

// változók
int buttonState = HIGH;       // a nyomógomb állapotának nyilvántartására használt változó
int prevButtonState = HIGH;   // a nyomógomb előző állapotának nyilvántartására használt változó
int nowChanged = LOW;         // ebben azt tároljuk, hogy épp most léptünk-e át a rögzítés előttiből rögzítés állapotba (mivel akkor figyelmen kívül kell hagyni a gomb elengedését)
int systemState = 0;          // a rendszer állapota, 0=rögzítés előtti várakozás, 1=rögzítés, 2=rögzítés befejeződött, kapcsold ki a tápfeszt
long oldmillis;               // az előző időpillanat tárolásásra, amikor a nyomógombon lefutó élet észleltünk
String dataString;            // a fájlba írandó adat
int sensor;                   // a beolvasott digiatlizált jelszint
int hourNumber = 1;           // az óra sorszáma, ahol tartunk
int prevSecond;               // az előző másodperc sorszáma
int actSecond;                // az aktuális másodperc     
int prevHour;                 // az előző óra
int actHour;                  // az aktuális óra
long startTime;               // a mérés kezdetének időpontja unixformátumban
long actTime;                 // aktuális idő unixformátumban 
File dataFile;                // fájlváltozó, mint a Pascalban :)
DateTime now;                 // a most beolvasott időpont 
  
void setup() {

#ifdef AVR
  Wire.begin();                         // I2C busz inicializálás
#else
  Wire1.begin();                        // Shield I2C pins connect to alt I2C bus on Arduino Due
#endif
  rtc.begin();                          // kapcsolódunk az RTC panelhez
  pinMode(redLedPin, OUTPUT);       // beállítjuk kimenetként a LEDek pinjeit
  pinMode(greenLedPin, OUTPUT);
  if (rtc.isrunning()) {                // ha fut az óra
    pinMode(buttonPin, INPUT);        // beállítjuk bemenetként a nyomógomb pinjét
    digitalWrite(buttonPin, HIGH);     
    pinMode(10, OUTPUT);
    if (SD.begin(chipSelect)) {         //ha van SD kártya is
    } else {                            // ha nincs SD kártya,
      digitalWrite(redLedPin, HIGH);    // morzézunk egy S betűt
      delay(150);
      digitalWrite(redLedPin, LOW);
      delay(100);
      digitalWrite(redLedPin, HIGH);    
      delay(150);
      digitalWrite(redLedPin, LOW);
      delay(100);
      digitalWrite(redLedPin, HIGH);    
      delay(150);
      digitalWrite(redLedPin, LOW);
      systemState = 3;                  // és leáll a program
    }  
  } else {                              // ha nem fut az RTC
      digitalWrite(redLedPin, HIGH);    // morzézunk egy R betűt
      delay(150);
      digitalWrite(redLedPin, LOW);
      delay(100);
      digitalWrite(redLedPin, HIGH);    
      delay(300);
      digitalWrite(redLedPin, LOW);
      systemState = 3;                  // és leáll a program  
  }
}  
  
void loop() {
  buttonState = digitalRead(buttonPin); // mindenképp beolvassuk a gomb állapotát
  if (systemState == 0) {               // ha bekapcsolás után, de rögzítési állapot előtt vagyunk
    digitalWrite(greenLedPin, HIGH);    // világít a zöld LED
    if (buttonState == LOW && prevButtonState == HIGH) { // ha lefutó él érkezik a nyomógombon
      oldmillis = millis();             // eltároljuk az idejét
      prevButtonState = LOW;            // és az előző állapotot átállítjuk
    } 
    if (buttonState ==  HIGH && prevButtonState == LOW && millis()-oldmillis < buttonDelay) { // 2 mp-nél korábbi felengedés
      prevButtonState = HIGH;           // elkönyveljük, h újra felengedett, más teendőnk nincs
    }
    if (buttonState == LOW && prevButtonState == LOW && millis()-oldmillis  > buttonDelay) { // 2 mp-nél hosszabb gombnyomás
      digitalWrite(greenLedPin, LOW);   // kioltjuk a zöld LEDet
      nowChanged =HIGH;                 // jelezzük, h most változott, az első felfutó élnél nem kell eseményjelzés a fájlba!
      oldmillis = millis();             // megjegyezzük az állapotváltás időpontját
      systemState = 1;                  // váltunk rögzítési folyamat állapotba
      now = rtc.now();                  // mennyi a pontos idő? :)
      startTime = now.unixtime();       // eltároljuk a kezdés valós idejét
      prevSecond = now.second();        // az előző másodpercet is
      prevHour = now.hour();            // az előző órát is
      dataFile = SD.open("1.txt", FILE_WRITE);  // megnyitjuk az első óra fájlját     
     }
  }
  if (systemState == 1) {               // ha rögzítési állapotban vagyunk
     
    sensor = analogRead(analogPin);     // beolvassuk az adatot
    dataString = String(sensor);        // karakterlánccá alakítjuk
    now = rtc.now();                    // kiolvassuk a pontos időt
    actTime = now.unixtime();           // eltároljuk unixformában
    actHour = now.hour();               // kiolvassuk, hány óra
    if (actHour != prevHour) {          // ha ugrott az előző kiolvasás óta, 
      hourNumber = hourNumber++;        // akkor növeljük a fájlnév sorszámát tartalmazó változót,
      prevHour = actHour;               // és eltesszük előző óraként
      dataFile.close();                 // és lezárjuk az előző fájlt
      switch (hourNumber) {             // megnyitjuk a megfelelő fájlt írásra
       case 2:
          dataFile = SD.open("2.txt", FILE_WRITE); 
          break;
       case 3:
          dataFile = SD.open("3.txt", FILE_WRITE); 
          break;
       case 4:
          dataFile = SD.open("4.txt", FILE_WRITE); 
          break;
       case 5:
          dataFile = SD.open("5.txt", FILE_WRITE); 
          break;
       case 6:
          dataFile = SD.open("6.txt", FILE_WRITE); 
          break;
       case 7:
          dataFile = SD.open("7.txt", FILE_WRITE); 
          break;
       case 8:
          dataFile = SD.open("8.txt", FILE_WRITE); 
          break;
       case 9:
          dataFile = SD.open("9.txt", FILE_WRITE); 
          break;
       case 10:
          dataFile = SD.open("10.txt", FILE_WRITE); 
          break;
       case 11:
          dataFile = SD.open("11.txt", FILE_WRITE); 
          break;
       case 12:
          dataFile = SD.open("12.txt", FILE_WRITE); 
          break;
       case 13:
          dataFile = SD.open("13.txt", FILE_WRITE); 
          break;
       case 14:
          dataFile = SD.open("14.txt", FILE_WRITE); 
          break;
       case 15:
          dataFile = SD.open("15.txt", FILE_WRITE); 
          break;
       case 16:
          dataFile = SD.open("16.txt", FILE_WRITE); 
          break;
       case 17:
          dataFile = SD.open("17.txt", FILE_WRITE); 
          break;
       case 18:
          dataFile = SD.open("18.txt", FILE_WRITE); 
          break;
       case 19:
          dataFile = SD.open("19.txt", FILE_WRITE); 
          break;
       case 20:
          dataFile = SD.open("20.txt", FILE_WRITE); 
          break;
       case 21:
          dataFile = SD.open("21.txt", FILE_WRITE); 
          break;
       case 22:
          dataFile = SD.open("22.txt", FILE_WRITE); 
          break;
       case 23:
          dataFile = SD.open("23.txt", FILE_WRITE); 
          break;
       case 24:
          dataFile = SD.open("24.txt", FILE_WRITE); 
          break;
       case 25:
          dataFile = SD.open("25.txt", FILE_WRITE); 
          break;
      }    
    }
    if (dataFile) {                     // ha sikerült a fájlt megnyitni
      dataFile.println(dataString);     // kiírjuk az adatot
      now = rtc.now();
      actSecond = now.second();         //kiolvassuk a másodpercet 
      if (actSecond != prevSecond) {    // ha ugrott az előző kiolvasás óta
        dataString = String(now.unixtime()); // időbélyeget is írunk a fájlba
        dataFile.println(dataString);
        prevSecond = actSecond;         // és az aktuális mp-et eltesszük előzőként
      }  
      if (actTime-startTime > 86400) {  // ha eltelt a kezdés óta már egy nap
        systemState = 2;                // beállítjuk h vége
        dataFile.close();               // és lezárjuk az utoljára használt fájlt
      }  
    }
    
    if (buttonState == LOW && prevButtonState == HIGH) { // ha lefutó él a nyomógombon
      oldmillis = millis();
      prevButtonState = LOW;
    } 
    if (buttonState ==  HIGH && prevButtonState == LOW && millis()-oldmillis < buttonDelay && nowChanged == LOW) { // ha 2 mp-nél korábbi felengedés, de csak nem közvetlenül állapotváltás után
      prevButtonState = HIGH;           // elkönyveljük a felengedett állapotot
      //ide kerül majd az eseményjelzés (1024) írása a fájlba, mert eseményt jelzett a felhasználó
      dataString = "1024";              // az adat helyére 1024 kerül
      if (dataFile) {                   // ha sikerült
        dataFile.println(dataString);   // kiírjuk a jelzésnek megfelelő 1024-et
      }  
    }
    if (buttonState ==  HIGH && prevButtonState == LOW && millis()-oldmillis < buttonDelay && nowChanged == HIGH) { // ha 2 mp-nél korábbi felengedés, közvetlenül állapotváltás után
      prevButtonState = HIGH;           // elkönyveljük, hogy a gombot felngedték
      nowChanged = LOW;                 // jelezzük, hogy most már nem az első felengedés jön az állapotváltás után, lehet figyelni az eseményeket
    }
    if (buttonState == LOW && prevButtonState == LOW && millis()-oldmillis  > buttonDelay && nowChanged == LOW) { // ha 2 mp-nél hosszabb gombnyomás, de csak ha nem az állapotváltás utáni túl hosszú
      systemState = 2;                  // váltunk rögzítés utáni állapotba, 
      dataFile.close();                 // és lezárjuk az utoljára használt fájlt
    }
  }
    if (systemState == 2) {             // ha rögzítés után vagyunk, kikapcsolás szükséges: a piros LED villogása jelzi
      digitalWrite(redLedPin, HIGH);
      delay(500);
      digitalWrite(redLedPin, LOW);
      delay(500);
  } 
}
Válasz küldése