SPI Interface: Wifi Shield and Arduino Robot

Hi, I have problems connecting the Wifi Shield (http://arduino.cc/en/Main/ArduinoWiFiShield) to the Arduino Robot (http://arduino.cc/en/Guide/Robot). What I have done is, I have connected the components via the ICSP port and the SS pin for the shield to TKD3 on the robot; the 'Handshake' pin, pin 7, to TKD5 on the robot; and the LED pin, pin 9 to TKD4 on the robot. I had to use these pins on the robot, because the designated pins are occupied by the LCD. I changed the pin definitions in the WIFI Library file as follows:

#define DATAOUT 	10 // MOSI										(was pin 11; changed to pin 10)
#define DATAIN  	11 // MISO										(was pin 12; changed to pin 11)
#define SPICLOCK  	9  // sck										(was pin 13; changed to pin 9)
#define SLAVESELECT TKD3 // ss										(was pin 10; changed to pin TKD3)
#define SLAVEREADY 	TKD5  // handshake pin							(was pin 7; changed to pin TKD5)
#define WIFILED 	TKD4  // led on wifi shield						(was pin 9; changed to pin TKD4)

Following this, I tried to load one of the Wifi example codes and adapted it to work for the robot as follows:

/*
 
 This example  prints the Wifi shield's MAC address, and
 scans for available Wifi networks using the Wifi shield.
 Every ten seconds, it scans again. It doesn't actually 
 connect to any network, so no encryption scheme is specified.
 
 Circuit:
 * WiFi shield attached
 
 created 13 July 2010
 by dlf (Metodo2 srl)
 modified 21 Junn 2012
 by Tom Igoe and Jaymes Dec
 */

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

void setup() {
  //Initialize serial and wait for port to open:
  Serial.begin(9600); 
  
  while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }

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

  // Print WiFi MAC address:
  printMacAddress();

  // scan for existing networks:
  Robot.println("Scanning available networks...");
  listNetworks();
}

void loop() {
  delay(10000);
  // scan for existing networks:
  Robot.println("Scanning available networks...");
  listNetworks();
}

void printMacAddress() {
  // the MAC address of your Wifi shield
  byte mac[6];                     

  // print your MAC address:
  WiFi.macAddress(mac);
  Robot.print("MAC: ");
  Robot.print(mac[5],HEX);
  Robot.print(":");
  Robot.print(mac[4],HEX);
  Robot.print(":");
  Robot.print(mac[3],HEX);
  Robot.print(":");
  Robot.print(mac[2],HEX);
  Robot.print(":");
  Robot.print(mac[1],HEX);
  Robot.print(":");
  Robot.println(mac[0],HEX);
}

void listNetworks() {
  // scan for nearby networks:
  Robot.println("** Scan Networks **");
  int numSsid = WiFi.scanNetworks();
  if (numSsid == -1)
  { 
    Robot.println("Couldn't get a wifi connection");
    while(true);
  } 

  // print the list of networks seen:
  Robot.print("number of available networks:");
  Robot.print(numSsid);

  // print the network number and name for each network found:
  for (int thisNet = 0; thisNet<numSsid; thisNet++) {
    Robot.print(thisNet);
    Robot.print(") ");
    Robot.print(WiFi.SSID(thisNet));
    Robot.print("\tSignal: ");
    Robot.print(WiFi.RSSI(thisNet));
    Robot.print(" dBm");
    Robot.print("\tEncryption: ");
    printEncryptionType(WiFi.encryptionType(thisNet));
  }
}

void printEncryptionType(int thisType) {
  // read the encryption type and print out the name:
  switch (thisType) {
  case ENC_TYPE_WEP:
    Robot.println("WEP");
    break;
  case ENC_TYPE_TKIP:
    Robot.println("WPA");
    break;
  case ENC_TYPE_CCMP:
    Robot.println("WPA2");
    break;
  case ENC_TYPE_NONE:
    Robot.println("None");
    break;
  case ENC_TYPE_AUTO:
    Robot.println("Auto");
    break;
  } 
}

However, when compiling, I get the following error:

SPI\SPI.cpp.o: In function SPIClass::end()': C:\Users\...\arduino-1.0.5\libraries\SPI/SPI.cpp:44: multiple definition of SPIClass::end()'
Robot_Control\SPI.cpp.o:C:\Users...\arduino-1.0.5\libraries\Robot_Control/SPI.cpp:44: first defined here
SPI\SPI.cpp.o: In function SPIClass::setBitOrder(unsigned char)': C:\Users\...\arduino-1.0.5\libraries\SPI/SPI.cpp:49: multiple definition of SPIClass::setBitOrder(unsigned char)'
Robot_Control\SPI.cpp.o:C:\Users...\arduino-1.0.5\libraries\Robot_Control/SPI.cpp:49: first defined here
SPI\SPI.cpp.o: In function SPIClass::setDataMode(unsigned char)': C:\Users\...\arduino-1.0.5\libraries\SPI/SPI.cpp:58: multiple definition of SPIClass::setDataMode(unsigned char)'
Robot_Control\SPI.cpp.o:C:\Users...\arduino-1.0.5\libraries\Robot_Control/SPI.cpp:58: first defined here
SPI\SPI.cpp.o: In function SPIClass::setClockDivider(unsigned char)': C:\Users\...\arduino-1.0.5\libraries\SPI/SPI.cpp:63: multiple definition of SPIClass::setClockDivider(unsigned char)'
Robot_Control\SPI.cpp.o:C:\Users...\arduino-1.0.5\libraries\Robot_Control/SPI.cpp:63: first defined here
SPI\SPI.cpp.o: In function SPIClass::begin()': C:\Users\...\arduino-1.0.5\libraries\SPI/SPI.cpp:19: multiple definition of SPIClass::begin()'
Robot_Control\SPI.cpp.o:C:\Users...\arduino-1.0.5\libraries\Robot_Control/SPI.cpp:19: first defined here
SPI\SPI.cpp.o:C:\Users...\arduino-1.0.5\libraries\SPI/SPI.cpp:44: multiple definition of `SPI'
Robot_Control\SPI.cpp.o:C:...e\arduino-1.0.5\libraries\Robot_Control/SPI.cpp:44: first defined here

I guess that I have to change the SPI Library, according to how the Wifi Shield operates; i.e. change the following functions:

void SPIClass::end() {
  SPCR &= ~_BV(SPE);
}

void SPIClass::setBitOrder(uint8_t bitOrder)
{
  if(bitOrder == LSBFIRST) {
    SPCR |= _BV(DORD);
  } else {
    SPCR &= ~(_BV(DORD));
  }
}

void SPIClass::setDataMode(uint8_t mode)
{
  SPCR = (SPCR & ~SPI_MODE_MASK) | mode;
}

void SPIClass::setClockDivider(uint8_t rate)
{
  SPCR = (SPCR & ~SPI_CLOCK_MASK) | (rate & SPI_CLOCK_MASK);
  SPSR = (SPSR & ~SPI_2XCLOCK_MASK) | ((rate >> 2) & SPI_2XCLOCK_MASK);
}

...But how, and what exactly?

I would really appreciate your help.
Thank you.
Kind regards
Stefan

Do not cross-post. Other topic deleted. Replies go here.

Ok. Does anyone have an idea?

I wouldn't change the SPI library. I would remove those functions from the robot library. Those are functions already in the SPI library.

The functions I displayed above are from the SPI library. Which functions exactly are you saying I should remove?

There are duplicate functions in your "/libraries/Robot_Control/SPI.cpp" that are also in "/libraries/SPI/SPI.cpp". That is what is generating the error. I would try removing the SPI files from "/libraries/Robot_Control". The ethernet shield needs those functions in "/libraries/SPI" or it will not function.

Ok thank you. I will try that.

I did as you suggested and deleted the SPI header and cpp files. It does compile now, however, nothing happens when uploaded. Do you have any further suggestions for me, please?

When I try the following code:

#include <SPI.h>
#include <WiFi.h>
#include <ArduinoRobot.h>
//SSID of your network 
char ssid[] = "yourNetwork";
//password of your WPA Network 
char pass[] = "secretPassword";

void setup()
{
  Robot.begin();
  Robot.beginTFT();
  Robot.beginSD();
  SPI.begin();
 
 
  WiFi.begin(ssid, pass);

  if (WiFi.status() != WL_CONNECTED) { 
    Robot.println("Couldn't get a wifi connection");
    while(true);
  } 
  // if you are connected, print out info about the connection:
  else {
   // print the received signal strength:
  long rssi = WiFi.RSSI();
  Robot.print("RSSI:");
  Robot.println(rssi);
  }
}

void loop () {}

I get the error message that no WifiShield is connected and the red 'Error' LED on the shield is on. Does this mean I made an error when connecting or is it a software problem?

This should be the way to connect. Put this code after SPI.begin(); This is from the example ConnectWithWPA example.

  Serial.begin(9600);

  // check for the presence of the shield:
  if (WiFi.status() == WL_NO_SHIELD) {
    Serial.println("WiFi shield not present"); 
    // don't continue:
    while(true);
  } 
  
 // attempt to connect to Wifi network:
  while ( status != WL_CONNECTED) { 
    Serial.print("Attempting to connect to SSID: ");
    Serial.println(ssid);
    // Connect to WPA/WPA2 network:    
    status = WiFi.begin(ssid, pass);

    // wait 10 seconds for connection:
    delay(10000);
  }
   
  // you're connected now
  Serial.print("You're connected to the network");

what should the variable status be defined as?

Now I get the error message: "Wifi shield not present" and again, the red LED on the shield is on.
Any suggestions, please?

I commented out the test for a Wifi Shield as can be seen in the code below; but it now gets stuck in the loop: "Attempting to connect...". However, the "Error" LED is not on anymore, instead the green "Link" LED is now on.

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

//SSID of your network 
char ssid[] = "SANO";
//password of your WPA Network 
char pass[] = "NakedMexican";
int status = WL_IDLE_STATUS;     // the Wifi radio's status

void setup()
{
 WiFi.begin(ssid, pass);

 Robot.begin();
 Robot.beginTFT();
 Robot.beginSD();




Serial.begin(9600);

  // check for the presence of the shield:
 /* if (WiFi.status() == WL_NO_SHIELD) {
    Robot.println("WiFi shield not present"); 
    // don't continue:
    while(true);
  } */
  
 // attempt to connect to Wifi network:
  while ( status != WL_CONNECTED) { 
    Robot.print("Attempting to connect to SSID: ");
    Robot.println(ssid);
    // Connect to WPA/WPA2 network:    
    status = WiFi.begin(ssid, pass);

    // wait 10 seconds for connection:
    delay(10000);
  }
   
  // you're connected now
  Robot.print("You're connected to the network");





/*  
  if (WiFi.status() != WL_CONNECTED) { 
    Robot.println("Couldn't get a wifi connection");
    while(true);
  } 
  // if you are connected, print out info about the connection:
  else {
   // print the received signal strength:
  long rssi = WiFi.RSSI();
  Robot.print("RSSI:");
  Robot.println(rssi);
  }*/
}

void loop () {}

You can't just comment out the test for the shield and expect it to work. You must determine why it is not finding the shield.

Did you do this? These pins are the SPI bus. If you change them, it certainly won't work.

I had to use these pins on the robot, because the designated pins are occupied by the LCD. I changed the pin definitions in the WIFI Library file as follows:

#define DATAOUT 10 // MOSI (was pin 11; changed to pin 10)
#define DATAIN 11 // MISO (was pin 12; changed to pin 11)
#define SPICLOCK 9 // sck (was pin 13; changed to pin 9)
#define SLAVESELECT TKD3 // ss (was pin 10; changed to pin TKD3)
#define SLAVEREADY TKD5 // handshake pin (was pin 7; changed to pin TKD5)
#define WIFILED TKD4 // led on wifi shield (was pin 9; changed to pin TKD4)

I thought I'd give it a try...
Yes, I did that, because the pins for the SPI bus in the documentation did not match the definitions. I will change them back and give it a try.

Changed them back as they were:

#define DATAOUT 	11 // MOSI										
#define DATAIN  	12 // MISO										
#define SPICLOCK  	13  // sck										
#define SLAVESELECT TKD3 // ss										(was pin 10; changed to pin TKD3)
#define SLAVEREADY 	TKD5  // handshake pin							(was pin 7; changed to pin TKD5)
#define WIFILED 	TKD4  // led on wifi shield						(was pin 9; changed to pin TKD4)

and still the same error message: "Wifi shield not present"

If you have the wifi library back the way it was, then you have interference from the robot SPI interface. Which pin does it use for the SPI slave select?

Sorry, but I don't quite understand your question. The slave select is connected to pin 10 on the Wifi Shield, and pin TDK3 on the Robot Control Board. Is that what you were asking?

stefanmarggraff:
Sorry, but I don't quite understand your question. The slave select is connected to pin 10 on the Wifi Shield, and pin TDK3 on the Robot Control Board. Is that what you were asking?

Yes. You can't use D10 for both slave select pins. The wifi shield uses D10 as the slave select, and the wifi library expects that pin to be the slave select. It appears the robot also uses D10. That is why you can't get the wifi shield to initialize, or even respond to the "shield not present" function call.

edit: If you want to try changing the wifi slave select, you had the right file, but you changed too many pins. The only one you needed to change was this one.

#define SLAVESELECT 10 // ss

Change that to another pin and bend D10 on the wifi shield so it doesn't insert into the Arduino, then jumper D10 on the shield to the new pin. Insert the robot's slave select into D10 on the Arduino.

FYI: You can't use D7 for the robot either. It is the wifi shield handshake pin.

So, just to clarify, this change is correct:

#define SLAVESELECT TKD3 // ss										(was pin 10; changed to pin TKD3)

and all the other pins remain unchanged?

I assume I can also remove the other two physical connections I made?