Can the Ethernet Shield work with other SPI devices?

Hi,

I have a Mega 1280, the latest Ethernet Shield, and an SPI-connected SCP1000 (on a Sparkfun Breakout).

I am using this library (http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1236443720/14#14) to interface with the SCP1000. I have changed the following to correspond to the mega:

  • const byte DataOutPin = 50;
  • const byte DataInPin = 51;
  • const byte SPIClockPin = 52;

I initialise the SCP1000 with a slave select pin of 37.

The SCP1000 and Ethernet Shield work fine independently. My research suggests there are/have been problems with the Ethernet Shield co-existing with other SPI devices.

I have tried setting the SS pins of both devices to LOW to enable and HIGH to disable, and PORTB |=  _BV(4); to reset the SS on the Ethernet Shield.

My current hacky code is as follows - any ideas?

/*
  Web  Server
 
 A simple web server that shows the value of the analog input pins.
 using an Arduino Wiznet Ethernet shield. 
 
 Circuit:
 * Ethernet shield attached to pins 10, 11, 12, 13
 * Analog inputs attached to pins A0 through A5 (optional)
 
 created 18 Dec 2009
 by David A. Mellis
 modified 4 Sep 2010
 by Tom Igoe
 
 */

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

#define PIN_BAROM_CSB		    37 //also referred to as Slave Select
#define PIN_ETHER_SS		    10 //also referred to as Slave Select

// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 192,168,0, 16 };

// Initialize the Ethernet server library
// with the IP address and port you want to use 
// (port 80 is default for HTTP):
Server server(80);
SCP1000 scp1000(PIN_BAROM_CSB);

void setup()
{
  // start the Ethernet connection and the server:
  pinMode(PIN_ETHER_SS, OUTPUT);
  digitalWrite(PIN_ETHER_SS, HIGH);
  pinMode(PIN_BAROM_CSB, OUTPUT);
  digitalWrite(PIN_BAROM_CSB, LOW);

  scp1000.init();
  scp1000.readSensor();
  
  digitalWrite(PIN_BAROM_CSB, HIGH);
  digitalWrite(PIN_ETHER_SS, LOW);
  Ethernet.begin(mac, ip);
  server.begin();
}

void loop()
{
  // listen for incoming clients
  Client client = server.available();
  if (client) {
    // an http request ends with a blank line
    boolean currentLineIsBlank = true;
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        // 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) {
          // send a standard http response header
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println();

//  client.print("Temprature (C/F): ");
//  client.print(scp1000.TempC);
//  client.print(" / ");
//  client.println( (1.8*scp1000.TempC + 32) );
//  client.print("Pressure (hPa): ");
//  client.println(scp1000.BaroP);
//  client.println();
//  client.println();
  
          // output the value of each analog input pin
          for (int analogChannel = 0; analogChannel < 6; analogChannel++) {
            client.print("analog input ");
            client.print(analogChannel);
            client.print(" is ");
            client.print(analogRead(analogChannel));
            client.println("
");
          }
          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();
  }
  
  
}

Every SPI device on the bus must have an unique SS (slave Select) line. This implies that for every device you need one SS pin (see note* below). Only one device can be active at the time so if you have three SPI devices on the "SPI-bus" two SS lines should be LOW and one may be HIGH.

Note*: minimizing SPI -SS pins In the case of two SPI devices you could use an invertor to switch between the devices => so only one pin is needed. And yes with only one SPI device you could connect the SS pin directly to +5V And by adding a shift register one could select between 8 (or more) SPI devices by means of 3 pins ==> - http://www.arduino.cc/en/Tutorial/ShiftOut

Hi,

Per my example, I’m using a distinct SS pin (37) for the SCP1000, and a SS pin of 10 for the Ethernet Card.

I have tried forcing the SS pins of each to HIGH to disable and LOW to enable (although the SCP library sets the SCP to LOW only before reading, and HIGH straight after).

Can someone confirm that the Ethernet shield will play nicely with other SPI devices? Were library mods needed?

Lee

The Ethernet library is hard-coded to use a certain pin. That code is starts at line 311 in libraries/Ethernet/utility/w5100.h (Arduino 0022). Regardless of what you do in your sketch, Ethernet will always use whatever pin is coded in w5100.h.

It looks like the SCP1000 uses whatever pin you specify, so the 2 libraries should not conflict... at least in terms of their peripheral select pins.

But there could be other conflicts, like perhaps requiring the SPI to be configured in very different modes? A comment in the SCP1000 code mentions using 125 kHz. Maybe the chip can't handle fast bit rates, which the Ethernet library would leave the SPI port configured in?

Also take a look at this: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1287657487 The poster recommends turning off interrupts before accessing the chip. In one of the other libs is using the SPI during an ISR, this could be causing a prob.