SparkFun Forums 

Where electronics enthusiasts find answers.

For the discussion of Arduino related topics.
By JuxOr
#139149
I am trying to connect the 3.3V MMA8452Q Accelerometer (on BoB) to the Arduino Pro Mini (5V) and haven't been able to establish communication.
I have also tested the accelerometer with the Arduino Uno (R3) with the same results.

Links to products being used:
MMA8452Q BoB: http://www.sparkfun.com/products/10955
Arduino Pro Mini: http://www.sparkfun.com/products/9218
Arduino Uno (R3): http://www.sparkfun.com/products/11021

Wiring (to Pro Mini):
Because the MMA pins are not 5V tolerant I added voltage dividers (10k/22k) on all four communication pins (SDA, SCL, INT1, & INT2) as well as on the supply pin for the BoB. This resistor combination drops the voltage to ~3.43v, within the 3.6v maximum for the chip.
I tested using only the internal 10k pull-up resistors on the BoB, as well as adding external pull-ups (4k7).
All other wiring matched the example sketch linked at the bottom of the accelerometer product page:
http://dlnmh9ip6v2uc.cloudfront.net/dat ... xample.zip
And, yes, just in case your wondering, I used the A4 & A5 labeled on the bottom side of the board (the SDA & SCL pins per the Arduino schematics).
(Ok, ok, I did connect them to the wrong A4 & A5 the first time... but I fixed it!)

The code I tried was the example code provided above. The only change I made was changing the SA0 value from 0 to 1 (and back) hoping that would fix the problem. My second fix (though it should have been the first) was to double check the baud rates. Correcting the baud rates got me a single output ("Could not connect to MMA8452Q: 0xFF") instead of garbage. (This error message is part of the example sketch, in case that wasn't obvious).


My theories on why this may not have worked are 1) I somehow fried the board (ESD or missed a wiring issue?) or 2) The board is DOA (less likely) or 3) Something with the voltage dividers is screwing with communication (eg 5V drops to 3.4V one way and drops again down to ~2.4V the other way). or there is always 4) I'm a freaking idiot and missed something obvious.

The voltage dividers *shouldn't* be the issue since (supposedly according to another post) the arduino will recognize voltages of less than 1V as high, but that was my first thought before I started researching heavily.

I found it interesting that the example code didn't mention using voltage dividers or logic level shifting, though it does mention not using the wire.c library in order to avoid the Arduino's internal pull-ups to 5V. This made me wonder if it was written for a specific board?

I also found part of the example sketch wording slightly confusing (though this is more of a side note than a reason the communication isn't working).
SDA and SCL should have external pull-up resistors (to 3.3V). 10k resistors worked for me. They should be on the breakout board.
This sketch is dated 4 days prior to the BoB schematics being updated to add on-board 10k pull-up resistors. In my research (I don't remember if it was on the MMA8452Q or general I2C communication) there was mention of the pull-up resistor values effecting the sample rate or communication frequency. How does this play into things?

I also ran across a lot of conflicting information (use logic level shifting, don't use shifting it only complicates it, etc. etc.). I did find this post (http://www.arduino.cc/cgi-bin/yabb2/YaB ... 1275738825) saying that modifying the wire library to not use the internal pull-ups allows 3.3v communication from the Arduino, but the discussion was specifically about the Arduino Duemilanove Atmega328. Is this the same for all Atmega328 based Arduinos?

My test with the Arduino Uno (R3) also yielded no communication. This time I followed the example code wiring without any voltage dividers (mistake?). I kept the testing time short just in case, but that part still made me nervous. I also tested this with and without the external pull-ups to 3.3V as well as SA0 values of 1 and 0.

Any tips, pointers or suggestions you can offer would be greatly appreciated. If more information is needed just let me know and I will be happy to provide as much as I can.

Thanks
By coryduce
#139230
Try this:
-Modify the wire library so that the internal pull ups are not used
-Remove all your level shifters
-Connect the I2C pins on the UNO directly to the I2C pins on the BoB
-Use the 3.3v pin on the UNO to provide power to the BoB
-Add external 4.7K pullups to the SDA and SCL lines. Connect the pullups to the 3.3v supply on the UNO

Since I2C pins are open collector, the max voltage on the I2C lines is set by the voltage that the pull up resistors are connected to, so you don't need voltage dividers.

In order to make this work with the Pro Mini, you will need to get an external 3.3v regulator for powering the BoB and the pull ups.
By JuxOr
#139234
Thanks Cory!
the max voltage on the I2C lines is set by the voltage that the pull up resistors are connected to
This is the part I was unsure of and was hanging me up, especially with the Pro Mini.

I'm still sitting here shaking my head though, because I wired it up exactly like you suggested a couple days ago and it wouldn't work, but this time it worked! I'm confused as to what I did differently, but whatever. It works.

I would still like to get it working with the Pro Mini since the Uno doesn't fit in my current project box, but I'm not sure I have time to mess around with it too much. I guess my next question would be; should the example code work exactly the same on the Pro Mini as on the Uno if I provide 3.3V to the sensor?

In theory is seems like a voltage divider should work to drop the 5V supply down to 3.3V and tie the pull-ups to that, but maybe I'm missing something there.

Thanks again for your help!

-Kyle
By whte_rbt
#146453
hey kyle,

i'm looking for similar guidance on a 3.3v accelerometer connected to a 5v atmega. were you able to get the device working using this advice? how do i disable internal pull up resistors within the wire library?

thanks
joe
By Joeisi
#146491
Hello Kyle and other Joe. ;) The issue I see with this is that I2C has a bi-directional line(SDA). Since it is bidirectional, both sides send data from that line. The voltage divider setup will work when going from the Mega to the BoB. But not back, because all of the current gets sucked down through the 10k resistor. (Analogy: Its hard swimming up a waterfall.(Its not that good, just get over it.)). So the Mega sees no voltage. So no data back. The Mega is lonely. No one to talk to. :(
Do not just use the pull ups to pull up to 3v3. It may work, but it is out of specs. When the Mega writes a high bit, the line will be pulled to 5V, efficiently killing your accelerometer. The 5V will be pulled down a little bit, but not enough to fall within the 3.6V maximum rating.(If I'm thinking correctly).
What you need to do is get a Logic Level Converter. Each line will have to be hooked up to both a TX and a RX on their side (Either 5v or 3v3) since I2C is bidirectional. Each side (5v and 3v3) will have to be pulled up individually. Hope this works for you!