Totally stumped over SPI not working & preventing digitalWrites

Hey gang,
I'm stumped over this, and I've managed to stump Coding Badly so far too.

I have what started as a simple test code to read some buttons, & make onboard LED flash to confirm wiring, then writing all 0s & all 1s to a TPIC6B595 shift register to test turning LED strings on & off.
The button read/LED on/off worked fine.
Added in the SPI.transfers()s - and nothing happened.
Commented out the SPI.transfers - LED followed the button press again.
CodingBadly took a look and pointed out I had not used SPI.begin (Big head slap!).
Added that, still no LED.
Added serial.begin and put in some prints to make sure the code was actually executing in loop, and it does.

Feeling aggravated now, I backed up to 1.0.1, 1.0, renamed the file & went back to -0023. Still no go.
Deleted 1.0.2, reinstalled it.
Still no go! What is going on?
Windows 7, Duemilanove bootloaded as an Uno from 1.0.2 via MKii, brand new '328P.
Testing is just a jumper wire from D5 to GND, watching the LED and the serial monitor. Nothing else is connected.

#include <SPI.h>

byte latch = 10;
byte ledPin = 13;
void setup(){
  Serial.begin(9600);
  SPI.begin();
  pinMode (2, INPUT);
  digitalWrite(2, HIGH);
  pinMode (3, INPUT);
  digitalWrite(3, HIGH);
  pinMode (4, INPUT);
  digitalWrite(4, HIGH);
  pinMode (5, INPUT);
  digitalWrite(5, HIGH);
  pinMode (ledPin, OUTPUT);
  pinMode (9, OUTPUT);
  digitalWrite(9, LOW); // OE*
  pinMode (latch, OUTPUT);
  digitalWrite (ledPin, HIGH); 

}
void loop(){
  if (digitalRead(5) == LOW){
    digitalWrite(latch, LOW);
    Serial.println("input low - latch low");
    SPI.transfer(0xFF);
    digitalWrite (latch, HIGH);
    Serial.println("input low - latch high");
    digitalWrite(ledPin, HIGH);
  }
  else {
    digitalWrite(latch, LOW);
    Serial.println("input high - latch low");
    SPI.transfer(0x00);
    digitalWrite (latch, HIGH);
    Serial.println("input high - latch high");
    digitalWrite (ledPin,LOW);
  }
}

Errors/warnings I see in compile with verbose output after the first compile when the IDE is started:

C:\Arduino-1.0.2\hardware\arduino\cores\arduino\HardwareSerial.cpp: In function 'void store_char(unsigned char, ring_buffer*)':
C:\Arduino-1.0.2\hardware\arduino\cores\arduino\HardwareSerial.cpp:83: warning: comparison between signed and unsigned integer expressions
C:\Arduino-1.0.2\hardware\arduino\cores\arduino\HardwareSerial.cpp: In function 'void __vector_18()':
C:\Arduino-1.0.2\hardware\arduino\cores\arduino\HardwareSerial.cpp:117: warning: unused variable 'c'
C:\Arduino-1.0.2\hardware\arduino\cores\arduino\HardwareSerial.cpp: In member function 'void HardwareSerial::begin(long unsigned int, byte)':
C:\Arduino-1.0.2\hardware\arduino\cores\arduino\HardwareSerial.cpp:364: warning: unused variable 'current_config'
C:\Arduino-1.0.2\hardware\arduino\cores\arduino\HardwareSerial.cpp: In member function 'virtual size_t HardwareSerial::write(uint8_t)':
C:\Arduino-1.0.2\hardware\arduino\cores\arduino\HardwareSerial.cpp:463: warning: comparison between signed and unsigned integer expressions

C:\Arduino-1.0.2\hardware\arduino\cores\arduino\Print.cpp: In member function 'size_t Print::print(const __FlashStringHelper*)':
C:\Arduino-1.0.2\hardware\arduino\cores\arduino\Print.cpp:44: warning: '__progmem__' attribute ignored

C:\Arduino-1.0.2\hardware\arduino\cores\arduino\Tone.cpp:119: warning: only initialized variables can be placed into program memory area

When I compile a 2nd time I don't see these. But digitalWrite is still not working,

Try this...

void setup(){
Serial.begin(9600);
pinMode (2, INPUT);
digitalWrite(2, HIGH);
pinMode (3, INPUT);
digitalWrite(3, HIGH);
pinMode (4, INPUT);
digitalWrite(4, HIGH);
pinMode (5, INPUT);
digitalWrite(5, HIGH);
pinMode (ledPin, OUTPUT);
pinMode (9, OUTPUT);
digitalWrite(9, LOW); // OE*

pinMode (latch, OUTPUT);
digitalWrite( latch, HIGH );
SPI.begin();

digitalWrite (ledPin, HIGH);

}

Note about Slave Select (SS) pin on AVR based boards
All AVR based boards have an SS pin that is useful when they act as a slave controlled by an external master. Since this library supports only master mode, this pin should be set always as OUTPUT otherwise the SPI interface could be put automatically into slave mode by hardware, rendering the library inoperative.

I think you forgot to set the SS pin (10) to output mode, it is a requirement for SPI to work as master.

Lefty

Edit: I see CB beat me to it, again. :smiley:

#include <SPI.h>

byte latch = 10;
byte ledPin = 13;
void setup(){
  Serial.begin(9600);
  pinMode (2, INPUT);
  digitalWrite(2, HIGH);
  pinMode (3, INPUT);
  digitalWrite(3, HIGH);
  pinMode (4, INPUT);
  digitalWrite(4, HIGH);
  pinMode (5, INPUT);
  digitalWrite(5, HIGH);
  pinMode (ledPin, OUTPUT);
  pinMode (9, OUTPUT);
  digitalWrite(9, LOW); // OE*

  pinMode (latch, OUTPUT);
  digitalWrite( latch, HIGH );
  SPI.begin();

  digitalWrite (ledPin, HIGH); 

}

void loop(){
  if (digitalRead(5) == LOW){
    digitalWrite(latch, LOW);
    Serial.println("input low - latch low");
    SPI.transfer(0xFF);
    digitalWrite (latch, HIGH);
    Serial.println("input low - latch high");
    digitalWrite(ledPin, HIGH);
  }
  else {
    digitalWrite(latch, LOW);
    Serial.println("input high - latch low");
    SPI.transfer(0x00);
    digitalWrite (latch, HIGH);
    Serial.println("input high - latch high");
    digitalWrite (ledPin,LOW);
  }
}

Moving the pinMode for latch prior to calling SPI.begin vs calling it after all the other pinModes did not make a difference.

#include <SPI.h>

byte latch = 10;
byte ledPin = 13;
void setup(){
  Serial.begin(9600);
  pinMode (2, INPUT);
  digitalWrite(2, HIGH);
  pinMode (3, INPUT);
  digitalWrite(3, HIGH);
  pinMode (4, INPUT);
  digitalWrite(4, HIGH);
  pinMode (5, INPUT);
  digitalWrite(5, HIGH);
  pinMode (ledPin, OUTPUT);
  pinMode (9, OUTPUT);
  digitalWrite(9, LOW); // OE*

  pinMode (latch, OUTPUT);
  digitalWrite( latch, HIGH );
  SPI.begin();

  digitalWrite (ledPin, HIGH); 

}

void loop(){
  if (digitalRead(5) == LOW){
    digitalWrite(latch, LOW);
    Serial.println("input low - latch low");
    SPI.transfer(0xFF);
    digitalWrite (latch, HIGH);
    Serial.println("input low - latch high");
    digitalWrite(ledPin, HIGH);
  }
  else {
    digitalWrite(latch, LOW);
    Serial.println("input high - latch low");
    SPI.transfer(0x00);
    digitalWrite (latch, HIGH);
    Serial.println("input high - latch high");
    digitalWrite (ledPin,LOW);
  }
}

Moving the pinMode for latch prior to calling SPI.begin vs calling it after all the other pinModes did not make a difference. ledPin will not go High.

But pin 13 is used by the SPI hardware/library as the MOSI signal, I think the SPI hardware takes over the use of pin 13 such that your digitalWrite commands on pin 13 will have no effect?

Lefty

Isn't pin 13 (ledPin) SCK? So the SPI transfer is going to toggle it for each bit and leave it low.

Perhaps if you used a different ledPin?

-br

billroy:
Isn't pin 13 (ledPin) SCK? So the SPI transfer is going to toggle it for each bit and leave it low.

Perhaps if you used a different ledPin?

-br

SCK pin is pin 12 on a 328p based board.

More simply stated once you perform a SPI(begin) pins 11,12, and 13 are controlled by the chips SPI hardware and you lose the ability to write to them until you perform a SPI(end)

Lefty

Well then I am puzzled, because it says here:

That PB5 is D13 is SCK.

-br

Ok, it appears I am losing my mind!
I'll try this on a different board that has an LED on pin8, which is where I started, but hadn't yet got SPI.begin in.

Okay, that solved it.

SCK is D13 on an Uno - not good to use for a debugging indicator when trying to do stuff with SPI.

I need to do more of my programming during the day it seems.

billroy:
Well then I am puzzled, because it says here:

http://www.arduino.cc/en/Hacking/PinMapping168

That PB5 is D13 is SCK.

-br

Well I'm going with the second box down in the SPI reference page:

Edit, appears to be a documentation error in the SPI reference page. But principal still applies in that once SPI(begin) is active you lose that ablility to manual write to pins 11, 12, and 13.

Lefty

That box is wrong.
SCK is D13
MISO is D12
MOSI is D11

Confirmed with any '328 based schematic.

Is everything resolved then? I tried that today. You can't use D13 as a pin if you are using SPI. :slight_smile:

A possibly stupid question: if D13 is being used for SPI, how much useless current drain is caused by the presence of the LED on "standard" Arduino boards?
Ciao,
Lenny

LROBBINS:
A possibly stupid question: if D13 is being used for SPI, how much useless current drain is caused by the presence of the LED on "standard" Arduino boards?
Ciao,
Lenny

Compared to the power used by the w5100, next to nothing. On a Mega, it is nothing. Digital pin 13 is not used by the SPI.

Yes Nick, is all set. Combination of testing between two boards, one with LED on pin 8 but where SPI.begin had been left off, and one with LED on pin 13 where SPI.begin finally got added but then conflicted with D13 as a debug aid really had me going.
Got my program debugged - was missing a ) , turns out
if ( digitalRead ( scorePin == HIGH ) {
evalutes as true!
So 4 inputs, all active all the time, made for not the results I wanted.

LRobbins,
If you check the recent schematics, the L LED is buffered by the LM358 comparator and places next to no load on D13, while drawing perhaps 3ma when turned on, assuming a Vf of 2V (I haven't measured it).