Pages: [1]   Go Down
Author Topic: MEGA2560 and I2C with LM92  (Read 1189 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 25
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I need help with the problem:
I have a LM92 (thermal sensor) connected to a Mega2560 (IDE 1.0.1 with its Wire library).
Cable length ist less than 10 inches. I have to read 2 Bytes, consequitivly send by the LM92 on a Wire.requestFrom from the Mega2560.
This works, but the Bytes which are read by Wire.read() have too much "1"'s, so the reported temperature is some degrees to high.
This problem worsens, if cable length is increased (e.g. 10 feet). I used internal pullups as well as external pullups -> no change.
Can anyone help ???
Logged

Seattle, WA USA
Online Online
Brattain Member
*****
Karma: 613
Posts: 49258
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

At 19 posts, you certainly should be aware that we need more details than what you provided. We're all familiar with the Mega, but an LM92 is a lot less common. So, a link to that device would be useful.

Quote
This works, but the Bytes which are read by Wire.read() have too much "1"'s, so the reported temperature is some degrees to high.
Some code and some proof (serial output) would be useful. Possibly, you need to ignore some bits, of the device is, for instance, only setting 12 bits and you are reading 16.

Quote
I used internal pullups as well as external pullups
A schematic would be useful, or, at a minimum a picture.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 25
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

LM92: http://www.datasheetcatalog.org/datasheet/nationalsemiconductor/LM92.pdf

Wiring : SDA to SDA , SCL to SCL, both with 4,7k pullups to 5V.

Code:
                            byte msb = 0;
                            byte lsb = 0;
                            long start = millis();
                            Wire.requestFrom(75,2);
                            while((Wire.available() < 2) && (millis()-start) < 1500) {
                            }
                            msb = Wire.read();
                            lsb = Wire.read();
                          
                            Serial.println(lsb, BIN);
                            Serial.println(msb, BIN);
                        
                            int lmtemp=0;
                            lmtemp = ((msb << smiley-cool | (lsb)) >> 3;
                            Serial.println(lmtemp, BIN);
                            
                            float tempfl = lmtemp * 0.0625;
Logged

Seattle, WA USA
Online Online
Brattain Member
*****
Karma: 613
Posts: 49258
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You are left shifting the byte smile face times?

The Wire.requestFrom() method blocks until the requested number of bytes arrives. The while loop that follows is useless.

Is the msb or the lsb the one that "has too many 1s"? If it is the msb, then notice that the link you posted says that the device returns 12 bits of data, and you are assuming that all 16 of them are important and valid. You need to mask off the upper 4 bits of msb.

Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 25
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thank you PaulS for your quick reply.
I don't know how the smiley came in there, of course it means "8".
The temperature is returned in 12 bits + sign(msb) = 13 bits. (while negative temperature can't occur in my application).
These are the msb bits, the LM 92 returns. The lower 3 bits are status bits, unimportant for me, therefore ">>3".

I don't think, it's a software problem because it gets worse the longer the cable is.

I just can say about the msb, that there are to much "1" read by Wire.read(). The lsb represents to small temperature differences to verify.

« Last Edit: October 11, 2012, 07:48:22 am by fs007 » Logged

Seattle, WA USA
Online Online
Brattain Member
*****
Karma: 613
Posts: 49258
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
The lower 3 bits are status bits, unimportant for me, therefore ">>3".
And the upper 4 bits of the MSB (or at least the upper 3) don't mean anything, either.

So, << 3 the msb to get rid of them, then >> 3 the msb, to get the 5 useful bits back where they belong.

Quote
The LM92 is a digital temperature sensor and thermal window
comparator with an I2C™ Serial Bus interface and an accuracy of ±0.33°C.
I2C is meant for communication between chips ON THE SAME BOARD. 10" is a pretty larger board. 10' is a ridiculous size for a PCB.

On the same board, the components are connected by traces, not wire. The wire acts like an antenna, picking up noise.

If you need to have the sensor that far away from the Arduino, that sensor is not the one you want.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 25
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
And the upper 4 bits of the MSB (or at least the upper 3) don't mean anything, either.
The msb of the first byte is temperature sign, followed by 12 bits of temperature data. The last (lowest) 3 Bits are status bits (that i don't need). Look at the datasheet (-> temperature register).

I used the LM92 with another mcu over a distance of more than 30 feet absulotly reliable. (shielded cable of course)
Are there any experiences about the Mega2560 and it's I2C interface ? Is it possible to use I2C for longer distances ?; maybe with some additional hardware ?

I tried to reduce the wire library's bitrate by editing the line
#define TWI_FREQ 100000L  to
#define TWI_FREQ 25000L
in wire.h, but couldn't see any difference in data reliability. Are there other hacks necessary to reduce bitrate ?

There is another thing, that makes me wonder: transferred data is quite stable (at stable temperature), but a few degrees to high. Doesn't look like the influence of noise etc.
« Last Edit: October 11, 2012, 08:16:27 am by fs007 » Logged

Seattle, WA USA
Online Online
Brattain Member
*****
Karma: 613
Posts: 49258
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
The msb of the first byte is temperature sign, followed by 12 bits of temperature data.
How are you fitting 13 bits in one 8 bit byte?

Quote
I used the LM92 with another mcu over a distance of more than 30 feet absulotly reliable. (shielded cable of course)
Are you still using shielded cable? Are there any changes to the environment? More noise, more electrical activity? What did the code on the other mcu look like?

Quote
Are there other hacks necessary to reduce bitrate ?
Why do you think you need to?
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 25
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
How are you fitting 13 bits in one 8 bit byte?
Not at all. My code:
int lmtemp=0;
lmtemp = ((msb << 8 | (lsb)) >> 3;

I did not program the other mcu, was no Atmel chip.

Quote
Are you still using shielded cable?
I tried shielded and unshielded cable. No difference over 10 inches.

Quote
Why do you think you need to?
I think, less bitrate makes bus-timing less critical. Furthermore there may be influence from SCL with 100khz to SDA when using longer cable.

There is another strange thing: You wrote, Wire.requestFrom would block. When a disconnet the LM92, there is no blocking but msb and lsb are read by Wire.read with 11111111 each.
« Last Edit: October 11, 2012, 08:39:08 am by fs007 » Logged

Pages: [1]   Go Up
Jump to: