Go Down

Topic: ISR zum Ansteuern einer SD-Karte (Read 87 times) previous topic - next topic

Luk_11

Hi zusammen,

ich habe ein kleines Programm geschrieben, das einen Ultraschall-Sensor ansteuert und die gemessene Distanz auf einer SD-Karte festhält.

Um den Mikrocontroller nicht durchgehend zu beschäftigen, löse ich erst dann einen neuen Trigger-Puls aus, wenn der vorherige am Receiver angekommen ist. Dies geschieht also durch eine Interrupt-Service-Routine.

Ähnlich möchte ich auch, dass das Ergebnis der Berechnung aus ultrasonicTrigger (siehe Code) nach Eingang des reflektierten Signals auf die SD-Karte geschrieben wird. Auch hierfür möchte ich also eine ISR  schreiben. Leider fehlt mir gerade die Idee, welcher Pin sich als ISR eignet. Wird der CS Pin immer zuerst auf HIGH gesetzt, wenn meine SD-Karte angesprochen wird? In dem Fall müsste mein Code stimmen.

Ich muss natürlich auch sicher gehen, dass die Datei auf der SD-Karte, in der die Daten geschrieben werden, nicht geöffnet ist, wenn ich die SD-Karte entnehme. Ich habe deshalb eigentlich vorgehabt die Loop nur für 8 Minuten auszuführen. Allerdings ist dies vermutlich kontraproduktiv, da der Mikrocontroller dann wieder die ganze Zeit beschäftigt ist, oder?

Code: [Select]
#include <SD.h>
#include <SPI.h>

int chipSelect = 53;
File mySensorData;
//SD card attached to SPI bus as follows:
//CS - Pin 53
//MOSI - Pin 51
//SCK - Pin 52
//MISO - Pin 50

int trigPin = 13;                                                    //ultrasonic-sensor trigger pin is connected to IO 13
int echoPin = 2;                                                     //ultrasonic-sensor echo pin is connected to IO 2, which is capable of handling interrupts
float pingTime;                                                      //round-trip-time (RTT)
float distance2target;
float speedOfSound = 343;                                            //speed of sound at 20°C in m/s

unsigned long minutes = 60000;                                       //60000ms = 1 minute

void setup() {

  Serial.begin(9600);
  pinMode(trigPin,OUTPUT);
  pinMode(echoPin,INPUT);
  SD.begin(chipSelect);                                              //initialize SD-card
  attachInterrupt (digitalPinToInterrupt(echoPin), ultrasonicTrigger, HIGH);
  attachInterrupt (digitalPinToInterrupt(chipSelect), write2SD, HIGH);

}

void loop() {

  if( millis() < minutes * 8) {
      ultrasonicTrigger();
      write2SD();
  }
}



  //Interrupt Service Routine to trigger an ultrasonic pulse right after arrival of the previous one
  void ultrasonicTrigger() {
   
  //the ultrasonic-sensor starts its measurements upon arrival of a trigger pulse:
  digitalWrite(trigPin,LOW);
  delayMicroseconds(2000);
  digitalWrite(trigPin,HIGH);
  delayMicroseconds(15);
  digitalWrite(trigPin,LOW);
  delayMicroseconds(15);
 
  //its response to the microcontroller is a pulse whose length corresponds to the RTT:
  pingTime = pulseIn(echoPin,HIGH);                                 //measure RTT in microseconds
  pingTime = pingTime/1000000;                                      //RTT in seconds
  distance2target = speedOfSound * pingTime/2;                      //distance to target in m
  distance2target = distance2target * 100;                          //distance to target in cm

  write2SD();
   
  }

  //Interrupt Service Routine to log results on SD card
  void write2SD() {
   
    mySensorData = SD.open("HYSRF.txt", FILE_WRITE);               //create or open the file "HYSRF.txt" on SD card
    mySensorData.println(distance2target);
    mySensorData.close();
   
  }



Tommy56

Warum willst Du das relativ langsame Schreiben der Daten auf SD in einem Imterrupt machen? Während dieser Zeit sind die anderen Interrupts nicht aktiv.
Es genügt doch, wenn Du nach Empfang des Ping die Daten schreibst.

Gruß Tommy
"Wer den schnellen Erfolg sucht, sollte nicht programmieren, sondern Holz hacken." (Quelle unbekannt)

michael_x

In einer ISR kannst du nicht auf eine SD Karte schreiben.

Du kannst dir merken, dass (und evtl. was) zu schreiben ist.Wenn das selten geug vorkommt, kannst du prüfen, ob eine Karte drin ist, eine Led einschalten, 1 sec warten, dann schreiben, Datei schließen,  Led aus.
Wenn keine Karte erkannt wurde, kannst du die Led schnell blinken lassen.
Dass die Karte nicht entnommen wird, während die Led an ist, sollte intuitiv genug sein.

Doc_Arduino

Hallo,

das ist Wahnsinn. In einer ISR werden keine langwierigen Dinge behandelt.
Setzte in der ISR ein bool Flag welches du in der loop abfragst und dann deine SD Funktionen abarbeitest.

Wenn du die Karte sicher entnehmen möchtest, dann programmiere einen Taster zum Schalter mit Anzeige LED. Damit sperrst du die Zugriffe auf die SD. Karte wieder drin > Zugriffe freigeben.

/CS hat im Ruhezustand High Pegel. Will man auf ein SPI Gerät zugreifen muss erst /CS auf Low, dann wird der SPI Bus aktiv und wenn alles durch setzt man /CS wieder auf High. Kannst auch die Bsp. der Lib anschauen.
Tschau
Doc Arduino '\0'

Messschieber auslesen: http://forum.arduino.cc/index.php?topic=273445
EA-DOGM Display - Demos: http://forum.arduino.cc/index.php?topic=378279

Luk_11

alles klar, vielen Dank euch!

das ist mein erstes Arduino-Projekt, ich lerne also noch ;-)

Go Up