Saturday, May 10, 2014

Talking to the MPU6050 with the Bus Pirate

I was having some trouble finding solid information on interfacing the bus pirate to an I2C bus.
Part of my problem was the fact that I was seeing the wrong cable colouring on many pages referring to the bus pirate. I purchased mine from SparkFun, as well as the cable - and the colouring is different (backwards perhaps?).

Anyways, here is how to hook up both SparkFun's MPU6050 breakout AND Bus Pirate with cable and make them talk nicely.

1) Get the correct cable diagram... (from dangerousprototypes.com)


2) Find out which colours correspond to SDA (I2C data line), SCL (clock line) GND and power.
SDA corresponds to MOSI (Master Out Slave In)
SCL corresponds to CLK (seems logical :])
GND is obviously black
Annnnnd you can power the MPU6050 board with 3.3V! (white cable).

3) MAKE SURE YOU ALSO CONNECT THE VLOGIC PIN ON THE MPU6050 BREAKOUT TO +3.3V (or whatever logic level you are using - for this little tutorial, it is +3.3V directly from the Bus Pirate).

4) Plug in your bus pirate and get talking to it - I use minicom on Ubuntu Linux, and the settings are 115200-8-N-1. This step is covered all over dangerousprototypes.com, so check it out there.

5) Switch to I2C mode at whatever frequency (I started with slowest just because I'm debugging).

HiZ> ?
General                                 Protocol interaction
---------------------------------------------------------------------------
?       This help                       (0)     List current macros
= X     Converts X                      (x)     Macro x
~       Selftest                        [       Start
#       Reset                           ]       Stop
$       Jump to bootloader              {       Start with read
&/%     Delay 1 us/ms                   }       Stop
a/A/@   AUXPIN (low/HI/READ)            "abc"   Send string
b       Set baudrate                    123
c/C     AUX assignment (aux/CS)         0x123
d/D     Measure ADC (once/CONT.)        0b110   Send value
f       Measure frequency               r       Read
g       Generate frequency/PWM          /       CLK hi
h       Commandhistory                  \       CLK lo
i       Versioninfo/statusinfo          ^       CLK tick
l/L     Bitorder (msb/LSB)              -       DAT hi
m       Change mode                     _       DAT lo
o       Set output type                 .       DAT read
p/P     Pullup resistors (off/ON)       !       Bit read
s       Script engine                   :       Repeat e.g. r:10
v       Show volts/states       //<0>   Usermacro x/assign x/list all
w/W     PSU (off/ON)
HiZ> m
1. HiZ
2. 1-WIRE
3. UART
4. I2C
5. SPI
6. 2WIRE
7. 3WIRE
8. KEYB
9. LCD
x. exit(without change)

(1)> 4
Set speed:
 1. ~5KHz
 2. ~50KHz
 3. ~100KHz
 4. ~400KHz

(1)> 1
Ready.

Now it should be ready to talk at about 5kHz to an I2C bus.

4) Next step is to turn the power on! Woo! To do this, enter 'W' and hit enter at the Bus Pirate prompt:


I2C> W
POWER SUPPLIES ON
Pinstates:                                                                                                                                                                                
1.(BR)  2.(RD)  3.(OR)  4.(YW)  5.(GN)  6.(BL)  7.(PU)  8.(GR)  9.(WT)  0.(Blk)                                                                                                           
GND     3.3V    5.0V    ADC     VPU     AUX     SCL     SDA     -       -                                                                                                                 
P       P       P       I       I       I       I       I       I       I                                                                                                                 
GND     3.27V   4.84V   0.00V   0.00V   L       H       H       L       L 


After turning them on, I type 'v' to get the states of each pin on the Bus Pirate to make sure it is what I expect. You'll see the colouring information is wrong here - possibly due to the firmware being from dangerousprototypes and not SparkFun.

5) Now we can start talking to the MPU6050! First - a quick run-down of the basic I2C 'items' available in the Bus Pirate, as well as some details regarding the I2C address of the MPU-6050.

  • [ - The start to an I2C transaction
  • ] - The stop to an I2C transaction
  • { - Start with a read (I never used this)
  • } - Stop (I never used this)
  • r - Read
  • 0xdeadbeef - Send this hex value (I typically use this since I've gotten used to it, and it's compact)
  • 0b010101 - Send this binary value
  • 123 - Send this decimal value
If you read the MPU6050 datasheet/usermanual, you'll see in section 9 the "Digital Interface".
Refer to that section for more details regarding I2C with the MPU-6050. 
Here is a quote from the intro paragraph for I2C mode :


9.2 I C Interface
I2C is a two-wire interface comprised of the signals serial data (SDA) and serial clock (SCL). In general, the lines are open-drain and bi-directional. In a generalized I C interface implementation, attached devices can be a master or a slave. The master device puts the slave address on the bus, and the slave device with the matching address acknowledges the master.

The MPU-60X0 always operates as a slave device when communicating to the system processor, which thusacts as the master. SDA and SCL lines typically need pull-up resistors to VDD. The maximum bus speed is400 kHz.

The slave address of the MPU-60X0 is b110100X which is 7 bits long. The LSB bit of the 7 bit address is determined by the logic level on pin AD0. This allows two MPU-60X0s to be connected to the same I C bus.When used in this configuration, the address of the one of the devices should be b1101000 (pin AD0 is logiclow) and the address of the other should be b1101001 (pin AD0 is logic high).

Notice that the 7bit I2C address is either going to be 0b1101000 or 0b1101001 (hex 0x68 or 0x69) (depending upon the state of pin AD0). ALSO NOTE THAT THERE IS A DIFFERENCE BETWEEN THE 7BIT ADDRESS AND USING 8BITS ON THE I2C BUS!! SEE  BELOW!

6) Now to do a single byte read sequence, we need two things:
  • The I2C address (don't know? Start with 0xD0 (corresponds to 7bit address 0b1101000).
  • The address of a register on the MPU-6050 we would like to read - I chose the I2C address register, as it is easy to see if you are operating the bus correctly. The register is 0x75.
For a single byte read the transaction goes like so:
  1. Master sends start and the 7bit I2C address (in 8 bits) of device it wants to talk to ( '[' and '0xd0' ) Note: 7 bit address is 0b1101000 but we send 8 bits at a time, so it is actually 0b11010000 on the bus for a write condition (0xd0) and 0b11010001 for a read condition (0xd1).
  2. Slave with that address acknowledges the master
  3. Master sends the register address it wants to read ( '0x75' )
  4. Slave acknowledges the master
  5. Master sends start and the address of device it wants to talk to PLUS 1 ( '[' and '0xd1' ) (Also at this point, you must type an 'r' for the bus pirate to know it should read data from the MPU-6050)
  6. Slave acknowledges the master and sends the data in the internal register (should be 0xd0)
  7. Master does NOT acknowledge and sends stop ( ']' )
See now the entire transaction played out with the Bus Pirate and an MPU-6050 connected properly:
I2C> [0xd0 0x75 [ 0xd1 r]
I2C START BIT
WRITE: 208 ACK 
WRITE: 117 ACK 
I2C START BIT
WRITE: 209 ACK 
READ: 104 
NACK
I2C STOP BIT
I2C>

You can see that the bus pirate plays out the transaction with decimal values, I'm sure you can change this to hex if you want. Decimal 104 is the same as hex 0x68 or binary 0b1101000.

No comments :

Post a Comment