4
\$\begingroup\$

I have developed a simple code for learning about SPI in Arduino Due. The code is compiling properly and now I would like to learn the next step on how to test the code with the board and get the master to communicate with the slave. Here is the code:

#include"SPI.h"
 int mosi = 75;          //assigning variables to pins
 int sck = 76;
 int ss = 10;
 int miso = 74;

void setup()
 {
   pinMode(mosi,OUTPUT);     //Configuring pins as input and output
   pinMode(sck,OUTPUT);
   pinMode(ss,OUTPUT);
   pinMode(miso,INPUT);
   SPI.begin(10);                   // waking up SPI bus
   SPI.setDataMode(10,SPI_MODE_0);  //setting mode for clk phase & pol
   SPI.setBitOrder(10, MSBFIRST);   // setting bit order for transfer
   SPI.setClockDivider(10,42);     //setting clock to 2 MHz
   digitalWrite(10,HIGH);     //keeping slave device unactive
 }
void set_value(int value);
 {
   digitalWrite(10,LOW);      //activate slave select line
   SPI.transfer(0);           
   SPI.transfer(value);    // transfer values from 0 to 255
   digitalWrite(10,HIGH);   //deactivate slave line after transfer
 }
void loop()
 {
   for(int i=0 ; i<256 ;i++)     //values to transfer
    {
      set_value(i);             //call function to transfer values
      delay(100);
    }
  }

IDE used : Arduino, Board used : Arduino Due

I have some doubts regarding this code:

1) How to test this code with my borad to check if its working correctly?

2) Why isn't the mosi, sck and ss pins used anywhere in the code, while all operations/functions are being done with respect to the slave line ss = 10?. Does the SPI module automatically take care of the data transmission and reception through MOSI and MISO?

3) What are the possible hardware connections if I am using one due board as my master and another due board as my slave?.

4) Should I dump this code into the master as well as slave for it work? Or Since master has to transmit and receive data from the slave board, I need to do some changes in this code?

5) If I am missing out anything or any directions regarding this would be helpful. I am newbie to embedded systems and totally confused & full of stupid doubts. PLz dont mind. Thanks!

\$\endgroup\$
  • \$\begingroup\$ You may consider splitting your questions for a better fit in StackExchange's Q&A format. \$\endgroup\$ – Mast Mar 25 '15 at 9:34
  • 1
    \$\begingroup\$ IMO multipart questions are fine if they are tightly coupled. \$\endgroup\$ – geometrikal Mar 25 '15 at 14:03
  • 1
    \$\begingroup\$ You don't need to manually toggle the CS pin or configure the SPI pins, these are already done in the SPI library. The SPI library is located in the libraries folder of your Arduino install directory. Open up the c++ files and take a look at the code, I think you will get a better understanding of the inner workings. It is also good to download the data sheet for the Due's MCU and have a look at the SPI section. Remember, the Arduino is just the avr-gcc compiler with some core c++ libraries and an IDE based on processing. \$\endgroup\$ – geometrikal Mar 25 '15 at 14:09
  • \$\begingroup\$ @geometrikal:I am actually facing some trouble using the spi.transfer function as its not performing its task. So, like you said, I started scanning through the libraries in the install directory. The spi c++ file is only available in the WiFi library folder. I checked the utilities in WiFi folder and found the C++ file spi_drv, however in this file, I searched and could not see any spi.transfer() function code, though they have used it.So, just wanted to know If you have come across it sometime when you scanning thru the spi code. If so, Pl direct.Thanks \$\endgroup\$ – PsychedGuy Mar 26 '15 at 14:10
  • \$\begingroup\$ I do not want to post another question asking if anyone has come across this function in the arduino libraries, as it would be silly. So, any help in short would be appreciated. \$\endgroup\$ – PsychedGuy Mar 26 '15 at 14:13
4
\$\begingroup\$

The Arduino DUE uses a slightly different methodology for SPI compared to the rest of the Arduino boards. It handles the operation of the SS line for you, so you don't have to.

While you can use the manual software method, it's better to use the hardware facilities where available.

The Arduino Due's SPI interface works differently than any other Arduino boards. The library can be used on the Due with the same methods available to other Arduino boards or using the extended methods. The extended methods exploits the the SAM3X hardware and allows some interesting features like:

  • automatic handling of the device slave selection.
  • automatic handling of different device configurations (clock speed, data mode, etc) so every device can have its own configuration automatically selected.

Arduino Due has three exposed pins for the devices Slave Select (SS) lines (pins 4, 10, and 52).

What this means is you initialize the SPI with the SS pin you are using:

SPI.begin(10);

Then you send and receive using the "continuation" versions of the SPI transfer function:

SPI.transfer(10, 0, SPI_CONTINUE);
SPI.transfer(10, value);

The first parameter is the SS pin (it's used as a key to connect the function to the right SPI instance), the second is the value to transfer, and the third tells SPI not to raise the SS pin after transfer.

The SPI on the Due is a single SPI bus with multiple hardware SS pins. The configuration of the bus is attached to that SS pin, so when you activate an SS pin it automatically configures the bus to the settings you have associated with that SS pin. This allows one bus to have multiple different settings (speed, clock polarity, bit order, etc) and switch between them properly without any manual intervention on your part.

You can read more about this way of working here: http://arduino.cc/en/Reference/DueExtendedSPI

As for testing your code, when I need to test an SPI port I usually create a loopback connection (connect MOSI to MISO) and send random values through it, receiving what is sent. The sent value and received value should match if the SPI is working properly.

\$\endgroup\$
  • \$\begingroup\$ Sorry if this is unrelated. Say if you have 2 slaves, one on pin 10 and one on pin 4, do you call SPI.begin(10) or SPI.begin(4) before you send data to each slave? \$\endgroup\$ – bakalolo Jul 9 '16 at 1:56
3
\$\begingroup\$

The easiest way to see if your SPI code is working is to connect your controller to external shift registers and find out.

You could use one or more serial-in parallel-out shift registers driving LEDs to test the SPI output: 74hc595 driving LEDs with 1k series resistors on each LED work well. I prefer to have the shift register outputs be active LOW - that means that all of the LED resistors to do the +5V rail with LEDs from each resistor to the shift register outputs.

You can use one or more parallel-in serial-out shift registers with DIP switches to test the SPI input: 4021 with 10k pull-up resistors plus a DIP switch to ground for each of the inputs.

A quick test is to write code that simply echoes the DIP switch inputs on the LEDs.

The specific reason I mention where the resistors go for both the serial-in and serial-out shift registers is that I make use of bus resistor networks in 10-pin SIP package. These are bread-board friendly (0.1" pin spacing) and make it easy (and neat & tidy) to add the necessary resistors.

One final note: because this is something that I used to do an awful lot (and still do!), I actually made up several little pieces of Veroboard (stripboard) with the components on the boards. One style has an 8-wide DIP switch & pull-up SIP network, the other style has a 10-segment bar-graph LED bar with pull-up SIP resistor network. These were all made with SIP-style (single-row) machine-pin sockets that allow me to use 24 AWG telephone / cat-5 solid wire to go from the little modules to the breadboard.

Using these little modules makes testing and experimenting very easy. The added advantages are that the components on these little modules don't take up space on your breadboard, they can be re-used over and over again, and they are friendly towards board-level microcontrollers such as Arduino or other single-board controllers.

I first made my little modules like this several decades ago and still use them today.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.