9- and 10-DoF LSM9DS0 shield for Teensy 3.1

Status
Not open for further replies.
I tend to think that a lot of the Arduino code that assumes there is only one i2c bus needs to be rewritten so the i2c object used is an argument to the initial constructor (with the default being Wire if not passed).

Arduino library code that assumes if you are not on an AVR, you must be on a Due, and always use Wire1 is just as broken (of course in the case of the Due, choosing to put Wire1 on the common SDA/SCL on the shield was a poor design choice).

And it is unfortunate that i2c_t3.h is not upwards compatible with Wire either, and you have to go and change all of the code to include i2c_t3.h instead. Ditto for the ATtiny85, where you need to use TinyWireM.h and/or TinyWireS.h.
 
There is a little overhead in switching to i2c_t3.h but I find the explicit call to specific SDA/SCL pins and the explicit choice of speed very useful and transparent. Unfortunately, until one gets used to this, the potential for error is great. And of course, i2c_t3.h is Teensy 3.1 specific and doesn't work with AVR controllers. That is a real disadvantage, but the advantages still outweigh.
 
Do you have pull up resistors? If this is the only I2C device in your circuit, you will have to close the solder junction on the board to enable the 10K pullup resistors.

Ah, yeah, doops. Closing the three pads together gets me some data that might be valid. So that's progress.

(My board has 4k7 resistors.)
 
Ah, yeah, doops. Closing the three pads together gets me some data that might be valid. So that's progress.

(My board has 4k7 resistors.)

Don't feel bad, the first time I tried to hook up this board via jumper wires I forgot the pullups too!

I started putting 4K7 resistors on all the latest boards for i2c pullups because I have been using 400 kHz "fast" i2c exclusively now. I am considering reducing these further to 2K2 since some sensors allow even faster i2c (IIRC > 1 MHz). Anyone have a suggestion for the 'right' size of pullup for 400 kHz? I don't want the commo to be a gigantic power sink though, but I want good sharp edges in the signal. I guess if I had a scope I could answer my own question...
 
Last edited:
The normal spec for I2C pins is to be able to sink 3mA. So theoretically at 3.3V you cannot go lower than 1.1K ohm on the Teensy side. If you go lower the Pin may not be able to pull the voltage down below logic zero.
Provided that your micro boards are soldered directly to the Teensy pins I believe bus capacitance should play a secondary role.
 
It sounds like you are saying that as long as I am above 1k1, I don't have to worry about it. But I thought I have seen scope traces of i2c signals where the sharpness of the pulses depends pretty strongly on the pullup resistor values and the commo speed. I haven't had any problems so far; I just wondered if there was a general rule of thumb. You know, 10 K for 100 KHz, 4K7 for 400 kHz, 2K2 for higher speeds, etc. Maybe not.

Or maybe this is only for longish commo lines. Are you saying this isn't an issue when the i2c component is nearly directly connected to the microprocessor? OK, now I get it!
 
Last edited:
Check out Wayne Truchsess' classic article on sizing resistors for I2C, if you haven't already.

The ideal for me would be the ability to easily set the I2C frequency. There will be other devices on the bus and I'd like every device to be flexible that there will be at least one common frequency where every device is happy. I'd also like it all to run as fast as possible - I've been pushing FRAM to 2 MHz and it's made a big difference to the speed of data transfer.
 
Wayne Truchsess' classic article

Yes, that's the one I remember seeing. Looks like either 4K7 or 2K2 would be fine generally.

4K7 keeps the power drain down a bit.
 
Yes. The (little, tiny) bluish passives above the steel case of the MS5637 are 0402 4K7 pull up resistors.

The pressure sensor will report on the air pressure of whatever enclosure it is in. If the enclosure is hermetically sealed, you will get that pressure. If there is sufficient communication with the outside air via even a small hole or gap in the case so that the inside and outside pressures can equilibrate, the MS5637 pressure will be the same as outside. I don't know what an IP67 rated enclosure is. Can you afford to allow air equilibration? Or do you intend to monitor the pressure inside the enclosure and expect it will be different from the outside air pressure?
 
The pressure sensor will report on the air pressure of whatever enclosure it is in. If the enclosure is hermetically sealed, you will get that pressure. If there is sufficient communication with the outside air via even a small hole or gap in the case so that the inside and outside pressures can equilibrate, the MS5637 pressure will be the same as outside. I don't know what an IP67 rated enclosure is. Can you afford to allow air equilibration? Or do you intend to monitor the pressure inside the enclosure and expect it will be different from the outside air pressure?

Thanks, that's what I figured.

First, IP67 is a rating for "ingress protection" - i.e. keeping things out, and more specifically, solid particles and liquids. The 6 in IP67 indicates "No ingress of dust; complete protection against contact (dust tight)." The 7 indicates "Ingress of water in harmful quantity shall not be possible when the enclosure is immersed in water under defined conditions of pressure and time (up to 1 m of submersion)." So in other words, it's completely sealed.

My project will be used in an application exposed to the elements, so the sealing is necessary (though IP67 might be overkill. IP65 would probably be adequate.) It would be nice to be able to use the pressure sensor to detect ambient pressure, but I don't think that will be possible and still be able to keep the enclosure weather tight. My other thought is to use an enclosure that is almost weather tight, but have a very tiny hole, possibly with a basic moisture trap, to allow the interior pressure to track the exterior pressure and seal the electronics appropriately (potting, conformal coating, etc.)

Anyway, it was more of a "nice to have" feature and not something I counted on having.
 
If it's protection from the elements in the usual sense, couldn't you afford a small hole in the bottom (or non-weather side) of the box with a foam dust trap over it to allow air pressure equilibration?
 
If it's protection from the elements in the usual sense, couldn't you afford a small hole in the bottom (or non-weather side) of the box with a foam dust trap over it to allow air pressure equilibration?

Possibly. The project will be going on off road motorcycles, etc. where water and dust ingress is a real threat. Dust is obviously easier to solve than water. I just did a quick bit of research and found a potential solution - the GORE Automotive Vent. It allows air exchange, but keeps particles and fluids out. Depending on cost, this may be the solution.
 
It sounds like you are saying that as long as I am above 1k1, I don't have to worry about it. But I thought I have seen scope traces of i2c signals where the sharpness of the pulses depends pretty strongly on the pullup resistor values and the commo speed. I haven't had any problems so far; I just wondered if there was a general rule of thumb. You know, 10 K for 100 KHz, 4K7 for 400 kHz, 2K2 for higher speeds, etc. Maybe not.

I thought I'd try waving a scope at the microshield and changing the I2C frequency to see how much the pulses change.

For 400 kHz and 4k7 pull-ups:

LSM9DS0 I2C SDA 400 kHz 4k7 20140908-0001.png

For 1000 kHz and 4k7:

LSM9DS0 I2C SDA 1000 kHz 4k7 20140908-0001.png

So not a big difference. I didn't see any change in behaviour with the frequency change, so 1 MHz seems fine. (That's not to say it's working, there's valid communication between the sensor and the Teensy, the checksum checks, the acceleration data I'm getting has a problem but that's unrelated to the frequency.)
 
These pulses seem pretty square. Looks like 4K7 works well.

If you are having issues with the micro board data output, maybe I could help...
 
If you are having issues with the micro board data output, maybe I could help...

Cheers. Here's the output I'm getting:

Code:
This is the LSM9DS0...
LSM9DS0 WHO_AM_I's returned: 0x49D4
Should be 0x49D4

MS5637 pressure sensor reset...
PROM data read:
C0 = 0
C1 = 0
C2 = 0
C3 = 0
C4 = 0
C5 = 0
C6 = 0
Checksum = 0 , should be 0
Digital temperature value = 20.00 C
Digital temperature value = 68.00 F
Digital pressure value = 0.00 mbar
Altitude = 145366.45 feet
Heading: 0.00
Pitch, Roll: 0.00, 0.00
ax = 0.00 ay = 0.00 az = 0.00 mg
gx = 0.13 gy = -0.18 gz = 0.10 deg/s
mx = 0.00 my = 0.00 mz = 0.00 mG
gyro temperature = 22.50
Yaw, Pitch, Roll: -13.80, 0.00, 0.00
q0 = 1.00 qx = 0.00 qy = 0.00 qz = 0.00
filter rate = 0.1
Digital temperature value = 20.00 C
Digital temperature value = 68.00 F
Digital pressure value = 0.00 mbar
Altitude = 145366.45 feet
Heading: 0.00
Pitch, Roll: 0.00, 0.00
ax = 0.00 ay = 0.00 az = 0.00 mg
gx = -0.02 gy = -0.10 gz = 0.21 deg/s
mx = 0.00 my = 0.00 mz = 0.00 mG
gyro temperature = 22.50
Yaw, Pitch, Roll: -13.80, 0.00, 0.00
q0 = 1.00 qx = 0.00 qy = 0.00 qz = 0.00
filter rate = 13492.5
Digital temperature value = 20.00 C
Digital temperature value = 68.00 F
Digital pressure value = 0.00 mbar
Altitude = 145366.45 feet
Heading: 0.00
Pitch, Roll: 0.00, 0.00
ax = 0.00 ay = 0.00 az = 0.00 mg
gx = 0.10 gy = 0.08 gz = 0.10 deg/s
mx = 0.00 my = 0.00 mz = 0.00 mG
gyro temperature = 22.50
Yaw, Pitch, Roll: -13.80, 0.00, 0.00
q0 = 1.00 qx = 0.00 qy = 0.00 qz = 0.00
filter rate = 13460.6
Digital temperature value = 20.00 C
Digital temperature value = 68.00 F
Digital pressure value = 0.00 mbar
Altitude = 145366.45 feet
Heading: 0.00
Pitch, Roll: 0.00, 0.00
ax = 0.00 ay = 0.00 az = 0.00 mg
gx = 0.77 gy = 0.11 gz = 0.81 deg/s
mx = 0.00 my = 0.00 mz = 0.00 mG
gyro temperature = 22.62
Yaw, Pitch, Roll: -13.80, 0.00, 0.00
q0 = 1.00 qx = 0.00 qy = 0.00 qz = 0.00
filter rate = 13364.5

That's from startup. The first two data sets are with the sensor stationary, after that I flipped it on it's back. It looks to me like it starts up fine, but there's no actual movement data at all.
 
The program is set to only read the sensors when the corresponding one of three interrupts is set HIGH. The lack of accel data I expect, since you have to relabel the pin 27 interrupt in the code to the actual pin 33 location of the INT1XM accel data ready interrupt. The lack of mag data is likely due to a similar issue. Check that there is good contact between the board pin connector and the Teensy pad. Alternatively, you could forgo the interrupt polling and just poll the data ready status register bits to check data ready. Another easy check is to simply remove the accel and mag data ready checks completely and you should get data from these two sensors.
 
Success!

AH yup.

I changed that line in the code to:

Code:
const byte INT1XM = 33;  // INT1XM tells us when accel data is ready

Now I'm getting good accelerometer and gyro data. And it's coming from a tiny tiny thing, so thank you for making this available.

Any hints on the mag?
 
Last edited:
I am assuming you checked that you have a good solder connection between the mag interrupt pinout on the board and the Teensy pad. You could try to 1) comment out the check for mag interrupt just to verify you are getting some reading, or 2) change the polling on the mag from hardware interrupt to checking the status register for new mag data ready. I suspect the interrupt pin solder joint is cold or otherwise not well connected.
 
Not sure what's going on with the mag interrupt. The electric connection is good but no interrupt. This isn't a problem for me, as this hardware can just check once in every little while.

Anyway, the micro shield is giving me accel, gyro, mag, and temperature data, along with Tait-Bryan angles, from a tiny sensor that'll fit in a gap in the current hardware design. And it takes 1 ms per read, so that too can fit into a gap in the program. So thanks for putting this little beauty together.
 
I'm glad you are getting all the data from the sensor now. It is very pleasing to me when other people find value in these little devices I make!

If it's not too crass and a misuse of this forum, may I suggest that if you have the time, would you mind posting a review of your experience with the device, both good and bad, on the Tindie site so others might benefit?
 
Since you have the version one board, the mag interrupt INTXM2 is routed to pin 32 not pin 27 as in the current sketch written for the new (version two) LSM9DS0+MS5637 board. I think this is why the mag interrupt was not working for you.
 
Pull Ups Required; Serial Streaming?

Don't feel bad, the first time I tried to hook up this board via jumper wires I forgot the pullups too!.

Unfortunately, I got to this forum after I had soldered my Pesky MPU9250 Mini shield onto my PJRC Teesnsy3.1 and was not aware the pull-ups were required.
Perhaps you should move this advice up into the user documentation or clarify early so history is not repeated.... again :)
I read the README but thought the issue was taken care of.

So after hacking in some 4K7 pull ups on the back side (easier for me than de-soldering all 12 pins - of which only 5 are needed) and not having a mini display I found that I could indeed turn the LED on and off by adding this code at the end of loop() and then flipping the board over and back:

Code:
    if (az > 0.5)
    {
      digitalWrite(myLed, HIGH);
    }
    else
    {
      digitalWrite(myLed,LOW);
    }
    //digitalWrite(myLed, !digitalRead(myLed));

So other than adding the pull-ups and rounding up the missing libraries, I have to say this stuff looks pretty promising; I had no previous encounter with Arduino software nor i2C interfacing.

What would speed me along faster than a mini display setup is some code or suggestions to stream some high speed sensor data to a COM port on my Win7 laptop. Anyone done this or have any thoughts?
 
Last edited:
Firstly, I am sorry the pullup resistors were a mystery on this device. It has solder jumpers on the front so users can decide whether to hook up the on-board 4K7 pull-up resistors in the breakout board circuit. The reason they are not just hardwired in is because there might be other I2C devices in the circuit with there own pullups or the microcontroller might have internal pullups (not on the Teensy). The alternative to green wiring your mini breakout board would have been to add another I2C breakout board to the circuit for testing, but soldering 4K7 (not 47K, I hope!) pullups to the pins on the back would certainly work and , as you found out, is easier than desoldering the whole breakout board. Although I have done this in the past and it is not impossible. Still, I apologize if the intent of the solder jumper for on-board pullups was not clear. I have been working with these for several months and I forget what is obvious to me might not occur to others until (as in your case) too late.

I added more info and warning at the Tindie site to make sure this shouldn't happen again.

As far as streaming the data, why isn't streaming of the data to the Serial monitor sufficient?
 
Last edited:
Not a problem on the pull up issue; you certainly have the right product approach. (And I corrected the typo in my post, thanks).

As far as streaming the data, why isn't streaming of the data to the Serial monitor sufficient?

Hmmm, again I stress no "priors" with Aduino stuff and I don't have a "mini display" ..If there is a "Serial monitor" on the PC side its not obvious to me and of course all your code is printing to the (Nokia) mini display...as far as I can tell. Is there something in the Arduino IDE? I am familiar with Putty and Tera Term if that helps with a response.

I could dig further in the Arduino references but I thought that streaming back to the PC via the USB connection would have been done by many before. Ideally I would like an application on the PC side to be able to open the COM port connected to this device, e.g. fopen("COM31", "r+") in Matlab or Octave. Perhaps a separate USB driver is required on the PC side and some UART code to serialize the data on the Teensy side? Hopefully I am making this sound harder than it really is ?

edit 1:To be more specific, being able to stream the raw gyro and accel data and perhaps temperature via USB in a compact binary format at say 1Mbaud would be kind of cool. I think the UART on the PC side could handle it.

edit 2: Well, meanwhile I checked the Arduino "manual" and sure enough was able to get the data you were sending to the "mini display" to show up on the ...hello...Serial Monitor in the IDE connect to "COM31"....Thanks for the hint !..but...

I guess I will have to get into the nitty gritty and hack your code to just pack out the raw data I want; will also need to look over the digital filter settings and the sample rate setup in the register. Hopefully (with the IDE off) I can use the same USB driver from my own application?
Just thought this sort of bare bones streaming would have already been done long ago.
 
Last edited:
Status
Not open for further replies.
Back
Top