Pages: 1 [2]   Go Down
Author Topic: Arduino as SPI slave  (Read 7632 times)
0 Members and 1 Guest are viewing this topic.
UK
Offline Offline
Newbie
*
Karma: 0
Posts: 46
Arduino Low Earth Orbit here we come
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi Rob

sorry to be thick

but what do you mean fly wire, would i not just set that PIN(HIGH) in the code?

ie
 digitalWrite(SSPin,LOW);

I'll give it a go today and let you know the results smiley once I am clear on that one

thank you for the help
Logged

nr Bundaberg, Australia
Offline Offline
Tesla Member
***
Karma: 129
Posts: 8599
Scattered showers my arse -- Noah, 2348BC.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

You can't do that because the SS signal is an input on your slave Arduino, it needs to be held low for the SPI hardware to work. The quickest way to do this (just to get things working) is to plug a wire (aka flying wire/lead) in with one end in a GND hole (one the Arduino headers) and the other end into the SS input, D10 on the Duemilanove and D53 on Mega. (not sure what you have).

______
Rob
« Last Edit: May 07, 2011, 05:36:25 am by Graynomad » Logged

Rob Gray aka the GRAYnomad www.robgray.com

UK
Offline Offline
Newbie
*
Karma: 0
Posts: 46
Arduino Low Earth Orbit here we come
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi Guys

I have tried the Arduino connected to the Glider and I am not getting anything, not even spirilious characters!

This could be that the SPI does not activate until the glider detects a flight as I have set the aux port to SPI as described in the manual.

I have connected in the following fashion -

Bird                       Arduini Duemilanove
Gnd                       Gnd
Aux1                      Pin 13 sck
Aux2                      Pin 11 MOSI
                             Pin 12 MISO not connected
                             Pin 10 SS connected to Gnd

I hope that’s correct, but I don't understand how the slave detects the speed and mode ETC and I notice we don't seem to have included any SPI library. Could you please explain? Is the code
SPCR |= _BV(SPE); some sort of built ASM cmd I don’t see a reference to it in the SPI reference page?
Should there not be some SPI library included and some settings made ie setClockDivider()???

failing my setup it has to be that a flight detection is required, in which case I need Synco and will have to wait until he gets back to NZ to chek on that

smiley-sad
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 499
Posts: 19071
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

You can't do that because the SS signal is an input on your slave Arduino, it needs to be held low for the SPI hardware to work.

From the Atmega manual, p171:

Quote
When the SPI is configured as a Slave, the Slave Select (SS) pin is always input. When SS is held low, the SPI is activated, and MISO becomes an output if configured so by the user. All other pins are inputs. When SS is driven high, all pins are inputs, and the SPI is passive, which
means that it will not receive incoming data. Note that the SPI logic will be reset once the SS pin is driven high.

So if your Arduino is an SPI slave, then pin 10 (for the Uno and variants) needs to be low or nothing will happen. As Graynomad said, grounding it should work.

My slave example didn't need the SPI library because the SPI library was designed for the master end. There is nothing particularly useful for slaves. Can you post your code? You should have the stuff in setup like this:

Code:
  // turn on SPI in slave mode
  SPCR |= _BV(SPE);

  // turn on interrupts
  SPCR |= _BV(SPIE);

And you need the interrupt service routine:

Code:
// SPI interrupt routine
ISR (SPI_STC_vect)
{
  byte c = SPDR;
 
 // process incoming byte here (eg. store it somewhere)

}  // end of interrupt service routine (ISR) SPI_STC_vect

The slave should detect the clock rate of the master. That is, the slave clocks data in as SCK changes, the rate at which it changes is controlled by the master.
Logged


UK
Offline Offline
Newbie
*
Karma: 0
Posts: 46
Arduino Low Earth Orbit here we come
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi Nick

I cut and pasted your slave code section from the start of this topic, so it should be spot on, I only removed the line as recommemed by Rob pertaining to MISO

Quote
// have to send on master in, *slave out*
  pinMode(MISO, OUTPUT);


I have also connected pin10 to gnd to pull it down

The idea was any data sent would be viewable on the serial monitor as your code outputs at 9600baud on the arduino com port.

I am seeing nothing, if my connections are correct I can ony asume that the data port only activates during flight, that is when the software detects a launch.

If you agree then I'll have to maybe fake a launch on tethered balloon and see if data starts to churn out.

thank you for the help so far, I'll post the explanation when I have it smiley
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 499
Posts: 19071
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

It's possible it's inactive I suppose. Without reading the datasheet it is hard to be sure. Your "fake" launch may prove things. The other thing would be, if possible, to hook up a scope or logic analyzer and try to see if the SCK is being pulsed at all. You would need to check you have the device configured correctly.
« Last Edit: May 07, 2011, 05:44:34 pm by Nick Gammon » Logged


nr Bundaberg, Australia
Offline Offline
Tesla Member
***
Karma: 129
Posts: 8599
Scattered showers my arse -- Noah, 2348BC.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
I am seeing nothing

The print line

Serial.println (buf);

Will not print anything (or at least nothing viewable) if for example you have low binary values in the buf array.

Just to see I'd change it to

Code:
Serial.println (buf[0], HEX);

and then maybe a loop to dump the whole thing.

Code:
for (int i = 0; i < 100; i++)
    Serial.println (buf[i], HEX);

Although if the ISR is not firing of course there will be nothing useful to look at.

______
Rob

« Last Edit: May 07, 2011, 08:44:31 pm by Graynomad » Logged

Rob Gray aka the GRAYnomad www.robgray.com

UK
Offline Offline
Newbie
*
Karma: 0
Posts: 46
Arduino Low Earth Orbit here we come
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks Rob, no joy yet, its looking like its not tramsmitting, I'll do some testing and post the results   smiley-sad-blue
Logged

nr Bundaberg, Australia
Offline Offline
Tesla Member
***
Karma: 129
Posts: 8599
Scattered showers my arse -- Noah, 2348BC.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Yep you need to verify things are working at the source then follow the data until you find where it stops.

______
Rob
Logged

Rob Gray aka the GRAYnomad www.robgray.com

UK
Offline Offline
Newbie
*
Karma: 0
Posts: 46
Arduino Low Earth Orbit here we come
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi Gents, Can I just check something with you, testing tonight I noticed that when the SPI connection is plugged into the Arduino the LED marked L is flashing very faintly. Looking at the schematic this looks to be the SCK working would you agree? if so is this normal? doe sthe SCK continually send a pulse? or does thsi idicate the SPI is pumping data out were just not seeing it?
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 499
Posts: 19071
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

... does the SCK continually send a pulse?

No it doesn't. See my logical analyzer data here:

http://www.gammon.com.au/spi

However, it is important to note that SPI does not wait for any acknowledgement. So if you are the slave, and you are not processing the data, that's your bad luck. The master will keep sending it.

... or does this indicate the SPI is pumping data out were just not seeing it?


Sounds like it is doing just that.

Sounds like either you have not configured your end as a slave, you haven't pulled SS low, or your interrupt service routine is not firing for some reason (like interrupts disabled).
« Last Edit: May 09, 2011, 05:04:44 pm by Nick Gammon » Logged


UK
Offline Offline
Newbie
*
Karma: 0
Posts: 46
Arduino Low Earth Orbit here we come
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hello Nick/Rob

This is odd after studying the ARDUINO 2009 sckematic I copied the 1K resistor and LED L off the SCK PIN and did the same on my breadboard for PIN 11 boths pins flash away nicely!

I take it that this means SPI data must be traversing the connections but still no output on the seriasl monitor window????

Help! I feel its nearly there what I am I missing (PIN 10 to gnd)

 smiley-sad
« Last Edit: May 11, 2011, 03:53:28 pm by nathanBomberHarris » Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 499
Posts: 19071
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Can we see the sketch for the receiving end?
Logged


UK
Offline Offline
Newbie
*
Karma: 0
Posts: 46
Arduino Low Earth Orbit here we come
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Sure //note code added as suggested by Rob I tried with and without smiley thank you for helping

// Written by Nick Gammon
// February 2011


#include "pins_arduino.h"

char buf [100];
volatile byte pos;
volatile boolean process_it;

void setup (void)
{
  Serial.begin (9600);   // debugging

  // have to send on master in, *slave out*
  //pinMode(MISO, OUTPUT);
 
  // turn on SPI in slave mode
  SPCR |= _BV(SPE);
 
  // get ready for an interrupt
  pos = 0;   // buffer empty
  process_it = false;

  // now turn on interrupts
  SPCR |= _BV(SPIE);

}  // end of setup


// SPI interrupt routine
ISR (SPI_STC_vect)
{
byte c = SPDR;  // grab byte from SPI Data Register
 
  // add to buffer if room
  if (pos < sizeof buf)
    {
    buf [pos++] = c;
   
    // example: newline means time to process buffer
    if (c == '\n')
      process_it = true;
     
    }  // end of room available
}  // end of interrupt routine SPI_STC_vect

// main loop - wait for flag set in interrupt routine
void loop (void)
{
  if (process_it)
    {
    buf [pos] = 0; 
    for (int i = 0; i < 100; i++)// Code added on suggestion Rob
    {
    Serial.println (buf[0],HEX); // Code added on suggestion Rob
    }
    pos = 0;
    process_it = false;
    }  // end of flag set
   
}  // end of loop
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 499
Posts: 19071
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

It helps to use the [ code ] tags (hit the # button above the post).

Anyway, you won't see anything if process_it is not true, and that hinges on getting a newline. Does the device send one?

For debugging you could change it to something like this to see if the buffer is filling up:

Code:
void loop (void)
{

  // debugging 
  if (pos > 20)
  {
   for (int i = 0; i < pos; i++)
      {
      Serial.println (buf[i], HEX);
      }
      pos = 0;
  }
 
   
}  // end of loop
Logged


Pages: 1 [2]   Go Up
Jump to: