First Time arduino/microcontroller user working with the LSM303C mag sensor

I was hoping to find some re-made short codes online for how to pull the magnetic readings off the sensor for the sensor I bought. However, it appears the LSM303C is too new and there hasn't been anything uploaded for it. I did find a code for a similar sensor, LSM303DLH, but I a too unsure if it can be ported with changes made to register values, etc.

link to the code:

link to LSM303C data sheet:

link to LSM303DLH data sheet:

Being very inexperienced I always question my judgement for this. But looking at the code and comparing data sheets does this code seem viable for what I am looking for?

The LSM303C is the newer version of LSM303DLH. I can't find how they differ or what has changed =( I guess they are the same for the software library. Even ST doesn't have a document for the differences. The accelerator range is lower, and the magnetic range is higher. You can ask ST if the software interface is still the same.

Adafruit has a library and tutorial for the LSM303DLH.

A quick read over the I2C/SPI timing diagrams shows they two sensors appear to have the same comms protocols. And the only major difference I can see is the number of pins on the DLH is larger than 303C. But they do have matching pins with similar descriptions. I am thinking they simplified the pin layout from LSM303DLh to the LSM303C.

Side question though is that sample code really all I would need to get the mag readings, assuming I can make changes to match up with my sensor? The code seems too simple.

Give it a try. It is a 3.3V sensor, which Arduino board are you using ?

I have the mega.

The mega has a 5V I2C-bus, you can not connect those SCL and SDA to the sensor. Or do you have a LSM303C breakout board with level shifters ? If not, you need a I2C level shifter.

I am rather lost on what a level shifter is. My sensor is soldered to a small board with pins that I have connected to a bread board. I built the remaining circuit on the breadboard.

Is that what you are talking about?

Yes, but there are easier modules. I use these small level shifters:

When the SDA and SCL have pullup resistors to 5V, the high level is 5V and I call that a 5V I2C-bus. That is too much for a 3.3V chip. A level shifter connects a 5V I2C bus to a 3.3V I2C bus in both ways, completely transparent. The Arduino Mega2560 is one of the few (or the only) board that has pullup resistors of 10k from SDA and SCL to 5V.

What do you mean easier modules? Because those are all from china and I can't waste a month waiting for them to ship.....

Hmmm I assume you are aware of the arduino Due. Having never heard of this I am interested because of the fact it is based on an arm processor. The fact it operates at 3.3V is a side plus. I am eventually going to have to port my code to an arm processor, unrelated to arduino. Is it possible the Due could make the overall process easier?

Also for the level shifters to work do I just assemble the circuit with all lines from the sensor pass through the shifter which is then connected to the corresponding arduino pins?

This device uses an annoying left-hand coordinate system.

Fair enough. Well I ordered a level shifter should e here tomorrow. Once it is placed in the circuit anything special need to be done to the code or is it a seamless integration?

An I2C level shifter is fully transparent. Everythin on the 3.3V bus and everything on the 5V bus is connected, like there is no barrier at all.

It also means that a 3.3V module must pull down the 3.3V [u]and[/u] the 5V voltage when communicating. So if you have many 5V modules and many 3.3V modules, and each module with pullup resistors for the I2C bus, you must calculate the total pullup resistor to see if it is not too low impedance.

The Due is the first and yet only Arduino with ARM processor (Arduino Tre coming soon) Not all user made libraries do work well with the Due yet.

I don't know how to connect, I only use those simple level shifters from Ebay ;)

The one I ordered was from Sparkfun because I needed it here in a timely manner but it does not appear to be any different. Any chance you could explain the purpose of a snippet of code from the library I found? I cannot figure out the reason for the hex values used because I cannot find them in the data sheet. The #define values used do not correlated with anything as far as I can tell.

#define LSM303_ACC 0x18
#define LSM303_MAG 0x1E

byte LSM303_read(byte address)
byte temp;

if (address >= 0x20)


if (address >= 0x20)
Wire.requestFrom(LSM303_ACC, 1);
Wire.requestFrom(LSM303_MAG, 1);
temp =;

return temp;

void LSM303_write(byte data, byte address)
if (address >= 0x20)


The LSM303DHL (the other one, the older DHL) is like two sensors melted in a single package. The magnetometer and accelerometer have both an I2C address. The sparkfun code tries to encapsulate that, so only the register address is used as parameter.

How exactly would that change things for my sensor? The sections in the data sheets for both sensors for the I2C magnetometer stuff are basically identical. I just can't figure out how they came up with the #define hex values.

hold the phone...I believe I figured out what was confusing me. In the data sheet for I2C read/write for the magnetometer the address given is 0011110b which is 0x3C for write and 00111101b which is 0x3D. If the mode bit is dropped I get 0x1E for the mag device address which is what the pre-made code uses.

Would you be able to offer any critques/input if I drew up a picture of my circuit to make sure I have everything correct?

Sure, we do that all day 8)

Below the text input field (when writing a post), you see "Additional Options...". You can use that to upload a photo of a drawing. Any drawing is okay.

YAY! That would be a big help. One last question before I take a crack and assembling and drawing the picture.

The data sheet says I must connect SDA/SLC to VDD_IO through a pullup resistor. How would I determine what resistance t use?