Problem getting Wifi Webserver and SD card working together

Hi,

I’m using an Arduino Uno with the official Wifi shield. I would like to run a web server that reads a file from the SD card when a specific URL is requested.

So I’m able to successfully connect to my Wifi network and also responds to URL requests I make from a browser on my computer.

I’m running into problems when trying to read from the SD card. When I read from the SD card in a seperate sketch, without using Wifi, it works fine.

According to the documentation SD and Wifi share the SPI bus. Here is the portion of the documentation:

Note that because the HDG104 and SD card share the SPI bus, only one can be active at a time. If you are using both peripherals in your program, this should be taken care of by the corresponding libraries. If you’re not using one of the peripherals in your program, however, you’ll need to explicitly deselect it. To do this with the SD card, set pin 4 as an output and write a high to it. For the HDG104, set digital pin 10 as a high output.

So I thought that I have to do the following to switch between SD and Wifi:

    // Switch to SD 
    digitalWrite(10,HIGH);
    digitalWrite(4,LOW);  

    // Read from SD

    // Switch back to Wifi
    digitalWrite(10,LOW);
    digitalWrite(4,HIGH);

Unfortunately that does not work. The http request comes in and as soon as SD.open(“test.txt”) is called the Arduino stops working. Looses Wifi connection and does not accept any subsequent http requests.

Any ideas on how I can get the Wifi to work with the SD card?

Here is the complete code from my sketch: (mostly copied and glued together from the examples)

/*
 Universal Remote - IR Remote control for a smartphone
 */

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

char ssid[] = "myssid";      //  your network SSID (name) 
char pass[] = "mypassword";   // your network password
  
int status = WL_IDLE_STATUS;
WiFiServer server(80);

File currentIRSignalFile;

void setup() {
  Serial.begin(9600);      // initialize serial communication

  pinMode(10, OUTPUT);
  pinMode(4, OUTPUT);

  Serial.print("Initializing SD card...");   
  if (!SD.begin(4)) {
    Serial.println("initialization failed!");
    return;
  }
  Serial.println("initialization done.");

  // check for the presence of the shield:
  if (WiFi.status() == WL_NO_SHIELD) {
    Serial.println("WiFi shield not present"); 
    while(true);        // don't continue
  } 

  // attempt to connect to Wifi network:
  while ( status != WL_CONNECTED) { 
    Serial.print("Attempting to connect to Network named: ");
    Serial.println(ssid);                   // print the network name (SSID);

    // Connect to WPA/WPA2 network. Change this line if using open or WEP network:    
    status = WiFi.begin(ssid, pass);

    // wait 10 seconds for connection:
    delay(10000);
  } 
  server.begin();                           // start the web server on port 80
  printWifiStatus();                        // you're connected now, so print out the status
}

void loop() {
  WiFiClient client = server.available();   // listen for incoming clients
 if (client) {
    Serial.println("new client");    
    String httpResponse = String("IRSIGNAL_NOT_FOUND");
    String httpRequest = "";
    // an http request ends with a blank line
    boolean currentLineIsBlank = true;
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        Serial.write(c);
        httpRequest +=c;
        
        // if you've gotten to the end of the line (received a newline
        // character) and the line is blank, the http request has ended,
        // so you can send a reply
        if (c == '\n' && currentLineIsBlank) {
          
          // I would like to listen to http://<ip address>/IRSignal/IRSignalName
          if (httpRequest.substring(5,13) == "IRSignal") {
            String httpSubRequest = httpRequest.substring(13);
            httpSubRequest.trim();
            String httpCodeRequest = httpSubRequest.substring(httpSubRequest.indexOf('/')+1, httpSubRequest.lastIndexOf("HTTP"));
            httpCodeRequest.trim();
                        
            Serial.print("IR Signal Requested:");
            Serial.println(httpCodeRequest);     
            
            if (httpCodeRequest == "SonyVolumeUp") {
              Serial.println("Trying to read from the SD Card");
              // switch to SD card
              digitalWrite(10,HIGH);
              digitalWrite(4,LOW);  
              
              File signalFile = SD.open("test.txt");
              if (signalFile) {
                Serial.println("IR Signal File found.");
                // read from the file until there's nothing else in it:
                while (signalFile.available()) {
                    Serial.write(signalFile.read());
                }
                // close the file:
                signalFile.close();
              }
              else 
                Serial.println("Error opening file.");
                
              // switch back to Wifi  
              digitalWrite(10,LOW);
              digitalWrite(4,HIGH);   
            }
          }
          
          // send a standard http response header
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/plain");
          client.println("Connnection: close");
          client.println();
          client.println(httpResponse);                   
          break;
        }
        if (c == '\n') {
          // you're starting a new line
          currentLineIsBlank = true;
        } 
        else if (c != '\r') {
          // you've gotten a character on the current line
          currentLineIsBlank = false;
        }
      }
    }
    // give the web browser time to receive the data
    delay(1);
    // close the connection:
    client.stop();
    Serial.println("client disonnected");
  }
}

void printWifiStatus() {
  // print the SSID of the network you're attached to:
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  // print your WiFi shield's IP address:
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);

  // print the received signal strength:
  long rssi = WiFi.RSSI();
  Serial.print("signal strength (RSSI):");
  Serial.print(rssi);
  Serial.println(" dBm");
  // print where to go in a browser:
  Serial.print("To see this page in action, open a browser to http://");
  Serial.println(ip);
}

And here is the serial output:

Initing SD card…initialization done.

Attempting to connect to Network named: myssid

Initializing SD card…initialization done.

Attempting to connect to Network named: myssid

SSID: myssid

IP Address: 192.168.1.105

signal strength (RSSI):-68 dBm

To see this page in action, open a browser to http://192.168.1.105

new client

GET /IRSignal/SonyVolumeUp HTTP/1.1

Host: 192.168.1.105

User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:16.0) Gecko/20100101 Firefox/16.0

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8

Accept-Language: en-US,en;q=0.5

Accept-Encoding: gzip, deflate

Connection: keep-alive

client disonnected

new client

client disonnected

new client

GET /IRSignal/SonyVolumeUp HTTP/1.1

Host: 192.168.1.105

User-Agent: Moz´R+‹¥…±¥é¥¹SD card…initialization done.

Attempting to connect to Network named: myssid

Thanks in advance and Cheers

I’ve got the same issue - did you ever resolve this?

Hi Madian

No. Unfortunately I never got it to work. I replaced the Arduino with a Raspberry.

Good luck.

Martin

Almost a year since this original posting and now it is plagueing me. Surely this has been resolved by now.

I have designed a similar project and I didn’t get much problem in handling this Arduino Wifi Shield, but if you have similar project then I would recommend to use Arduino YUN instead of Arduino Wifi Shield. Btw I will always prefer Raspberry Pi 3 over Arduino YUN.

When it comes to cloud computing etc. Raspberry Pi 3 is the best choice. Arduino is good for embedded but not for Wifi stuff.