Difference between revisions of "Using SPI modules with an arduino"

From BitWizard WIKI
Jump to: navigation, search
(software)
(software)
 
(2 intermediate revisions by the same user not shown)
Line 28: Line 28:
 
== software ==
 
== software ==
  
 +
 +
This example uses the BIGRELAY module, and rotates through the six relays each time you press the button.
 +
(no relays are activated until you first press the button. )
  
 
  const int SPICLK  = 13;
 
  const int SPICLK  = 13;
Line 34: Line 37:
 
  const int SPISS  = 10;
 
  const int SPISS  = 10;
 
  const int myswitch = 9;
 
  const int myswitch = 9;
 
+
 
+
 
  void SPIinit(void)
 
  void SPIinit(void)
 
  {
 
  {
Line 46: Line 49:
 
   SPCR    =  _BV(SPE) | _BV(MSTR) | _BV(SPR1) | _BV(SPR0);
 
   SPCR    =  _BV(SPE) | _BV(MSTR) | _BV(SPR1) | _BV(SPR0);
 
  }
 
  }
 
+
 
  char SPI(char d)  
 
  char SPI(char d)  
 
  {  // send character over SPI
 
  {  // send character over SPI
Line 55: Line 58:
 
   return (received);
 
   return (received);
 
  }
 
  }
 
+
 
  void SPI_startpkt (void)
 
  void SPI_startpkt (void)
 
  {
 
  {
 
   digitalWrite (SPISS, 0);
 
   digitalWrite (SPISS, 0);
 
  }
 
  }
 
+
 
  void SPI_endpkt (void)
 
  void SPI_endpkt (void)
 
  {
 
  {
 
   digitalWrite (SPISS, 1);
 
   digitalWrite (SPISS, 1);
 
  }
 
  }
 
+
 
  static unsigned char bigrelay = 0x9c;
 
  static unsigned char bigrelay = 0x9c;
 
+
 
  #define WAIT1 25
 
  #define WAIT1 25
 
  #define WAIT2 15
 
  #define WAIT2 15
 
+
  setregval (unsigned char addr, unsigned char reg, unsigned char val)
+
  void setregval (unsigned char addr, unsigned char reg, unsigned char val)
 
  {
 
  {
 
   
 
   
Line 83: Line 86:
 
   SPI_endpkt ();
 
   SPI_endpkt ();
 
  }
 
  }
 
+
 
  void setup (void)
 
  void setup (void)
 
  {
 
  {
Line 91: Line 94:
 
   pinMode (myswitch, INPUT_PULLUP);
 
   pinMode (myswitch, INPUT_PULLUP);
 
  }
 
  }
 
+
 +
//#define USE_SWITCH
 +
#ifdef USE_SWITCH
 +
#define DOIT digitalRead (myswitch) == 0
 +
#else
 +
#define DOIT 1
 +
#endif
 +
 
  void loop (void)  
 
  void loop (void)  
 
  {
 
  {
 
   static int r;
 
   static int r;
 
+
   if (digitalRead (myswitch) == 0) {
+
   if (DOIT) {
      r = r + 1;
 
      if (r == 6) r = 0;
 
 
       setregval (bigrelay, 0x10, 1 << r);
 
       setregval (bigrelay, 0x10, 1 << r);
 +
#ifdef USE_SWITCH
 
       delay (10); // debounce
 
       delay (10); // debounce
 
       while (digitalRead (myswitch) == 0)
 
       while (digitalRead (myswitch) == 0)
 
           /* nothing */ ;
 
           /* nothing */ ;
 
       delay (10); // debounce.
 
       delay (10); // debounce.
 +
#else
 +
      delay (500);
 +
#endif
 +
      r = r + 1;
 +
      if (r == 6) r = 0;
 
   }
 
   }
 
  }
 
  }

Latest revision as of 14:55, 16 January 2018

intro

It is very convenient to expand your arduino with the bitwizard I2C or SPI modules. This article focuses on the SPI variant.

hardware

To connect your bitwizard module to your arduino I prefer to use the connector on the arduino that is originally for ICSP. Almost all the SPI signals are there. And we chose the pinout to be the same as well.

The only signal that does not appear on the ICSP connector is the "slave select" signal. The ICSP connector has "RESET" there.

So use the following connection:

 arduino    bitwizard
 ICSP        SPI
 1           1
 2           2 
 3           3
 4           4
 6           6

[todo find the names of the signals]

This leaves SS/RESET. We cannot use the RESET line on the ICSP connector. We recommend you use the D10 pin of the arduino as that is the pin recommended for the purpose by the chip manufacturer Atmel. So:

 arduino    bitwizard
             SPI
   D10       5

software

This example uses the BIGRELAY module, and rotates through the six relays each time you press the button. (no relays are activated until you first press the button. )

const int SPICLK  = 13;
const int SPIMOSI = 11;
const int SPIMISO = 12;
const int SPISS  = 10;
const int myswitch = 9;


void SPIinit(void)
{
  pinMode (SPICLK,  OUTPUT);
  pinMode (SPIMOSI, OUTPUT);
  pinMode (SPIMISO, OUTPUT);
  pinMode (SPISS,   OUTPUT);
  digitalWrite (SPISS, 1);
  
  SPCR    =  _BV(SPE) | _BV(MSTR) | _BV(SPR1) | _BV(SPR0);
}

char SPI(char d) 
{  // send character over SPI
  char received = 0;
  SPDR = d;
  while(!(SPSR & _BV(SPIF)));
  received = SPDR;
  return (received);
}

void SPI_startpkt (void)
{
  digitalWrite (SPISS, 0);
}

void SPI_endpkt (void)
{
  digitalWrite (SPISS, 1);
}

static unsigned char bigrelay = 0x9c;

#define WAIT1 25
#define WAIT2 15

void setregval (unsigned char addr, unsigned char reg, unsigned char val)
{

  SPI_startpkt ();
  delayMicroseconds (WAIT1);
  SPI (addr);
  delayMicroseconds (WAIT2);
  SPI (reg);
  delayMicroseconds (WAIT2);
  SPI (val);
  SPI_endpkt ();
}

void setup (void)
{
  int i;
  
  SPIinit ();
  pinMode (myswitch, INPUT_PULLUP);
}

//#define USE_SWITCH
#ifdef USE_SWITCH
#define DOIT digitalRead (myswitch) == 0
#else 
#define DOIT 1
#endif

void loop (void) 
{
  static int r;

  if (DOIT) {
     setregval (bigrelay, 0x10, 1 << r);
#ifdef USE_SWITCH 
     delay (10); // debounce
     while (digitalRead (myswitch) == 0)
         /* nothing */ ;
     delay (10); // debounce.
#else 
     delay (500);
#endif
     r = r + 1;
     if (r == 6) r = 0;
  }
}