I have an inertial measurement unit (IMU) sensor that communicates over SPI. I use Mega2560.

I want to read one simple WHO_AM_I register.

On documentation:

SPI Operational Features

  1. Data is delivered MSB first and LSB last
  2. Data is latched on the rising edge of SCLK
  3. Data should be transitioned on the falling edge of SCLK
  4. The maximum frequency of SCLK is 1MHz
  5. SPI read and write operations are completed in 16 or more clock cycles (two or more bytes). The first byte contains the SPI Address, and the following byte(s) contain(s) the SPI data. The first bit of the first byte contains the Read/Write bit and indicates the Read (1) or Write (0) operation. The following 7 bits contain the Register Address. In cases of multiple-byte Read/Writes, data is two or more bytes:

SPI Address format

MSB              LSB
R/W  A6  A5  A4  A3  A2  A1  A0

SPI Data format

MSB              LSB
D7  D6  D5  D4  D3  D2  D1  D0

On Registermap WHO_AM_I:

Hex Add / Dec Add /  Register Name / Serial I/F / bit7 / bit 6 ..... bit 0
75 / 117 / WHO_AM_I / R /  WHOAMI[7:0]

Pin Assigments:

51 > SDI
52 > SCLK
50 > SDO/ADO
53 > CS

#include <SPI.h> //add arduino SPI library;
//list of all registers binary addresses;
byte WHO_AM_I           = 0B01110101;

byte Read  = 0B10000000;
byte Write = 0B00000000;

//chip select pin on arduino;
const int CS = 53;
SPI.h sets these for us in arduino
const int SDI = 11;
const int SDO = 12;
const int SCL = 13;

void setup() {
  //start the SPI library;
  //initalize the chip select pins;
  pinMode(CS, OUTPUT);


void loop() {

byte rValue = ReadRegister(WHO_AM_I);

Serial.print(Read | WHO_AM_I,BIN);
Serial.print(" > Value: ");


byte ReadRegister(byte Address){
  byte result = 0;
  digitalWrite(CS, LOW); 
  SPI.transfer(Read | Address);
  result = SPI.transfer(0x00);
  digitalWrite(CS, HIGH);

void WriteRegister(byte Address, byte Value){
  digitalWrite(CS, LOW);
  SPI.transfer(Write | Address);
  digitalWrite(CS, HIGH);

But it returned 0.


1 Answer 1


You are missing:

  • SPI.setClockDivider(SPI_CLOCK_DIV16);//1MHZ MAX SPEED. nIf you are using 16MHZ
  • SPI.setBitOrder(MSBFIRST);
  • SPI.setDataMode(SPI_MODE0);

  • Desactivate I2C mode Register


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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