I2c problem

Discussion about the ZBasic language including the System Library. If you're not sure where to post your message, do it here. However, do not make test posts here; that's the purpose of the Sandbox.
Post Reply
FFMan
Posts: 502
Joined: 09 January 2010, 12:52 PM

I2c problem

Post by FFMan »

Now i've done a few projects with I2c and i've always got them to work with either little or some effort.

I'm now trying to get a temperature reading from an LM75A but I can'get it to respond. I've tried a zx40n and 328l both h/w are s/w channels but i can't seem to get a response. I've got 4k7 pull-ups in place.

If i use i2cmd i get a return of -1

If i use bval = I2CPutByte(chanI2c, byAddress) i get a false returned

Does this suggest the device is simply not responding ?

The published default address is &h48
dkinzer
Site Admin
Posts: 3120
Joined: 03 September 2005, 13:53 PM
Location: Portland, OR

Re: I2c problem

Post by dkinzer »

FFMan wrote:If i use bval = I2CPutByte(chanI2c, byAddress) i get a false returned. Does this suggest the device is simply not responding ?
I would think so. Did you remember that the I2C slave address needs to be in the upper 7 bits? For a slave address of 0x48 you would use 0x91 for reading and 0x90 for writing.

You can see this more clearly, perhaps, in the timing diagram from the LM75A datasheet (excerpt attached).
Attachments
LM75A-I2C.jpg
LM75A-I2C.jpg (23.32 KiB) Viewed 4412 times
- Don Kinzer
FFMan
Posts: 502
Joined: 09 January 2010, 12:52 PM

Post by FFMan »

don

you are spot on - i'd missed that and when i looked at previous code for similar but different device which works on those address i overlooked it.

it works now thanks
FFMan
Posts: 502
Joined: 09 January 2010, 12:52 PM

Post by FFMan »

OK follow on question

Thanks to you I have the LM75a working on address &h91

Before i used the LM75a i tried the mcp9808 but i couldn't get it to work, partly because I wasn't entirely sure what the correct address is.

So knowing now i had working device (LM75a) and hardware i wrote a loop to put address sequentially out on i2c to see when i got a response. An address scan in other words.

I failed to get the mcp9808 to respond in the range 1-255, so i connected the known working lm75a in ran the scan again, but it failed to respond even when the scan hit the right address. Is this not a valid thing to do in I2c like this ?

Code: Select all

Call I2CStart(chanI2c)
	bval=false
	while bval=false and byAddress<255
		bval = I2CPutByte&#40;chanI2c, byAddress&#41;
		debug.print byAddress;" Addr ";bval
		sleep&#40;0.5&#41;
		byAddress=byAddress+1
	wend
dkinzer
Site Admin
Posts: 3120
Joined: 03 September 2005, 13:53 PM
Location: Portland, OR

Post by dkinzer »

FFMan wrote:Is this not a valid thing to do in I2c like this ?
No. Every transaction on the I2C bus begins with and "I2C Start signal" and ends with an "I2C Stop signal". Devices do not perform an address matching function until after the I2C Start and I would guess that they don't try to match again until another start signal occurs.

I think that this may work:

Code: Select all

    bval=false
    while bval=false and byAddress<=255
        Call I2CStart&#40;chanI2c&#41;
        bval = I2CPutByte&#40;chanI2c, byAddress&#41;
        Call I2CStop&#40;chanI2c&#41;
        debug.print byAddress;" Addr ";bval
        sleep&#40;0.5&#41;
        byAddress=byAddress + 2
    wend
Note that I modified the code to bump the address by two. If you initialize 'byAddress' to 1 that would result in scanning the 128 possible I2C addresses using a read operation. I don't think it is necessary to try both read and write.
- Don Kinzer
FFMan
Posts: 502
Joined: 09 January 2010, 12:52 PM

Post by FFMan »

ok that works i've established the decimal address as 48.

then i send character 5 to read the temp data.

I'm getting 2 bytes of data back but i'm not quite how i should interpret it as detailed on page 24 of the attached.

Do i map bits marked 2^7 to 2^-4 to the LSBs of a word then if the sign bit is set subtract if from 2047 ?

then divide it by 10000 to get 4 decimal digits ?

any help much appreciated
FFMan
Posts: 502
Joined: 09 January 2010, 12:52 PM

Post by FFMan »

found this online which should nail it:-

float temp = t & 0x0FFF;
temp /= 16.0;
if (t & 0x1000) temp -= 256;
dkinzer
Site Admin
Posts: 3120
Joined: 03 September 2005, 13:53 PM
Location: Portland, OR

Post by dkinzer »

FFMan wrote:found this online which should nail it
It didn't make sense to me and didn't produce the correct results. I modified it and incorporated it into a test program that demonstrates it is working.

Code: Select all

' Ths data array provides some test values for the LM75A
Dim lm75a_data as IntegerVectorData &#40;&#123;
    &H7d00,
    &H1900,
    &H0080,
    &H0000,
    &Hff80,
    &He700,
    &Hc900
&#125;&#41;

' This data array provides the Celsius temperatures for the above data
Dim lm75a_data_check as SingleVectorData &#40;&#123;
    125.0,
    25.0,
    0.5,
    0.0,
    -0.5,
    -25.0,
    -55.0
&#125;&#41;

Sub Main&#40;&#41;
    Dim i as Integer
    For i = 1 to UBound&#40;lm75a_data&#41;
        Call lm75a_convert_temp_data&#40;lm75a_data&#40;i&#41;, lm75a_data_check&#40;i&#41;&#41;
    Next i
End Sub

' This subroutine converts an LM75A data value to the corresponding temperature
Sub lm75A_convert_temp_data&#40;ByVal data as Integer, ByVal check as Single&#41;
    Dim temp as Single
    temp = CSng&#40;data And &Hff80&#41; / 256.0
    Debug.Print "LM75A value &H"; CStrHex&#40;data&#41;; " is "; Fmt&#40;temp, 2&#41;; "*C &#40;s/b&#41; "; Fmt&#40;check, 2&#41;
End Sub
- Don Kinzer
FFMan
Posts: 502
Joined: 09 January 2010, 12:52 PM

Post by FFMan »

thanks don.

just to be clear but it's of no matter, we got the LM75a working ok once i got the address right thanks to you. I then switched to the mcp9808 which i had failed to get working earlier and had parked. That is what this decode issue relates to.

from the mcp9808 i get returned decimal bytes 193 & 101 but i can't seem to make sense of them having tried various options.

temp in here would be in the region of 23-24c but i think the return is degrees F.

i'll try some more things tomorrow, ran out of time this evening
FFMan
Posts: 502
Joined: 09 January 2010, 12:52 PM

Post by FFMan »

actually with a bit more fiddling i got bytes 192 & 168 to convert to 26.5c using the code i posted earlier.

this sensor is more accurate than the lm75a returning 3 decimal places whereas the lm75a is only half a degree resolution.

thank you for your help
dkinzer
Site Admin
Posts: 3120
Joined: 03 September 2005, 13:53 PM
Location: Portland, OR

Post by dkinzer »

FFMan wrote:[T]his decode issue relates to [the MCP9808].
Sorry, I didn't catch that.
- Don Kinzer
FFMan
Posts: 502
Joined: 09 January 2010, 12:52 PM

Post by FFMan »

no apology necessary, it wasn't very clear and really should have been another post rather than a continuation

Anyhow, all good, 2 working temp sensors
Post Reply