Results 1 to 4 of 4

Thread: Working with Arduino and SPI

  1. #1
    Fox Furry crenn's Avatar
    Join Date
    Apr 2005
    Location
    In the shadows behind you
    Posts
    4,067

    Default Working with Arduino and SPI

    Working with Arduino and SPI

    Summary
    What I plan to do is show you how to work with an SPI device and an arduino. This includes setting up the registers, setting the mode of SPI and setting the speed of communication.

    Why?
    For one of the projects I'm working on, I have to interface with a triple axis accelerometer (An ADXL345) and get values back that I can use to help stabilise a mechanical system. I got this sensor almost a year ago and have only recently started getting it to work due to my limited knowledge at the time. One of the main problems that happened when I went to test this sensor was the different voltage levels, the micro that I had intended to use was 5v and the sensors were all 3.3v; and to solve this problem I had to bring in a voltage translator so I wouldn't burn out the sensor. The next problem I came up against was the electronics I designed, needed to be programmed, and also work with the various sensors. However I had a slight problem getting a custom PCB (we were out of budget) and using vero board resulted in a short somewhere which disabled the entire system. This was the first time I designed a system, and I learnt a lot. Regardless, fast forward to a few months ago. I decide to have another crack of getting this sensor to work, and I've mostly got it working (it's now a hardware issue which needs to be resolved, the software is working fine though). So I thought I might share the software side of what I did.

    Why SPI and not I2C (Wire)?
    The reason I went for SPI over I2C was:
    • SPI is faster than I2C
    • Easier for me to do the voltage translations than I2C
      • I2C has bidirectional data lines which makes it difficult to do the voltage translations (I've recently discovered there is an easy and interesting way to do it, but that's for another time and when I can try it)
      • Also note that there is 2 versions of SPI, 3 wire SPI and 4 wire SPI, I'm using 4 wire SPI as I'd encounter the same problem with 3 wire SPI that I had with I2C
    • Lack of knowledge about doing I2C communication (and SPI, although SPI seemed easier to me)
    Current state of code and example output
    Code:
      #define DATAOUT 11//MOSI orange wire
      #define DATAIN  12//MISO
      #define SPICLOCK  13//sck
      #define SLAVESELECT 10//ss
       
      #define SPI_CONTROL (1<<SPE)|(1<<MSTR)|(1<<CPHA)|(1<<CPOL)|
       
      #define RW_MASK 0x80
      #define MB_MASK 0x40
      #define CB_MASK (RW_MASK|MB_MASK)
       
       
      byte spi_transfer(byte data)
      {
        SPDR = data;                    // Start the transmission
        while(!(SPSR & (1<<SPIF)));     // Wait the end of the transmission
        return SPDR;                    // return the received byte
      }
       
       
      void writeADXL(byte reg, byte data){
        Serial.println("Slave low");
        Serial.println("Transferring");
        digitalWrite(SLAVESELECT,LOW);
        delayMicroseconds(1);
        spi_transfer(((~CB_MASK)&reg)); //write instruction and address
        spi_transfer(data); //send data
        delayMicroseconds(1);
        digitalWrite(SLAVESELECT,HIGH);
        delayMicroseconds(1);
        Serial.println("Slave High");
        Serial.print("Tranferred ");
        Serial.print(data, HEX);
        Serial.print(" to ");
        Serial.println(reg, HEX);
      }
       
      byte readADXL(byte reg){
        byte temp=0;
        digitalWrite(SLAVESELECT,LOW);
        delayMicroseconds(1);
        spi_transfer(((~CB_MASK)&reg)|0x80); //read instruction and address
        temp=spi_transfer(0xFF); //send data
        delayMicroseconds(1);
        digitalWrite(SLAVESELECT,HIGH);
        delayMicroseconds(1);
        Serial.print("Reg is ");
        Serial.print(reg, HEX);
        Serial.print(", data reads ");
        Serial.println(temp, HEX);
        return temp;
      }
       
      void intAXDL(){
        writeADXL(0x2D,0x28);
        delay(20);
        writeADXL(0x31,0x0F);
        delay(20);
        writeADXL(0x38,0x00);
        delay(20);
      }
       
       
      void setup()
      {
        byte clr;
        pinMode(DATAOUT, OUTPUT);
        pinMode(DATAIN, INPUT);
        pinMode(SPICLOCK, OUTPUT);
        pinMode(SLAVESELECT, OUTPUT);
        digitalWrite(SLAVESELECT,HIGH);
        // start serial port at 9600 bps:
        Serial.begin(9600);
        SPCR = 0b01011111; //(1<<SPE)|(1<<DORD)|(1<<MSTR);
        SPSR = 0;
        clr=SPSR;
        clr=SPDR;
        delay(10);
        Serial.println("Set mode");
        intAXDL();
        Serial.println("Initialization finished");
      }
       
      void loop()
      {
        readADXL(0x00);
        readADXL(0x36);
        readADXL(0x37);
        delay(500);
      }
    This is it for now, however there will be updates tomorrow on this post including newer, commented and cleaner code and a full explanation of everything going on.
    Antec Sonata II | Pioneer DVR-212
    Good news! You can follow my website or follow me on twitter!

  2. #2
    Fox Furry crenn's Avatar
    Join Date
    Apr 2005
    Location
    In the shadows behind you
    Posts
    4,067

    Default Re: Working with Arduino and SPI

    Reserved Post 1 - Just in case
    Antec Sonata II | Pioneer DVR-212
    Good news! You can follow my website or follow me on twitter!

  3. #3
    Fox Furry crenn's Avatar
    Join Date
    Apr 2005
    Location
    In the shadows behind you
    Posts
    4,067

    Default Re: Working with Arduino and SPI

    Reserved Post 2 - Just making sure

    EDIT: If These additional posts aren't required, I'll delete them.
    Antec Sonata II | Pioneer DVR-212
    Good news! You can follow my website or follow me on twitter!

  4. #4
    Resident 100HP water-cannon operator SXRguyinMA's Avatar
    Join Date
    Jun 2008
    Location
    MA
    Posts
    5,865

    Default Re: Working with Arduino and SPI

    this should be neat, I can't wait to see what you come up with!

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •