Ethernet und SD Karte gleichzeitig nutzen - mit dem Ethernetshield

Hallo,
Die meisten werden sagen, das muss man den Pin4 und Pin10 switchen.
Und gleichzeitig funktioniert das schon mal gar nicht.

Meine Frage bezieht sich auf dies Displaying a Web Page with Image using the Arduino Ethernet Shield and SD Card

Dort wird dies offensichtlich gemacht.
Und z.b in dieser Zeile der gemeinsame Zugriff:

 client.write(webFile.read()); // send web page to client

Um es vorweg zu nehmen, es funktioniert bei mir auch nicht.
Aber offensichtich funktioniert es in diesen TUT - stehe gerade etwas auf dem Schlauch

Nachtrag: Sorry weiter unten läuft ein ähnlicher Thread, den habe ich nicht gesehen.

Mit der richtigen Bibliotheken funktioniert das. Steht in der Beschreibung irgendwo, welche Bibliotheken verwendet werden?
Grüße Uwe

Hallo Uwe:
Ich finde nur das...

 References: WebServer example by David A. Mellis and 
                  modified by Tom Igoe
                - SD card examples by David A. Mellis and
                  Tom Igoe
                - Ethernet library documentation:
                  http://arduino.cc/en/Reference/Ethernet
                - SD Card library documentation:
                  http://arduino.cc/en/Reference/SD

#include <SPI.h>
#include <Ethernet.h>
#include <SD.h>

Das sind doch Standard Lib's oder ? - zudem verwende ich Arduino 1.0.4, das TUT bezieht sich auf 1.0.3

Wenn du aber sicher bist, das es funktioniert muss ich die Lib's noch genauer ansehen.
War voher eher der Meinung das dies nicht funktionieren kann, da zwei Devices an einem Bus gleichzeitig aktiv sind

...also ich habe den Arduino Ethernet bzw. den Arduino Mega mit Ethernet/SD Shield damit am laufen
das ich vor jedem Abschnitt wo ich auf's Ethernet oder die SD-Karte zugreife den CS (Pin 10 und Pin 4)
gezielt mit dem Aufruf folgender Funktionen einstelle:

//################# Chip-Select ansteuern ###################################
void selETH() { // waehlt den Ethernetcontroller aus

digitalWrite(SDselect, HIGH);
digitalWrite(ETHselect, LOW);

}
//####################################
void selSD() { // waehlt die SD-Karte aus

digitalWrite(ETHselect, HIGH);
digitalWrite(SDselect, LOW);

}

//#################################
void selCLK() { // waehlt die RTC aus bzw. sperrt Ethernet und SD-Karte

digitalWrite(SDselect, HIGH);
digitalWrite(ETHselect, HIGH);

}
##########################################################################

...das sieht dann z.B. so aus:

selSD(); // CS auf SD Card setzen
dataFile = SD.open(WDLfile, FILE_WRITE);

Mit dieser Vorgehensweise läuft meine Applikation Wochenlang durch ohne Abstürtze... :wink:

@Bitklopfer: Du machst in deinem Programm IHMO was anderes.

Die Zeile:
dataFile = SD.open(WDLfile, FILE_WRITE);
Hat hier nichts mit dem Ethernet Controller zu tun, deshalb funktioniert dies bei dir, wenn du den Ethernet Controller deaktivierst und die SD Karte aktivierst.

Bei mir schaut es aber so aus:

EthernetClient client;
File webFile;
....
client.write(webFile.read()); // send web page to client

In diesem Fall wird der Inhalt einer Datei auf die HTML Seite kopiert, man braucht also beide Devices quasi gleichzeitig.
Klar kann das nicht gehen, aber in dem Beispielcode aus meiner erstem Posting wird es so gemacht.

Ohne Pin 10 oder 4 anzufassen. Dies wird wohl in der SD oder Ethernet Lib geregelt.
Da der Code in dem Beispiel aber so läuft, liegt der Verdacht nahe das ich die falsche Version der Lib benutze.

Ich habe deinen Vorschlag schon ausprobiert, funktioniert nicht.
Wie auch, wenn ich den Ethernet aktiv ist die SD deaktiv und umgekehrt.

rudirabbit:
In diesem Fall wird der Inhalt einer Datei auf die HTML Seite kopiert, man braucht also beide Devices quasi gleichzeitig.
Klar kann das nicht gehen, aber in dem Beispielcode aus meiner erstem Posting wird es so gemacht.

Ohne Pin 10 oder 4 anzufassen. Dies wird wohl in der SD oder Ethernet Lib geregelt.

Ja, "ohne Pin 10 oder 4 anzufassen" scheint wohl tatsächlich zu funktionieren, wenigstens mit manchen Funktionen der SD- und Ethernet-Library und wenn man sich an bestimmte Reihenfolgen und Funktionen hält, scheinen es die Libraries selbst zu managen, darauf deuten auch von mir durchgeführte Tests hin.

Aber: Das von Dir verlinkte Programm ist doch irgendwie ein Fake, denn es läuft auf einem UNO plus Ethernet-Shield plus den verwendeten Beispieldateien plus einem Standard-Desktop-Webbrowser (hier verwendet: Google-Chrome) trotzdem nicht. Und zwar aus dem Grund: RAM-Speichermangel.

Bei meinen Tests mit dem von Dir verlinkten Programm ist es so, daß die von einem Standard-Webbrowser gesendeten HTTP-Header so lang sind, dass
String HTTP_req = ""; // stores the received HTTP request
...
HTTP_req += c; // save HTTP request character
zum vollständigen Verbrauch des RAM-Speichers beim Einlesen des HTTP-Requests auf einem UNO führt, so dass der Controller bei HTTP-Anfragen wahlweise hängenbleibt oder neu startet, jedenfalls nicht das macht, was er machen soll. Sprich: Ein UNO hat zu wenig RAM-Speicher!

Der Code könnte ggf. mit kleinen Anpassungen im Quellcode auf einem Controller mit mehr RAM-Speicher laufen, etwa einem MEGA.

Oder bei einer komplett anderen speicherplatzsparenden Programmierung ohne "String" Objekte bei der Auswertung der HTTP-Header zu verwenden.

Oder zusammen mit einem WEB-Browser, der sehr kurze HTTP-Header sendet. Manche Browser kann man z.B, so konfigurieren, dass Sie keinen "User-Agent" String im HTTP-Header mitsenden oder einen "User-Agent" String nach eigenem Wunsch. Jedenfalls: Das gezeigte Youtube-Video vom Funktionieren des Sketches mag unter bestimmten Umständen zutreffen, aber bei Verwendung eines UNO-Boards mit einem Standard-Webbrowsers zum Datenabruf hat das Gesamtsystem zu wenig RAM-Speicher. Und das vor allem, weil im Sketch mit einem String-Objekt der Speicher für nichts und wieder nichts vergeudet wird.

Hi,

Das von Dir verlinkte Programm ist doch irgendwie ein Fake, denn es läuft auf einem UNO plus Ethernet-Shield plus den verwendeten Beispieldateien plus einem Standard-Desktop-Webbrowser (hier verwendet: Google-Chrome) trotzdem nicht. Und zwar aus dem Grund: RAM-Speichermangel.

Ich habe mir HTTP_req auf der seriellen Ausgeben lassen, so viel Zeichen sind das bei mir nicht (Morzilla Firefox und Android Tablett also Chrome)
Bei jedem neuen Request wird der String auch wieder gelöscht.

Den Code habe ich nicht 1:1 aus dem Link übernommen, arbeite aber auch mit der String Class.
Das ist aber nicht das Problem, denn dies läuft bei mir ja.
Sobald der GET request kommt und ich auf die SD greife, hängt der Webserver.

Aber dein Hinweiß, das es auf die Reihenfolge ankommt ist gut, dem werde ich nachgehen.
Es wäre schon gut die HTML Seite auf der SD zu haben.

Es kommt das Arduino Mega Board zum Einsatz, auch wegen des Flash.
Wenn man eine bisschen aufwendigere Website im Sketch hat, wird dieser schnell zu groß für das UNO Board.

Was ich auch noch erwähnen muß, ich verwende kein Orginal Arduino Ethernetshield, meines kommt vom Chinamann.
Habe da auch schon gelesen, das dies nicht 100% kompatibel sein.

rudirabbit:
Den Code habe ich nicht 1:1 aus dem Link übernommen, arbeite aber auch mit der String Class.

Wenn Du das brauchst.
Ich brauche unter Arduino NIEMALS String-Objekte.

rudirabbit:
Was ich auch noch erwähnen muß, ich verwende kein Orginal Arduino Ethernetshield, meines kommt vom Chinamann.
Habe da auch schon gelesen, das dies nicht 100% kompatibel sein.

Meine Ethernet-Shields sind auch alles billigste China-Ware.

Teste mal beiliegenden "Arduino SD-Karten Webserver", der läuft bei mir auf einem UNO mit China-Ethernet-Shield,
anpassen der IP-Adresse an Dein Netzwerk nicht vergessen:

/*
 * This sketch uses the microSD card slot on the Arduino Ethernet shield
 * to serve up files over a very minimal browsing interface
 *
 * Some code is from Bill Greiman's SdFatLib examples,
 * some is from the Arduino Ethernet WebServer example, 
 * some is from Limor Fried (Adafruit),
 * some is from "jurs" for German Arduino forum,
 * so its probably under GPL
 */

#include <SD.h>
#include <SPI.h>
#include <Ethernet.h>

/************ ETHERNET STUFF ************/
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 192, 168, 2, 111 };
EthernetServer server(80);

/************ SDCARD STUFF ************/
Sd2Card card;
SdVolume volume;
SdFile root;
SdFile file;

// store error strings in flash to save RAM
#define error(s) error_P(PSTR(s))

void error_P(const char* str) {
  PgmPrint("error: ");
  SerialPrintln_P(str);
  if (card.errorCode()) {
    PgmPrint("SD error: ");
    Serial.print(card.errorCode(), HEX);
    Serial.print(',');
    Serial.println(card.errorData(), HEX);
  }
  while(1);
}

char* strupper( char* s )
// helper function char array to uppercase letters
{
  for (char* p = s; *p; ++p)
    *p = toupper( *p );
  return s;
}

char* strlower( char* s )
// helper function char array to lowercase letters
{
  for (char* p = s; *p; ++p)
    *p = tolower( *p );
  return s;
}

void setup() {
  Serial.begin(9600);
 
  PgmPrint("Free RAM: ");
  Serial.println(FreeRam());  
  
  // initialize the SD card at SPI_HALF_SPEED to avoid bus errors with
  // breadboards.  use SPI_FULL_SPEED for better performance.
  pinMode(10, OUTPUT);                       // set the SS pin as an output (necessary!)
  digitalWrite(10, HIGH);                    // but turn off the W5100 chip!

  if (!card.init(SPI_HALF_SPEED, 4)) error("card.init failed!");
  
  // initialize a FAT volume
  if (!volume.init(&card)) error("vol.init failed!");

  PgmPrint("Volume is FAT");
  Serial.println(volume.fatType(),DEC);
  Serial.println();
  
  if (!root.openRoot(&volume)) error("openRoot failed");

  // list file in root with date and size
  PgmPrintln("Files found in root:");
  root.ls(LS_DATE | LS_SIZE);
  Serial.println();
  
  // Recursive list of all directories
  PgmPrintln("Files found in all dirs:");
  root.ls(LS_R);
  
  Serial.println();
  PgmPrintln("Done");
  
  // Debugging complete, we start the server!
  Ethernet.begin(mac, ip);
  server.begin();
}

void ListFiles(EthernetClient client, uint8_t flags) {
  // This code is just copied from SdFile.cpp in the SDFat library
  // and tweaked to print to the client output in html!
  dir_t p;
  
  root.rewind();
  client.println("<ul>");
  while (root.readDir(p) > 0) {
    // done if past last used entry
    if (p.name[0] == DIR_NAME_FREE) break;

    // skip deleted entry and entries for . and  ..
    if (p.name[0] == DIR_NAME_DELETED || p.name[0] == '.') continue;

    // only list subdirectories and files
    if (!DIR_IS_FILE_OR_SUBDIR(&p)) continue;

    // print any indent spaces
    client.print("<li><a href=\"");
    for (uint8_t i = 0; i < 11; i++) {
      if (p.name[i] == ' ') continue;
      if (i == 8) {
        client.print('.');
      }
      client.print((char)p.name[i]);
    }
    client.print("\">");
    
    // print file name with possible blank fill
    for (uint8_t i = 0; i < 11; i++) {
      if (p.name[i] == ' ') continue;
      if (i == 8) {
        client.print('.');
      }
      client.print((char)p.name[i]);
    }
    
    client.print("</a>");
    
    if (DIR_IS_SUBDIR(&p)) {
      client.print('/');
    }

    // print modify date/time if requested
    if (flags & LS_DATE) {
       root.printFatDate(p.lastWriteDate);
       client.print(' ');
       root.printFatTime(p.lastWriteTime);
    }
    // print size if requested
    if (!DIR_IS_SUBDIR(&p) && (flags & LS_SIZE)) {
      client.print(' ');
      client.print(p.fileSize);
    }
    client.println("</li>");
  }
  client.println("</ul>");
}

// How big our line buffer should be. 100 is plenty!
#define BUFSIZ 100

void loop()
{
  char clientline[BUFSIZ];
  int index = 0;
  
  EthernetClient client = server.available();
  if (client) {
    // an http request ends with a blank line
    boolean current_line_is_blank = true;
    
    // reset the input buffer
    index = 0;
    
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        
        // If it isn't a new line, add the character to the buffer
        if (c != '\n' && c != '\r') {
          clientline[index] = c;
          index++;
          // are we too big for the buffer? start tossing out data
          if (index >= BUFSIZ) 
            index = BUFSIZ -1;
          
          // continue to read more data!
          continue;
        }
        
        // got a \n or \r new line, which means the string is done
        clientline[index] = 0;
        
        // Print it out for debugging
        Serial.println(clientline);
        
        // Look for substring such as a request to get the root file
        if (strstr(clientline, "GET / ") != 0) {
          // send a standard http response header
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println();
          
          // print all the files, use a helper to keep it clean
          client.println("<h2>Files:</h2>");
          ListFiles(client, LS_SIZE);
        } else if (strstr(clientline, "GET /") != 0) {
          // this time no space after the /, so a sub-file!
          char *filename;
          
          filename = clientline + 5; // look after the "GET /" (5 chars)
          // a little trick, look for the " HTTP/1.1" string and 
          // turn the first character of the substring into a 0 to clear it out.
          (strstr(clientline, " HTTP"))[0] = 0;
          
          // print the file we want
          Serial.println(filename);

          if (! file.open(&root, filename, O_READ)) {
            client.println("HTTP/1.1 404 Not Found");
            client.println("Content-Type: text/html");
            client.println();
            client.println("<h2>File Not Found!</h2>");
            break;
          }
          
          Serial.println("Opened!");
          strlower(filename);          
          client.println("HTTP/1.1 200 OK");
          if (strstr(filename,".htm")!=NULL)
            client.println("Content-Type: text/html");
          else if (strstr(filename,".jpg")!=NULL)
            client.println("Content-Type: image/jpg");
          else  
            client.println("Content-Type: text/plain");
          client.println();
          
          int16_t c;
          while ((c = file.read()) >= 0) {
              // uncomment the serial to debug (slow!)
              //Serial.print((char)c);
              client.print((char)c);
          }
          file.close();
        } else {
          // everything else is a 404
          client.println("HTTP/1.1 404 Not Found");
          client.println("Content-Type: text/html");
          client.println();
          client.println("<h2>File Not Found!</h2>");
        }
        break;
      }
    }
    // give the web browser time to receive the data
    delay(1);
    client.stop();
  }
}

Wenn Du keine Datei aufrufst, zeigt der Server ein Dateilisting mit anklickbaren Dateinamen an. Dateinamen mit der Endung .htm werden als HTML gesendet, Dateinamen mit der Endung .jpg als Bild und Dateinamen mit der Endung .txt als einfacher Text. Unbekannte Dateiendungen werden ebenfalls als einfacher Text gesendet, aber zumindest unter Windows werden die Browser die Datei dann wohl trotzdem downloaden statt anzeigen.

Probier's mal aus, ob das bei Dir läuft!

Probier's mal aus, ob das bei Dir läuft!

Thx !
Das läuft, Hardware also in Ordnung.

Jetzt muss ich nur rausfinden was im meinem Code nicht passt, in deinem Code werden aber die CS Pins angefasst.
Muss deinen Code mal genauer ansehen, wie das CS Handling dort gemacht wird.

@jurs:

Ich brauche unter Arduino NIEMALS String-Objekte.

Hast ja recht, ich komme aus der Delphi (Pascal) Richtung, und wollte bei den Strings nicht mit Char Arrays arbeiten.
Der Ressouren auf dem Atmels sind nicht so groß, deshalb macht das Sinn.

  filename = clientline + 5; // look after the "GET /" (5 chars)
          // a little trick, look for the " HTTP/1.1" string and 
          // turn the first character of the substring into a 0 to clear it out.
          Dies --->   (strstr(clientline, " HTTP"))[0] = 0;

Ich finde diese Stelle im Code schon interessant, wie das Einfluss auf filename hat.
Aber schon verstanden.

Bei deinem Code wird mit SdFile file gearbeitet.
In meinem verlinktem Code jedoch mit File file.

SdFile und File sind wohl beide in der SD Lib definiert ....

rudirabbit:
@Bitklopfer: Du machst in deinem Programm IHMO was anderes.

Die Zeile:
dataFile = SD.open(WDLfile, FILE_WRITE);
Hat hier nichts mit dem Ethernet Controller zu tun, deshalb funktioniert dies bei dir, wenn du den Ethernet Controller deaktivierst und die SD Karte aktivierst.

Bei mir schaut es aber so aus:

EthernetClient client;

File webFile;
....
client.write(webFile.read()); // send web page to client




In diesem Fall wird der Inhalt einer Datei auf die HTML Seite kopiert, man braucht also beide Devices quasi gleichzeitig.
Klar kann das nicht gehen, aber in dem Beispielcode aus meiner erstem Posting wird es so gemacht.

Ohne Pin 10 oder 4 anzufassen. Dies wird wohl in der SD oder Ethernet Lib geregelt. 
Da der Code in dem Beispiel aber so läuft, liegt der Verdacht nahe das ich die falsche Version der Lib benutze.

Ich habe deinen Vorschlag schon ausprobiert, funktioniert nicht.
Wie auch, wenn ich den Ethernet aktiv ist die SD deaktiv und umgekehrt.

NEIN...ich mache genau das....
und zwar umschalten zwischen SD und Ethernet und genau bevor ich auf eines der Teile zugreife
kommt der entsprechende Aufruf von selSD() oder selETH() vorher in eine Zeile rein.

WEIL du kannst nicht beide Teile GLEICHzeitig aktivieren...das gibt Totsicher einen Crahs auf dem SPI Bus. DAS ist nunmal SO !

Also du kannst entweder die SD ansprechen oder den ETH und wenn du dazwischen Daten rumschaufeln willst dann mußt die notgedrungen in einer Variablen zwischenspeichern. Und wie schon gesagt bei mir läuft das so schon Wochenlang...
Hier ist auf einem Mega2560 Board das ETH Shield mit SD installiert und obendrauf noch ein LCD Shield mit Tasten.
Die erfassten Analogwerte werden auf der SD abgelegt und können per Web auch abgefragt werden. Und jedesmal wenn
nach 50.000 Datensätzen ein neuer Datenfile generiert wird dann wird die aktuelle Zeit epoch/Unix von einem NTP Server
abgefragt und der interne Sekundenzähler aktuallisiert.

Also nochmals Chipselects sind dazu da auszuwählen auf welchen Busteilnehmer die CPU zugreifen kann.
Im Auto kannst du auch nicht gleichzeitig 2 Gänge einlegen....oda...

rudirabbit:
Hast ja recht, ich komme aus der Delphi (Pascal) Richtung, und wollte bei den Strings nicht mit Char Arrays arbeiten.
Der Ressouren auf dem Atmels sind nicht so groß, deshalb macht das Sinn.

Nicht nur deshalb. String-Objekte sind unter Arduino fehlerhaft implementiert. Wenn Du es selbst mal testen möchtest: In 125khz rfid Reader - char* / char[] - Deutsch - Arduino Forum habe ich als Reply #28 mal einen kurzen Testcode gepostet, der innerhalb einer Schleife von nur 100 Schleifendurchläufen mit Verwendung von String-Objekten abstürzt (getestet mit Arduino Versionen bis 1.0.3), d.h. das Schleifenende nicht erreicht. Solche Dinge kannst Du nicht für Programme verbrauchen, die stunden-, tage-, wochen- und monatelang durchlaufen sollen. Deshalb willst Du keine String-Objekte, wenn Du zuverlässig funktionierende Programme möchtest. Darüber hinaus arbeiten sämtliche Funktionen der C-Standardlibrary mit C-Strings (char Arrays) und nicht mit String-Objekten.

Bitklopfer:
WEIL du kannst nicht beide Teile GLEICHzeitig aktivieren...das gibt Totsicher einen Crahs auf dem SPI Bus. DAS ist nunmal SO !

Ja. Trotzdem mußt Du den Code dafür nicht unbedingt in den Sketch reinschreiben, weil der Code dafür teilweise schon in den Libraries drinsteht.

Dass ich oben in Reply #7 einen völlig einwandfrei funktionierenden "Arduino SD-Karten Webserver" gepostet habe, hast Du gesehen?

Am Beispiel der Ethernet-Library z.B. steht der notwendige Code innerhalb der Quellcodedatei w5100.cpp, wo die Funktionen dann z.B. so aussehen:

uint8_t W5100Class::write(uint16_t _addr, uint8_t _data)
{
  setSS();  
  SPI.transfer(0xF0);
  SPI.transfer(_addr >> 8);
  SPI.transfer(_addr & 0xFF);
  SPI.transfer(_data);
  resetSS();
  return 1;
}

D.h. beim Aufrufen von "write" wird zu Anfang mit "setSS();" der Ethernet-Chip aktiviert, am Ende der Funktion wird er mit "resetSS();" wieder deaktiviert, zwischendurch wird der Transfer über den SPI Bus durchgeführt. D.h. Du rufst im Sketch nur "client.write" auf und automatisch wird von der Library das angesprochene Gerät aktiviert.

Ja. Trotzdem mußt Du den Code dafür nicht unbedingt in den Sketch reinschreiben, weil der Code dafür teilweise schon in den Libraries drinsteht.

Was eben in meinem Fall nicht funktionierte weil die Reihenfolge wohl nicht passte und somit beide CS Pin der Devices die an einem Bus liegen aktiv(low) sind.
Also besser selbst drum kümmern.
Wie Bitklopfer schon sagte, erst die Daten von der SD im wertvollem Ram des AVR's speichern und dann vom dort aus zum Ethernet.

Das heißt man kann keine größere Datenmengen die > des gerade freien Ram des AVR sind zum Ethernet übertragen. Das ist eher suboptimal.
Evtl. dann aufteilen.

Also nochmals Chipselects sind dazu da auszuwählen auf welchen Busteilnehmer die CPU zugreifen kann.

Das war mir im Prinzip schon klar, hatte ich auch so in etwa im Eingangsposting drin.

Es war der Beispielcode aus dem Link in meinem Eingangsposting - ob es evtl, einen Trick gibt dies zu umgehen.

Im Auto kannst du auch nicht gleichzeitig 2 Gänge einlegen....oda...

Klar geht das ;-), dazu must den Schaltautomat ausbauen, dann kannst du zwei Schiebemuffen gleichzeitig mit einem Schaltrad verbinden.
Dies führt zum Blockieren des Getriebes - oder wie hier zum Blockieren des SPI.

rudirabbit:
Wie Bitklopfer schon sagte, erst die Daten von der SD im wertvollem Ram des AVR's speichern und dann vom dort aus zum Ethernet.

Ja, diese Sendeschleife mit der Logik "ein Byte lesen - ein Byte senden" ist natürlich furchtbar ineffektiv und langsam:

 while ((c = file.read()) >= 0) {
              // uncomment the serial to debug (slow!)
              //Serial.print((char)c);
              client.print((char)c);
          }

Da macht man besser eine Logik "100 Bytes lesen - 100 Bytes senden" oder sowas in der Art draus, um größere Dateien zu senden und dabei eine deutliche Geschwindigkeitssteigerung zu erzielen, wenn gleich ein ganzer Datenblock an den Ethernet-Chip übergeben wird.

Also ich habe das komplette Tutorial erst vor kurzem durchgearbeitet, hat alles genauso wie beschrieben funktioniert, zumindest mit den Mega2560+EthernetShield. Habe die Standardbibliotheken von 1.0.3 verwendet, zwischenzeitlich verwende ich für mein angepassten Sketch die 1.0.4.

Im Part 16 wird auch auf das RAM-Problem vom UNO hingewiesen und eine Lösung mit einem Puffer vorgeschlagen...

Wenn du den Code 1:1 kopierst, sollte er eigentlich laufen, aber da hast du auch schon Probleme oder wie?

Spexx:
Wenn du den Code 1:1 kopierst, sollte er eigentlich laufen, aber da hast du auch schon Probleme oder wie?

Das habe ich noch nicht gemacht, weil obsolet. Ich habe die selbe Hardware wie du, deshalb denke ich das dies auch bei mir laufen würde.

Meine Frage in dem Thread ging eher dahin, in dem Beipiel Code schaut es so aus als ob beide Devices gleichzeitig benutzt werden.
Ich habe Teile des Code in meinem Projekt getestet und das ging nicht, da die Lib's im Hintergrund die CS Lines der beiden Devices nicht richtig schalten.

Wenn man dies sauber Programmieren will, sollte man sich besser den Vorschag von jurs ansehen.

Hallo,

ich würde meinem Hausautomations-Arduino gerne eine Weboberfläche hinzufügen.

So wie ich es interpretiere, müsste ich hierfür dann nicht nur Gebrauch von der Ethernetschnittstelle, sondern auch vom SD-Kartenslot machen.

Habt Ihr mir evtl. Tipps, wie ich Probleme mit dem "Nadelöhr SPI-Schnittstelle" vermeiden kann?

Frohe Weihnachten Euch allen! :kissing:

Chris

[NETCOP]
Bitte keine fremden Threads hijacken.
[/NETCOP]

Habt Ihr mir evtl. Tipps, wie ich Probleme mit dem "Nadelöhr SPI-Schnittstelle" vermeiden kann?

  1. Einen µC mit 2 SPI Schnittstellen verwenden.
  2. Problem akzeptieren und damit leben.

Übrigens:
Welche Probleme hättest du denn gerne?