I2c troubleshooting

I just started using an imp with a custom impee, but I’m having issues getting i2c communication up and running. I haven’t ruled out issues with my hardware, but the circuit is pretty simple, so I think it’s unlikely. Also, when I hook an o-scope up to the SCL and SDA pins, I’m not seeing any signals, which suggests that I have something configured incorrectly.

Here’s the code I’m using:

`imp.configure(“Test resistor”,[],[]);


local AD5245_ADDR = 0x2D;

local result = hardware.i2c12.write(AD5245_ADDR, “\x00”);


The “write” function always returns -2, even though the docs say the only options are 0 and -1.

Any suggestions for troubleshooting would be greatly appreciated!

A return value of -2 indicates that the address has been sent but the slave has not acknowledged. Have you got external pull-ups on SCL and SDA?

I’ll add the other error codes to the documentation.

Yeah, 4.7k on each. Both channels are stuck at 3.3V.

I have 2 other ICs on the same i2c line, and writing to both addresses results in the same return code.

If you’re using the sparkfun breakout board, you may have a problem with pin 1. Try i2c89 for starters.

I’m using a custom circuit board that’s based on the SparkFun breakout board, but the i2c circuit is hardwired.

Why do you mention the problem with pin 1? Is that a known issue?

At finer temporal resolution, I’m seeing signals on pin 2 (SDA), but not pin 1 (SCL). What could this indicate?

The sparkfun breakout board socket exacerbates issues with pin1 on some imps - specifically, the pin9 contact spring bends the imp pcb up and causes pin1 to sometimes not make contact.

This doesn’t happen on the imp breakouts, or on all imps. If you contact info@electricimp.com we can swap your imp out for you.

Hmm…that would definitely explain my problem. Is there an easy way to hack the imp to improve the contact? Or do you recommend just sending the imp back?

You could try a piece of paper between the top of the imp and the socket. I’ve seen that done successfully…

Hi jsiegle,
I also made my boards based on Sparkfun’s board. I have a issue with nvram being cleared on wake up from deep sleep. Have you already checked nvram with your boards? I hope you don’t have problem with this.

I’m also having some difficulty with i2c. pretty new to this - coming from arduino world.

I’ve looked through the new and old documentation on i2c library and read up a bit on the net. I think I understand the gist of i2c - master activates slave, slave acknowledges and then streams some bytes, waits for next instruction.

I’m trying to read data from the MMA8452 accelerometer sparkfun breakout board, and im cross-referencing things in some of their example code, located here : https://github.com/sparkfun/MMA8452_Accelerometer/blob/master/Firmware/MMA8452Q_BasicExample/MMA8452Q_BasicExample.ino

this gives me the relevant sub- registers, as I understand it… the things that would follow a command like

hardware.i2c89.read(accelerometer, “\x0D”, 1);

with accelerometer defined as:

const accelerometer = 0x1D;

If anyone can help me get over this hump, ive posted a little code on github :

from the imp ive got Pin8 to SCL and Pin9 to SDA

its my understanding that the sparkfun breakout comes with pull-up resistors on the datalines.

my code logs out :

2013-10-29 19:04:27 UTC-4: [Status] Device configured to be "accel"
2013-10-29 19:04:27 UTC-4: [Device] trying to start
2013-10-29 19:04:28 UTC-4: [Device] (null : 0x0x0)

I also use the MMA8452Q in some dice (see electricdice.com)

You need to shift the address left by 1.

hardware.i2c89.read(accelerometer << 1, "\\x0D", 1);

Presumably this is because the imp i2c library assumes 7bit addressing and does a >> 1 on the address you provide. Other i2c hardware I have seen expects the MSB of the i2c address from a chip’s spec to be aligned in bit.

The << 1 worked for me. Maybe it should be fixed in the library? Opinions?

Here is some of my code that may be helpful.

/////////////////////////////////////////////// // constants for MMA8452Q i2c registers // the slave address for this device is set in hardware. Creating a variable to save it here is helpful. // The SparkFun breakout board defaults to 0x1D, set to 0x1C if SA0 jumper on the bottom of the board is set const MMA8452Q_ADDR = 0x1D // A '<< 1' is needed. I add the '<< 1' in the helper functions. //const MM8452Q_ADDR = 0x1C // Use this address if SA0 jumper is set. const STATUS = 0x00 const ZYXOW_BIT = 0x7 // name_BIT == BIT position of name const ZYXDR_BIT = 0x3 const OUT_X_MSB = 0x01 const SYSMOD = 0x0B const SYSMOD_STANDBY = 0x00 const SYSMOD_WAKE = 0x01 const SYSMOD_SLEEP = 0x02 const INT_SOURCE = 0x0C const SRC_ASLP_BIT = 0x7 const SRC_FF_MT_BIT = 0x2 const SRC_DRDY_BIT = 0x0 const WHO_AM_I = 0x0D const I_AM_MMA8452Q = 0x2A // read addr WHO_AM_I, expect I_AM_MMA8452Q const XYZ_DATA_CFG = 0x0E const FS_2G = 0x00 const FS_4G = 0x01 const FS_8G = 0x02 const HPF_OUT_BIT = 0x5 const HP_FILTER_CUTOFF = 0x0F const FF_MT_CFG = 0x15 const ELE_BIT = 0x7 const OAE_BIT = 0x6 const XYZEFE_BIT = 0x3 // numBits == 3 (one each for XYZ) const XYZEFE_ALL = 0x07 // enable all 3 bits const FF_MT_SRC = 0x16 const EA_BIT = 0x7 const FF_MT_THS = 0x17 const DBCNTM_BIT = 0x7 const THS_BIT = 0x0 // numBits == 7 const FF_MT_COUNT = 0x18 const ASLP_COUNT = 0x29 const CTRL_REG1 = 0x2A const ASLP_RATE_BIT = 0x6 // numBits == 2 const ASLP_RATE_12p5HZ = 0x1 const ASLP_RATE_1p56HZ = 0x3 const DR_BIT = 0x3 // numBits == 3 const DR_12p5HZ = 0x5 const DR_1p56HZ = 0x7 const LNOISE_BIT = 0x2 const F_READ_BIT = 0x1 const ACTIVE_BIT = 0x0 const CTRL_REG2 = 0x2B const ST_BIT = 0x7 const RST_BIT = 0x6 const SMODS_BIT = 0x3 // numBits == 2 const SLPE_BIT = 0x2 const MODS_BIT = 0x0 // numBits == 2 const MODS_NORMAL = 0x00 const MODS_LOW_POWER = 0x03 const CTRL_REG3 = 0x2C const WAKE_FF_MT_BIT = 0x3 const IPOL_BIT = 0x1 const CTRL_REG4 = 0x2D const INT_EN_ASLP_BIT = 0x7 const INT_EN_LNDPRT_BIT= 0x4 const INT_EN_FF_MT_BIT = 0x2 const INT_EN_DRDY_BIT = 0x0 const CTRL_REG5 = 0x2E

Just message me if this is helpful, I can share my read, write, and init functions

I stripped out my device specific code.

Here is generic electric imp code for i2c read and write and specific MMA8452Q accelerometer constants and functions.

I see that this imp i2c library https://github.com/omribahumi/imp_i2c_lcd/blob/master/ImpLcd.nut

also call i2c.read and i2c.write with address << 1

Last week I helped someone debug an MSP430 I2C circuit and one of the problems was the address from the spec needing to be >> 1 before writing to the address register.

Is this just common knowledge when using I2C libraries?

Thanks, the <<1 worked for me on my Sparkfun breakout board. I am talking to a BlinkM. Before adding this shift to the address I was getting a -2 on i2c89 and i2c12.
After adding the shift i2c12 still returned -2, however i2c89 worked.

Clock speed was CLOCK_SPEED_100_KHZ


I’m trying to connect couple of i2c sensors to Imp and everything works out well when only one sensor is connected. When I add another sensor to the bus hardware.i2c89.write starts to return -1.

Philmy mentioned that he adds the error codes to the documentation but at least documentation of i2c.write does not contain any error code specification. Are those codes specified somewhere else?

Where are your pullups? Do you have two sets?