Gixxer:
... nicer and more updated one....
I'll start with a way of implementing the "updated" part. Someone else can make it "nicer."
I started with the Ethernet library WebClient example in arduino-0022. I added a few lines from the SD library DataLogger example to open a file and store the bytes in the SD card on the Ethernet Shield.
By building on "official" Arduino library examples rather than just making up a bunch of stuff on my own, my hope is that maybe the result will be useful as a reference that can be maintained more easily as the Arduino stuff evolves over subsequent releases.
Note, particularly, that with the Arduino libraries, the application sketch does not have to manipulate any of the chip select pins for alternating between accesses to the two different SD devices. Really.
I mean, I have seen some postings where people made flat statements that you had to clutter up your sketches with all of that stuff, but you don't have to. Really. The libraries take care of that.
I have used multiple SPI devices in other applications, but since this thread is about the Ethernet Shield, that's what the following simple example is for.
/*
EthernetSD.pde
A note from davekw7x:
Code in this sketch combines code from two examples in arduino-0022:
The Ethernet library WebClient example sketch
created 18 Dec 2009
by David A. Mellis
No licensing or copyright information was explicitly given
in the sketch, but it is part of the Arduino distribution,
so this little program inherits whatever restrictions are
in effect for Arduino.
The SD library DataLogger example sketch:
created 24 Nov 2010
updated 2 Dec 2010
by Tom Igoe
That author graciously released the DataLogger code to public domain,
and I do the same for whatever few lines that I have created for this example
Citation would be the Polite Thing To Do, but is not really expected.
Regards,
davekw7x
*/
/*
Web client example sketch from arduino-0022 with a few lines
added by davekwy7x to store results of an HTML "get" command
in a file on SD.
Tested with genuine Arduino Ethernet Shield Version 5
(the one with the microSd connector) and a genuine Arduino
Duemilanove.
My local net is served by a Linux machine with IP address 10.10.5.1,
and it has an Apache web server configured in a completely conventional
manner.
There is a file named "test.php" in /var/www/html/daves.
The contents of the file are between the dashed lines
------------------------------------------
<html>
<head>
<Title>test.php</title>
<body>
<?php
print 'Hello, World!
';
print 'From /var/www/html/daves';
?>
</body>
------------------------------------------
After running this sketch you can take the SD card from
the Ethernet Shield and read it on your PC (or whatever).
Or you can run the SD library DumpFile example (after
changing the file name in that sketch to match the
file name in this one).
davekw7x
March, 2011
*/
#include <SD.h>
#include <SPI.h>
#include <Ethernet.h>
const int SD_CHIP_SELECT = 4; // For the Ethernet Shield
const int ETHERNET_CHIP_SELECT = 10;
//
// Enter a MAC address and IP address for your controller below.
//
// A "private" MAC address that will never be part
// of any commercial product, so shouldn't conflict
// with anything on your net (unless you are running
// something else like this that you have given
// this identical MAC address.)
byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
//
//IP address for my sandbox LAN with an Apache web server
// Change the following to whatever addresses are
// appropriate for your testing.
//
byte ip[] = {10, 10, 5, 177};
byte server[] = {10, 10, 5, 1};
//
//HTML command to get a PHP file located in /var/www/html/daves on
// my webserver machine.
// Change it for whatever you want to test it with.
//
char htmlCommand[] = "GET /daves/test.php";
//
// Initialize the Ethernet client library
// with the IP address and port of the server
// that you want to connect to (port 80 is default for HTTP),
// and is used by my Apache server.
//
Client client(server, 80);
//
// Define the file name and file here so that it can be used
// in both setup() and loop()
char filename[] = "webfile.txt";
File dataFile;
void setup() {
//
// Start the serial library.
Serial.begin(9600);
//
// Give things a second to settle down.
delay(1000);
Serial.print("Initializing SD card...");
//
// Make sure that the default chip select pin is set to
// output, even if you don't use it. (Note
// from davekw7x: This isn't really necessary
// here, since the library takes care of it,
// but it doesn't hurt.)
pinMode(ETHERNET_CHIP_SELECT, OUTPUT);
digitalWrite(ETHERNET_CHIP_SELECT, HIGH);
//
// See if the card is present and can be initialized.
if (!SD.begin(SD_CHIP_SELECT)) {
Serial.println("Card failed, or not present");
//
// exit() disables interrupts and enters
// a do-nothing forever loop
exit(1); // Value is irrelevant
}
Serial.println("card initialized.");
//
// Open the file.
dataFile = SD.open(filename, FILE_WRITE);
if (!dataFile) {
Serial.println("Can't open ");Serial.print(filename);
Serial.println(" for writing.");
exit(1);
}
Serial.print("Opened file ");Serial.print(filename);
Serial.println(" for writing.");
//
// Start the Ethernet connection.
Ethernet.begin(mac, ip);
Serial.println("Connecting...");
// If it couldn't connect, bail out
if (!client.connect()) {
Serial.println("Connection failed.");
exit(1);
}
// OK! Now ready for action.
Serial.println("Connected!");
// Make the HTTP request.
client.println(htmlCommand);
client.println();
// Return from setup() so that the results of
// the request can be handled in loop()
}
void loop()
{
// If there are incoming bytes available
// from the server, read them and print
// them and store then in the SD file.
if (client.available()) {
char c = client.read();
Serial.print(c);
dataFile.print(c);
}
//
// If the server is disconnected, stop the client and close the file
if (!client.connected()) {
Serial.println();
Serial.println("Disconnecting.");
client.stop();
Serial.print("Closing file ");Serial.println(filename);
dataFile.close();
Serial.println("Program is complete.");
exit(0);
}
// Client is still connected.
// Loop back for more bytes.
}
Note that the argument to open a file for writing is "FILE_WRITE" and is documented on the Arduino SD reference page. If the file does not exist, it creates a new file. If the file already exists, it appends new stuff to it. Other arguments are possible and are documented in the SdFat library, for which the Arduino SD library is a wrapper.
I have tested this with a couple of microSD cards that I have (1 GigaByte and 4 GigaByte). They came formatted "FAT32." I had no reason re-format them, so I left the formatting alone. I can read and write them in any of the various card readers on my Windows XP and my Linux workstations.
Bottom line recommendations:
1. Don't even think of trying my little program unless (and until) you can successfully run the SD DataLogger and SD FileDump examples. That way you can verify that the required SD functionality is present with your setup.
2. For the Ethernet stuff, I would probably start with the WebServer example before going to WebClient. That way you can make sure your Ethernet setup works before you try to get some HTML stuff from a web server. At any rate, make sure that WebClient works by itself before trying to combine its code with other stuff.
3. For other kinds of Ethernet applications and other kinds of SD applications (SD reading from a file to use with a WebServer, for example), you can try doing the same as I did: Test each one using Arduino library examples or make your own examples. After each one is working (perfectly), then (and only then) try to combine them.
Regards,
Dave
Footnote
To whom it may concern:
The subject of this thread when it started was about combining Ethernet and SD functions on an Ethernet Shield. I respectfully suggest that you verify correct operations of both Ethernet and SD stuff before trying to combine them. If you have problems with one or other of the separate functions, I respectfully suggest that you confer with other posts in this forum (or start your own thread) instead of tacking stuff to this one.