
Introduction
This discussion shows how to interface a Dallas Semiconductor DS1621 Thermometer and 24LC32 Serial EEPROM with the Basic Stamp BS2 so as to realize a 4000 byte data acquisition system using only two signal leads. Note that this could easily be extended t o eight DS1621s and eight 24LC32s to provide measurements at eight points and 32,000 bytes of memory storage.
Note that the combined cost of the 1621 and 24LC32 is less than $8.00.
Discussion
This discussion is in rough form. It will be reworked and eventually it will become a part of a new book which discuuses interfacing with serial devices. But, in the interim, you may find it useful.
Program DATA_LOG.BS2 assumes that the DS1621 is set for an A2A1A0 address of 1 and the 24LC32 for an address of 0. Note that in fact, as the two are different devices, they both could have been assigned the same 3-bit address. I used different addresses to illustrate how the variable "device" must be changed depending on which device the Stamp is communicatiing with.
When the Stamp is reset, the program forks based on the setting of input bit 8 to either begin a logging sequence or to dump the previously logged data to the PC. Thus, a data acquisition unit consisting only of the Stamp and the two ICs might be deployed to measure and log temperature. The user would set input 8 to a logic 0 and reset the processor to begin the logging sequence. The logged data might later be uploaded to a PC, by first setting input 8 to a logic one and resetting the Stamp.
The current technique for uploading is crude, consisting only of the use of the Stamp "debug" command. We are working on serial software for the PC which will permit the data to be saved to disk in a format which lends later analysis using spreadsheet. (Note that the various debug writes to the terminal must be removed. I left them in as I found them to be invaluable in appreciating what was going on in communicating with the I2C devices.)
The data logging portion of the program is a combination of routines developed for the DS1621 and 24LC32.
The configuration register in the DS1621 is set to $02. In fact, this need only be done once in the lifetime of the device and could well be done in another program.
The program then takes 4000 measurements at nominally one minute intervals. The DS1621 is commanded to start conversion and then a conversion is read from the 1621. The conversion process is then stopped to conserve power. The data is then written to E EPROM and for good measure, I also read the data back from the EEPROM. This verification is only for debugging and should be removed in the final product.
In addition to improving on the crude technique for uploading the data to the PC, there are a number of other possible areas for improvement.

' DATA_LOG.BS2
'
' Illustrates implementation of a data logger using a single DS1621
' thermometer and a 32 K serial EEPROM on a single two wire pair.
'
'
' BS2 DS1621 24LC32
'
' A2=A1=A0=1 A2=A1=A0=0
'
' Pin5 (term 10) --------------- SCL (term 2) ----- SCL (term 6)
' Pin4 (term 9) ---------------- SDA (term 1) ----- SDA (term 5)
'
' Note that 10K pullup resistors to +5VDC are required on both signal
' leads.
'
' Debug and Pause statements were included only to see what is going on.
'
'
' copyright Peter H. Anderson and Towanda L. Malone, MSU, March 18, '97
'
address var byte ' eeprom address
device var byte ' device 0-7
o_byte var byte ' byte to send to device
i_byte var byte ' byte fetched from eeprom
i_9_bit var word ' 9 bit reading fetched from 1621
dta var byte ' data to be programmed in eeprom
T_C var byte ' Temperature in degrees C
n var byte ' index
b var bit ' bit
times var word ' number of measurements
ack_bit var bit
SDA_PIN con 4
SCL_PIN con 5
SDA_OUT var out4
SCL_OUT var out5
SDA_IN var in4
SDA_DIR var dir4
OUT con 1
IN con 0
dirs=$f0ff
main
if IN0=8 then log_data ' if IN8 is zero log data
' if at logic 1 then dump to PC
dump_data ' read each location in turn and output to terminal
address = $000
device=0 ' eeprom
for times = 0 to 3999
gosub read_random_data
debug dec i_byte
debug $0d ' newline character
address=address+1
next
stop
log_data
device=1 ' DS1621. A2=0, A1=0, A0=1
gosub config_1621 ' write to 02 configuration register
address=$000
for times = 0 to 3999 ' 4000 measurements
device = 1
gosub start_convert ' write start convert to DS1621
gosub meas
T_C = i_9_bit/2 ' sacrifice some accuracy
debug dec T_C
gosub stop_convert ' stop conversion to save power
device=0 ' now the eeprom
dta = T_C
gosub write_random_data ' save the temperature
gosub read_random_data ' just to check
debug dec i_byte
sleep 60 ' pause for a minute
address=address+1 ' next address
next
stop
config_1621 'configure DS1621
gosub start
o_byte = $90 | (device<<1) ' 1001 a2 a1 a0 0
gosub out_byte
gosub nack
o_byte = $ac ' config as CPU control, continuous
gosub out_byte
gosub nack
o_byte = $02
gosub out_byte
gosub nack
high SCL_PIN
gosub sstop
return
start_convert ' begin temperature conversion
gosub start
o_byte = $90 | (device<<1)
gosub out_byte
gosub nack
o_byte = $ee
gosub out_byte
gosub nack
high SCL_PIN
gosub sstop
return
meas ' sends read temperature command
' value fetched from DS1621 return in i_9_bit
gosub start
o_byte = $90 | (device<<1) ' note this is a write
gosub out_byte
gosub nack
o_byte = $aa ' command to read temperature
gosub out_byte
gosub nack
gosub start ' note there is no stop
o_byte = $90 | (device<<1) | $01 ' now a read
gosub out_byte
gosub nack
gosub get_9_bits
high SCL_PIN
gosub sstop
return
stop_convert ' send command $22 to stop the continuous conversion
gosub start
o_byte = $90 | (device<<1)
gosub out_byte
gosub nack
o_byte = $22
gosub out_byte
gosub nack
high SCL_PIN
return
write_random_data 'writes specified data to specified address
agn
gosub start
o_byte=$a0 | (device << 1) ' 1 0 1 0 a2 a1 a0 0
gosub out_byte
gosub nack
o_byte= address >> 8 ' high byte of address
gosub out_byte
gosub nack
o_byte= address & $ff ' low byte of address
gosub out_byte
gosub nack
o_byte=dta
gosub out_byte
gosub nack
gosub sstop
gosub ack ' ack polling
if ack_bit=1 then agn
return
read_random_data ' reads data from specified address
' returns in variable in_byte
gosub start
o_byte=$a0 | (device << 1) ' 1 0 1 0 a2 a1 a0 0
gosub out_byte
gosub nack
o_byte= address >> 8 ' high byte of address
gosub out_byte
gosub nack
o_byte= address & $ff ' low byte of address
gosub out_byte
gosub nack
gosub start
o_byte=$a0 | (device << 1) | $01' 1010 a2 a1 a0 1
gosub out_byte
gosub nack
gosub get_byte
gosub nack
gosub sstop
return
out_byte ' shift out o_byte beginning with most sig bit
low SDA_PIN
for n=0 to 7
b= (o_byte >> 7) & 1
if (b=1) then out_one
SDA_DIR=OUT
debug "0"
_clk
high SCL_PIN
pause 100
low SCL_PIN
pause 100
o_byte=o_byte << 1
next
SDA_DIR=IN
return
out_one
SDA_DIR=IN
debug "I"
goto _clk
get_9_bits ' read 9 bits from DS1621, most sig bit first
SDA_DIR=IN 'input
i_9_bit=0
for n=0 to 8
pause 200
high SCL_PIN ' clock high, then read SDA, then clock low
pause 200
i_9_bit=(i_9_bit << 1) | SDA_IN
debug dec SDA_IN
low SCL_PIN
next
SDA_DIR=OUT 'output
return
get_byte ' read 8 bits from 24LC32, most sig bit first
SDA_DIR=IN 'input
i_byte=0
for n=0 to 7
pause 200
high SCL_PIN ' clock high, then read SDA, then clock low
pause 200
i_byte=(i_byte << 1) | SDA_IN
debug dec SDA_IN
low SCL_PIN
next
SDA_DIR=OUT 'output
return
nack
SDA_DIR=IN ' input just in case
ack_bit=1
high SCL_PIN
ack_bit=SDA_IN
debug "A"
debug dec ack_bit
debug $0d
low SCL_PIN
SDA_DIR=OUT ' output
return
ack
debug "POLL"
gosub start
o_byte=$a0 | (device << 1)
gosub out_byte
gosub nack
return
start
high SDA_PIN
high SCL_PIN
debug "START"
debug $0d
low SDA_PIN 'bring SDA low while clock is high
low SCL_PIN
return
sstop
low SDA_PIN
high SCL_PIN
pause 10
high SDA_PIN 'bring SDA high while clock is high
debug "STOP"
debug $0d
return