SD Karte funktioniert nur bei ersten Test

Hallo zusammen,

dies ist mein erster Post. Sollte jemand Verbesserungsvorschläge haben, dann immer her damit.


Ausgangssituation:
Ich besitze einen Controllino Maxi an welchem ich, wie folgt erklärt, ein SD Karten Modul mit einer Micro 4GB SD Karte von Transcend angeschlossen habe.

Controllino Pin:
(siehe Bild im Anhang)
SD Karten Modul:
MISO MISO
MOSI MOSI
SCK SCK
Digital 2 CS
5V VCC
GND GND

Anwendungsgebiet:
Ich möchte einen Webserver erstellen, dessen HTML Script sich auf der SD Karte befindet. Danach sollen Webserver und Controllino per XML Datei miteinander kommunizieren.

HTML Script:

<!DOCTYPE html>
<html lang="de">
  <head>
    <title>LTS Steuerung</title>
    <script>
      strLTS = "";
      var LTS_state = 0;

      function GetArduinoIO() {
        nocache = "&nocache=" + Math.random() * 1000000;
        var request = new XMLHttpRequest();
        request.onreadystatechange = function () {
          if (this.readyState == 4) {
            if (this.status == 200) {
              if (this.responseXML != null) {
                // XML file received
                var count;
                if (
                  this.responseXML.getElementsByTagName("LTS").childNodes[0]
                    .nodeValue === "on"
                ) {
                  document.getElementById("LTS").innerHTML = "ON";
                  LTS_state = 1;
                } else {
                  document.getElementById("LTS").innerHTML = "OFF";
                  LTS_state = 0;
                }
              }
            }
          }
        };
        request.open("GET", "ajax_inputs" + strLTS + nocache, true);
        request.send(null);
        setTimeout("GetArduinoIO()", 1000);
        strLTS = "";
      }
      function GetButton() {
        if (LTS_state === 1) {
          LTS_state = 0;
          strLTS = "&LTS=0";
        } else {
          LTS_state = 1;
          strLTS = "&LTS=1";
        }
      }
    </script>
  </head>
  <body onload="GetArduinoIO()">
    <div class="textbereich">
      <h1 class="title">Leistungstrennschalter</h1>
      <button type="button" class="einaus" id="LTS" onclick="GetButton()">
        OFF
      </button>
    </div>
  </body>
</html>

Controllino Code:

#include <SPI.h>
#include <Ethernet.h>
#include <SD.h>
#define REQ_BUF_SZ   60

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192, 168, 0, 2);
EthernetServer server(80);
File webFile;
char HTTP_req[REQ_BUF_SZ] = {0};
char req_index = 0;
boolean LTS = {0};

void setup()
{
    // disable Ethernet chip
    pinMode(10, OUTPUT);
    digitalWrite(10, HIGH);
    
    Serial.begin(9600);
    
    // initialize SD card
    Serial.println("Initializing SD card...");
    if (!SD.begin(4)) {
        Serial.println("ERROR - SD card initialization failed!");
        return;
    }
    Serial.println("SUCCESS - SD card initialized.");
    // check for index.htm file
    if (!SD.exists("index.htm")) {
        Serial.println("ERROR - Can't find index.htm file!");
        return;
    }
    Serial.println("SUCCESS - Found index.htm file.");
    pinMode(9, OUTPUT);
    
    Ethernet.begin(mac, ip);
    server.begin();
}

void loop()
{
    EthernetClient client = server.available();

    if (client) {
        boolean currentLineIsBlank = true;
        while (client.connected()) {
            if (client.available()) {
                char c = client.read(); // r
                if (req_index < (REQ_BUF_SZ - 1)) {
                    HTTP_req[req_index] = c;
                    req_index++;
                }
                if (c == '\n' && currentLineIsBlank) {
                    client.println("HTTP/1.1 200 OK");
                    if (StrContains(HTTP_req, "ajax_inputs")) {
                        client.println("Content-Type: text/xml");
                        client.println("Connection: keep-alive");
                        client.println();
                        setLTS();
                        XML_response(client);
                    }
                    else {
                        client.println("Content-Type: text/html");
                        client.println("Connection: keep-alive");
                        client.println();
                        webFile = SD.open("index.html");
                        if (webFile) {
                            while(webFile.available()) {
                                client.write(webFile.read());
                            }
                            webFile.close();
                        }
                    }
                    Serial.print(HTTP_req);
                    req_index = 0;
                    StrClear(HTTP_req, REQ_BUF_SZ);
                    break;
                }
                if (c == '\n') {
                    currentLineIsBlank = true;
                } 
                else if (c != '\r') {
                    currentLineIsBlank = false;
                }
            }
        }
        delay(1);    
        client.stop(); 
    } 
}

void setLTS(void)
{
    // LTS (pin 9)
    if (StrContains(HTTP_req, "LTS=1")) {
        LTS_state = 1;                                               // save LTS state
        digitalWrite(9, HIGH);
    }
    else if (StrContains(HTTP_req, "LTS=0")) {
        LTS_state = 0;                                            // save LTS state
        digitalWrite(9, LOW);
    }
}

// send the XML file with switch status

void XML_response(EthernetClient cl)
{
    int count;                                                      // used by 'for' loops

    
    cl.print("<?xml version = \"1.0\" ?>");
    cl.print("<inputs>");
    
    // checkbox LTS states
    cl.println("</LTS>");
    // LTS
    cl.print("<LED>");
    if (LTS) {
        cl.print("on");
    }
    else {
        cl.print("off");
    }
    cl.println("</LTS>");
    
    cl.print("</inputs>");
}

// sets every element of str to 0 (clears array)


void StrClear(char *str, char length)
{
    for (int i = 0; i < length; i++) {
        str[i] = 0;
    }
}

// searches for the string sfind in the string str
// returns 1 if string found
// returns 0 if string not found
char StrContains(char *str, char *sfind)
{
    char found = 0;
    char index = 0;
    char len;

    len = strlen(str);
    
    if (strlen(sfind) > len) {
        return 0;
    }
    while (index < len) {
        if (str[index] == sfind[found]) {
            found++;
            if (strlen(sfind) == found) {
                return 1;
            }
        }
        else {
            found = 0;
        }
        index++;
    }

    return 0;
}

Problem:
Sobald ich das SD Karten Modul das erste mal anschließe und das Beispiel “SD Cardinfo” hochlade, funktioniert alles einwandfrei und die SD Karte wird erkannt. Wenn ich danach meinen Controllino Code hochlade, wird die SD Karte auch noch erkannt. Doch sobald ich die SD Karte aus dem Slot herausnehme, am PC anschließe und die HTML Datei darauf kopiere, wird bei erneutem Test, egal ob mit eigenem Programm oder Cardinfo, die SD Karte nicht mehr erkannt.
Zur Behebung des Problems habe ich bereits versucht die HTML Datei wieder zu löschen und die SD Karte zu formatieren (nicht nur Schnellformatierung). Zusätzlich habe ich mir zwei weitere SD Kartenleser und zwei weitere Micro SD Karten gekauft. Jedoch sind alle Versuche vergeblich gescheitert und aus diesem Grund wende ich mich nun an die Community und hoffe mir kann jemand bei meinem Problem helfen.


Schon einmal vielen Dank im Voraus für alle Tipps und Hilfestellungen!

Grüße,
Tobias Klaus

funktionierende Links
SD Kartenmodul
SD Karte

Moko:
funktionierende Links
SD Kartenmodul
SD Karte

Bei mir funktionieren alle Links. Welche Meldung kommt bei dem ersten Link?

Der Link zum Controllino ist der einzige der funktioniert, die anderen sind "leer"

man sieht den Fehler auch schon im Quelltext:

[iurl=https://www.controllino.shop/p/controllino-maxi]Controllino Maxi[/iurl]


[iurl="http://\"http://\\"http://\\"https://www.az-delivery.de/products/copy-of-spi-reader-micro-speicherkartenmodul-fur-arduino?variant=38523274578&gclid=CjwKCAjw1v_0BRAkEiwALFkj5iOywsdDInxYoizHinr522eqUgY5YsTPiHTrzCinWtHL1QUjnoLxGhoC9_sQAvD_BwE""]SD Karten Modul[/iurl]


[iurl="http://\"http://\\"http://\\"https://www.reichelt.de/microsdhc-speicherkarte-4gb-transcend-class-10-ts4gusdc10-p261368.html?PROVID=2788&gclid=CjwKCAjw1v_0BRAkEiwALFkj5i9f36tBAusIpWWARwGokytyTVHuYd1EYuxlA8TXrJqVo-YZqaawrBoCgJQQAvD_BwE&&r=1""]4GB SD Karte von Transcend[/iurl]

Moko:
Der Link zum Controllino ist der einzige der funktioniert, die anderen sind "leer"

man sieht den Fehler auch schon im Quelltext:

[iurl=https://www.controllino.shop/p/controllino-maxi]Controllino Maxi[/iurl]

[iurl="http://"http://\"http://\"https://www.az-delivery.de/products/copy-of-spi-reader-micro-speicherkartenmodul-fur-arduino?variant=38523274578&gclid=CjwKCAjw1v_0BRAkEiwALFkj5iOywsdDInxYoizHinr522eqUgY5YsTPiHTrzCinWtHL1QUjnoLxGhoC9_sQAvD_BwE""]SD Karten Modul[/iurl]

[iurl="http://"http://\"http://\"TS4GUSDC10: MicroSDHC-Speicherkarte 4GB, Transcend, Class 10 bei reichelt elektronik""]4GB SD Karte von Transcend[/iurl]

Danke für die Info, sollte jetzt funktionieren!

Du verwendest in deinem Sketch einen anderen CS-Pin als in deiner Beschreibung zu Anschaltung.

HotSystems:
Du verwendest in deinem Sketch einen anderen CS-Pin als in deiner Beschreibung zu Anschaltung.

Das ist nicht ganz richtig, da sich der Name Digital 2 auf den Controllino Pin bezieht, welcher mit Pin 4 am Arduino Board angeschlossen ist. (siehe Foto im Anhang)

Und wie bereits erwähnt funktioniert es beim ersten mal, also kann es nicht am Pinselect liegen.

Könnte das Dein Problem/Lösung sein:

Veränderung an der sd.cpp ?

Grüße
Jörg

Joerg_L:
Könnte das Dein Problem/Lösung sein:

https://forum.arduino.cc/index.php?topic=409527.msg2820282#msg2820282

Veränderung an der sd.cpp ?

Grüße
Jörg

Leider Hilft mir das auch nicht weiter. Habe gerade die SdFat Libary herunter geladen, jedoch funktioniert es mit dem SdInfo Beispiel auch nicht.

In dem anderen Forenbeitrag wurde beschrieben, dass die SD Karte beim herausziehen "durcheinander" kommen könnte. Kann es daran liegen, dass es immer nur beim ersten mal funktioniert hat und deshalb der Controllino nicht mehr mit der SD Karte bzw. mit dem SD Kartenmodul kommunizieren kann?

Ich sehe nirgends, dass Du SD.end() aufrufst, bevor Du die Karte entnimmst.
Das normale Vorgehen ist: Taster --> SD.end() -->LED signalisiert -> SD wechseln -> Taster -->SD.begin(...)

Gruß Tommy

hm, in meinem Programm was ich mal gemacht hatte (https://forum.arduino.cc/index.php?topic=491121.0) da funktioniert nach Anpassen der sd.cpp das Wechseln der SD Karte in laufenden Betrieb.
Das ging davor auch nicht.

Grüße Jörg