DS1624 protocol problems

PaioX

New Member
Hi (again),
I've build a simple circuit that use a 18X and a DS1624 i2c temperature sensor.
I've used two 4,7K pullup resistor on i2c bus, but I'm still having problem maybe with bin->dec conversion or i2c data transfer (sometimes i read 255°C).
I'm powering the picaxe via a LM7805 with a small cap between power rails.
Could someone help me to check the code please?!
Tnx


Code:
'Device Address
SYMBOL ads1624 = %10010000

'Device Specifics
SYMBOL access_config = $ac
SYMBOL rd_temp = $aa
SYMBOL start_convert_t = $ee 


main:
GOSUB init_ads1624 'set single shot mode
GOSUB rtd ' read tempeture and display
END


init_ads1624:
I2CSLAVE ads1624, I2CFAST, I2CBYTE
WRITEI2C access_config, ($00) 'protocol error?
PAUSE 300
WRITEI2C start_convert_t, ($00)
PAUSE 100
RETURN


rtd:
READI2C rd_temp, (b0, b1)
PAUSE 200
w0=%0001100100010000
'bin->dec
w1 = b1 'decimal part
'fractional conversion
w2 = w0 & %0000000000001000 MAX 1 * 03125 'minimum temp increment 0.03125°
w2 = w0 & %0000000000010000 MAX 1 * 06250 + w2
w2 = w0 & %0000000000100000 MAX 1 * 12500 + w2
w2 = w0 & %0000000001000000 MAX 1 * 25000 + w2
w2 = w0 & %0000000010000000 MAX 1 * 50000 + w2

SERTXD("Temp = ",#w1,".") 'Show decimal part

IF b1 > 16 THEN NoLeadZero 'Add or not a zero after the dot
SERTXD("0")


NoLeadZero:
SERTXD(#w2,CR,LF) 'fract part
PAUSE 200
GOTO rtd
 

hippy

Ex-Staff (retired)
According to page 7 of the DS1624 datasheet, the 16-bit temperature is transmitted MSB first. Your READI2C reads it LSB first, you need -

READI2C rd_temp, ( b1, b0 )

You also have a bug with your "IF b1 > 16" to add a leading zero when w0 = $0018. A better test would be -

If w0 < 10000 Then ' add leading zero

There's a further problem with overflow when w0 = $00C0, for

w2 = w0 & %0000000001000000 MAX 1 * 25000 + w2
w2 = w0 & %0000000010000000 MAX 1 * 50000 + w2

w2 = 50000 + 25000 = 75000 which overflows 65535.
 

westaust55

Moderator
Firstly, where your new question is in relation to the same topic as you earlier posts, it is warranted to post under the original thread. This provides a flow of information and makes it easier for others to understand the question.
For example I have just had to find your earlier thread to quickly access the DS1624 datasheet.


and next, onto the code . .

I can see where you may have though that your readi2c command sequence is b0, b1 from looking at the Read diagram on datasheet page 5, but from the table on datasheet page 11, hippy is correct and the MSByte is sent first so the order needs to be b1, b0.


Where you have the program line:
WRITEI2C start_convert_t, ($00)
After sending the start_convert_t control code no further data is required.
As such try:
WRITEI2C (start_convert_t)


Then, where you read the temp from the DS1624, you had the line:
READI2C rd_temp, (b0, b1)
Based upon the diagram on page 5 and the table on page 11, you need to break this down as:
WRITEI2C (rd_temp) ; sent the command to initiate a temperature send
READI2C (b1, b0) ; then read the actual temp data



I presume that the line:
w0=%0001100100010000
is only a test line. It is otherwise preventing you using the actual temperature.


By adjusting your program and scaling to avoid maths overflow, you may get 4 decimal places with (I believe) ~0.0001 degree maths error using:
w2 = w0 & %0000000000001000 MAX 1 * 02083
w2 = w0 & %0000000000010000 MAX 1 * 04166 + w2
w2 = w0 & %0000000000100000 MAX 1 * 08333 + w2
w2 = w0 & %0000000001000000 MAX 1 * 16666 + w2
w2 = w0 & %0000000010000000 MAX 1 * 33340 + w2

w2 = w2 / 20 * 3


and here is an alternate quick way to extract the temperature to two decimal places without maths overflow:
Whole Degrees = w0 / 256
Fraction = w0 // 256 * 250 / 640
Then, if fraction is less than 10, you can print a leading zero.
 

Attachments

MartinM57

Moderator
As well as all the above, try putting a SERTXD(CR,LF,"b0=",#b0,' b1=",#b1) after your readi2c command - then you can see if you are getting sensible (i.e. expected, given the actual temperature) values back from the read command.

This will help you identify if it is an i2c problem or a maths problem.
 
Last edited:

hippy

Ex-Staff (retired)
This is how I'd display the received temperature ...

w0 = %0111111111111000 ' +127.96875
Gosub ShowTemperature

w0 = %1110011011110000 ' -25.06250
Gosub ShowTemperature

End

ShowTemperature:
SerTxd( "Temp = " )
If bit15 = 1 Then
SerTxd( "-" )
w0 = w0 ^ %1111111111111000 + %1000
Else
SerTxd( "+" )
End If
w1 = bit3 * 0312
w1 = bit4 * 0625 + w1
w1 = bit5 * 1250 + w1
w1 = bit6 * 2500 + w1
w1 = bit7 * 5000 + w1
SerTxd( #b1, "." )
If w1 = 0 Then : SerTxd( "00" ) : End If
If w1 < 1000 Then : SerTxd( "0" ) : End If
SerTxd( #w1 )
w1 = bit3 * 5
SerTxd( #w1, CR, LF )
Return
 
Last edited:

PaioX

New Member
WRITEI2C (rd_temp) ; sent the command to initiate a temperature send
READI2C (b1, b0) ; then read the actual temp data
On the datasheet it also say to send <cadr,1> before receiving the two data byte, so have I to put also a WRITEI2C (%10010001) before READI2C?

Thanks to all for your help :)

p.s. I've a question about writei2c command, the manual says WRITEI2C location,(variable,...) but what is location used for?I think that to config the ds1624 I've to put all in bracket such
WRITEI2C (access_config, $01) is it correct?Or WRITEI2C access_config, ($01)?
 

Paride

New Member
Have you cheked the R/~W bit?Picaxe use 0 for read and 1 for write, but DS1624 seems to use 1 for read and 0 for write.
 

PaioX

New Member
Ok solved with hippy's routine.
I had to add the extra 0x00 after the start_convert_t to avoid program crash (I don't know why, but without 0x00 the program stops after some minute)

Now...let's experiment with internal eeprom :p
 

westaust55

Moderator
Thanks to all for your help :)

I've a question about writei2c command, the manual says WRITEI2C location,(variable,...) but what is location used for?I think that to config the ds1624 I've to put all in bracket such
WRITEI2C (access_config, $01) is it correct?Or WRITEI2C access_config, ($01)?
when sending commands to the i2c device you put the data in the brackets.

By way of example, here is some code that I have written previously to control and fetch data from an i2c device
Code:
      SLAVEi2c PRS, i2cslow, i2cbyte 	; set up to write to and read from the Pressure Sensor 
     
      WRITEi2c ($FF,$F0)
      PAUSE 50					; must pause at least 40ms for analogue to digital conversion
      WRITEi2c ($FD)
      READi2c  (PMSB, PLSB)			; fetch the Pressure MSB and LSB
      
      WRITEi2c ($FF,$E8)
      PAUSE 50					; must pause at least 40ms - here we give just a little more time
      WRITEi2c ($FD)
      READi2c  (TMSB, TLSB)			; fetch the Temperature MSB and LSB
      LOW Preset					; place the pressure sensor module into idle mode
The location parameter is only used where a device, such as memory has many locations and you need to indicate where to start reading from / writing to.

here is an example of reading several locations from an EEPROM. The location here is represented by the variable "PRE":
Code:
SLAVEi2c PRE, i2cslow, i2cbyte	; set up to read the Pressure Sensor constants
	READi2c PreConst1,(b3, b2, b5, b4, b7, b6, b9, b8)	; read the first 8 values from the pressure module
 
Last edited:

westaust55

Moderator
On the datasheet it also say to send <cadr,1> before receiving the two data byte, so have I to put also a WRITEI2C (%10010001) before READI2C?
That right and that is exactly what the code I gave you is doing.
WRITEI2C (rd_temp) ; sent the command to initiate a temperature send
READI2C (b1, b0) ; then read the actual temp data​

The WRITEi2c command sends the address (cadr) and the 0 bit automatically then sends the rd_temp instruction

The READi2c command again sends the address (cadr) and the 1 bit automatically then reds back the two bytes of data.
 

westaust55

Moderator
Have you cheked the R/~W bit?Picaxe use 0 for read and 1 for write, but DS1624 seems to use 1 for read and 0 for write.
@Paride,

welcome to the PICAXE forum.

Your comment is unfortunately in error.

the R/W bit is always 1 for Read and 0 for Write. If you look closely there is a line (bar) over the "W" which indicates active when low (=0).

See also the attached extract from a typical EEPROM datasheet.
 

Attachments

Top