HELP! with EEPROM and Sensirion SHT11
mellomary
Posts: 3
My name is Mary and I need help with storing my temperature/humidity values from the Sensirion SHT11 to the EEPROM, and then retreiving those values when I rerun a separate program.· I know I would have to use the WRITE/READ commands, I just don't know how.· I am using the exact same code that the sensor came with, I just need help with imputing the WRITE/READ into the code.· I need at least 24 hours worth of data.· The code is below.· I have put my coding and questions·in red color.· I am not that skilled at using this Basic Stamp and coding for it...it's not my kinda thing.· I need help ASAP!· This is for a class of mine.· Thank you.
' {$STAMP BS2}
' {$PBASIC 2.5}
ShtData· PIN 1
Clock··· PIN 0········· 'bi-directional data
ShtTemp·· CON %00011····· 'read temperature
ShtHumi·· CON %00101····· 'read humidity
ShtStatW· CON %00110····· 'status register write
ShtStatR· CON %00111····· 'status register read
ShtReset· CON %11110····· 'soft reset
Ack······ CON 0
NoAck···· CON 1
No······· CON 0
Yes······ CON 1
DegSym··· CON 186········ 'degree symbol for DEBUG
ioByte··· VAR Byte······· 'data from/to SHT11
ackBit··· VAR Bit········ 'ack/nak from/to SHT11
toDelay·· VAR Byte······· 'timeout delay timer
timeOut·· VAR Bit········ 'timeout status
soT······ VAR Word······· 'temp counts from SHT11
tC······· VAR Word······· 'temp - Celcius
tF······· VAR Word······· 'temp - Fahrenheit
soRH····· VAR Word······· 'humidity counts
rhLin···· VAR Word······· 'humidity; linearized
rhTrue··· VAR Word······· 'humidity; compensated
status··· VAR Byte······· 'status byte
eeaddress VAR Byte (I would need to make a command like this for the WRITE/READ command, right?)
Initialize:
· GOSUB SHT_Connection_Reset····· 'reset device connection
· PAUSE 250
· DEBUG CLS,
······· "SHT11 Sensor Demo", CR,
······· "
", CR
Main:
· DO
··· GOSUB SHT_Measure_Temp
··· DEBUG CRSRXY, 0, 3,
····· "soT..... ", DEC soT, CR,
····· "tC...... ", DEC (tC / 10), ".", DEC1 tC, DegSym, " ", CR,
····· "tF...... ", DEC (tF / 10), ".", DEC1 tF, DegSym, " "
··· GOSUB SHT_Measure_Humidity
··· DEBUG CRSRXY, 0, 7,
····· "soRH.... ", DEC soRH, CR,
····· "rhLin... ", DEC (rhLin / 10), ".", DEC1 rhLin, "% ", CR,
····· "rhTrue.. ", DEC (rhTrue / 10), ".", DEC1 rhTrue, "% "
····· WRITE 0, Word tF, Word rhTrue (would I put the WRITE command here?)
··· PAUSE 1000
· LOOP
· END
SHT_Connection_Reset:
· SHIFTOUT ShtData, Clock, LSBFIRST, [noparse][[/noparse]$FFF\9]
SHT_Start:
· INPUT ShtData··········· 'let pull-up take high
· LOW Clock
· HIGH Clock
· LOW ShtData
· LOW Clock
· HIGH Clock
· INPUT ShtData
· LOW Clock
· RETURN
'measure temperature
'-- celcius = raw * 0.01 - 40
'-- fahrenheit = raw * 0.018 - 40
'
SHT_Measure_Temp:
· GOSUB SHT_Start·········· 'alert device
· ioByte = ShtTemp········· 'temperature command
· GOSUB SHT_Write_Byte····· 'send command
· GOSUB SHT_Wait··········· 'wait for measurement
· ackBit = Ack············· 'another read follows
· GOSUB SHT_Read_Byte······ 'get MSB
· soT.HIGHBYTE = ioByte
· ackBit = NoAck··········· 'last read
· GOSUB SHT_Read_Byte······ 'get LSB
· soT.LOWBYTE = ioByte
· tC = soT ** $1999 - 400·· 'convert to tenths C
· tF = soT ** $2E14 - 400·· 'convert to tenths F
· RETURN
'measure humidity
'
SHT_Measure_Humidity:
· GOSUB SHT_Start·········· 'alert device
· ioByte = ShtHumi········· 'humidity command
· GOSUB SHT_Write_Byte····· 'send command
· GOSUB SHT_Wait··········· 'wait for measurement
· ackBit = Ack············· 'another read follows
· GOSUB SHT_Read_Byte······ 'get MSB
· soRH.HIGHBYTE = ioByte
· ackBit = NoAck··········· 'last read
· GOSUB SHT_Read_Byte······ 'get LSB
· soRH.LOWBYTE = ioByte
· rhLin = (soRH ** $67AE) - (soRH ** $83 * soRH ** $5B) - 40
· rhTrue = (tC - 250) * (soRH ** $34) + rhLin
· RETURN
'sends "status"
'
SHT_Write_Status:
· GOSUB SHT_Start············ 'alert device
· ioByte = ShtStatW·········· 'write to status reg cmd
· GOSUB SHT_Write_Byte······· 'send command
· ioByte = status
· GOSUB SHT_Write_Byte
· RETURN
'returns "status"
'
SHT_Read_Status:
· GOSUB SHT_Start············ 'alert device
· ioByte = ShtStatW·········· 'write to status reg cmd
· GOSUB SHT_Read_Byte········ 'send command
· ackBit = NoAck············· 'only one byte to read
· GOSUB SHT_Read_Byte
· RETURN
'sends "ioByte"
'returns "ackBit"
'
SHT_Write_Byte:
· SHIFTOUT ShtData, Clock, MSBFIRST, [noparse][[/noparse]ioByte]·· 'send byte
· SHIFTIN· ShtData, Clock, LSBPRE,·· [noparse][[/noparse]ackBit\1] 'get ack bit
· RETURN
'returns "ioByte"
'sends "ackBit"
'
SHT_Read_Byte:
· SHIFTIN ShtData, Clock, MSBPRE, [noparse][[/noparse]ioByte]····· 'get byte
· SHIFTOUT ShtData, Clock, LSBFIRST, [noparse][[/noparse]ackBit\1] 'send ack bit
· INPUT ShtData································ 'release data line
· RETURN
SHT_Wait:
· INPUT ShtData································ 'data line is input
· timeOut = No································· 'assume no timeout
· FOR toDelay = 1 TO 250······················· 'wait ~1/4 second
··· IF (ShtData = 0) THEN EXIT
··· PAUSE 1
· NEXT
· IF (toDelay = 250) THEN timeOut = Yes········ 'loop completed = timeout
· RETURN
SHT_Soft_Reset:
· GOSUB SHT_Connection_Reset····· 'reset the connection
· ioByte = ShtReset·············· 'reset command
· ackBit = NoAck················· 'only one byte to send
· GOSUB SHT_Write_Byte··········· 'send it
· PAUSE 11······················· 'wait at least 11 ms
· RETURN
Code for READING·the data from the EEPROM (I don't think this·code is correct...it doesn't work.· I don't know how to· make it work!)·
' {$STAMP BS2}
' {$PBASIC 2.5}
tF· VAR Word
rhTrue· VAR Word
eeaddress VAR Byte
DEBUG "retrieving measurements", CR, CR
READ eeaddress, Word tF
READ eeaddress, Word rhTrue
DEBUG DEC3 eeaddress, "······ ", DEC3 tF, CR
DEBUG DEC3 eeaddress, "······ ", DEC3 rhTrue, CR
' {$STAMP BS2}
' {$PBASIC 2.5}
ShtData· PIN 1
Clock··· PIN 0········· 'bi-directional data
ShtTemp·· CON %00011····· 'read temperature
ShtHumi·· CON %00101····· 'read humidity
ShtStatW· CON %00110····· 'status register write
ShtStatR· CON %00111····· 'status register read
ShtReset· CON %11110····· 'soft reset
Ack······ CON 0
NoAck···· CON 1
No······· CON 0
Yes······ CON 1
DegSym··· CON 186········ 'degree symbol for DEBUG
ioByte··· VAR Byte······· 'data from/to SHT11
ackBit··· VAR Bit········ 'ack/nak from/to SHT11
toDelay·· VAR Byte······· 'timeout delay timer
timeOut·· VAR Bit········ 'timeout status
soT······ VAR Word······· 'temp counts from SHT11
tC······· VAR Word······· 'temp - Celcius
tF······· VAR Word······· 'temp - Fahrenheit
soRH····· VAR Word······· 'humidity counts
rhLin···· VAR Word······· 'humidity; linearized
rhTrue··· VAR Word······· 'humidity; compensated
status··· VAR Byte······· 'status byte
eeaddress VAR Byte (I would need to make a command like this for the WRITE/READ command, right?)
Initialize:
· GOSUB SHT_Connection_Reset····· 'reset device connection
· PAUSE 250
· DEBUG CLS,
······· "SHT11 Sensor Demo", CR,
······· "
", CR
Main:
· DO
··· GOSUB SHT_Measure_Temp
··· DEBUG CRSRXY, 0, 3,
····· "soT..... ", DEC soT, CR,
····· "tC...... ", DEC (tC / 10), ".", DEC1 tC, DegSym, " ", CR,
····· "tF...... ", DEC (tF / 10), ".", DEC1 tF, DegSym, " "
··· GOSUB SHT_Measure_Humidity
··· DEBUG CRSRXY, 0, 7,
····· "soRH.... ", DEC soRH, CR,
····· "rhLin... ", DEC (rhLin / 10), ".", DEC1 rhLin, "% ", CR,
····· "rhTrue.. ", DEC (rhTrue / 10), ".", DEC1 rhTrue, "% "
····· WRITE 0, Word tF, Word rhTrue (would I put the WRITE command here?)
··· PAUSE 1000
· LOOP
· END
SHT_Connection_Reset:
· SHIFTOUT ShtData, Clock, LSBFIRST, [noparse][[/noparse]$FFF\9]
SHT_Start:
· INPUT ShtData··········· 'let pull-up take high
· LOW Clock
· HIGH Clock
· LOW ShtData
· LOW Clock
· HIGH Clock
· INPUT ShtData
· LOW Clock
· RETURN
'measure temperature
'-- celcius = raw * 0.01 - 40
'-- fahrenheit = raw * 0.018 - 40
'
SHT_Measure_Temp:
· GOSUB SHT_Start·········· 'alert device
· ioByte = ShtTemp········· 'temperature command
· GOSUB SHT_Write_Byte····· 'send command
· GOSUB SHT_Wait··········· 'wait for measurement
· ackBit = Ack············· 'another read follows
· GOSUB SHT_Read_Byte······ 'get MSB
· soT.HIGHBYTE = ioByte
· ackBit = NoAck··········· 'last read
· GOSUB SHT_Read_Byte······ 'get LSB
· soT.LOWBYTE = ioByte
· tC = soT ** $1999 - 400·· 'convert to tenths C
· tF = soT ** $2E14 - 400·· 'convert to tenths F
· RETURN
'measure humidity
'
SHT_Measure_Humidity:
· GOSUB SHT_Start·········· 'alert device
· ioByte = ShtHumi········· 'humidity command
· GOSUB SHT_Write_Byte····· 'send command
· GOSUB SHT_Wait··········· 'wait for measurement
· ackBit = Ack············· 'another read follows
· GOSUB SHT_Read_Byte······ 'get MSB
· soRH.HIGHBYTE = ioByte
· ackBit = NoAck··········· 'last read
· GOSUB SHT_Read_Byte······ 'get LSB
· soRH.LOWBYTE = ioByte
· rhLin = (soRH ** $67AE) - (soRH ** $83 * soRH ** $5B) - 40
· rhTrue = (tC - 250) * (soRH ** $34) + rhLin
· RETURN
'sends "status"
'
SHT_Write_Status:
· GOSUB SHT_Start············ 'alert device
· ioByte = ShtStatW·········· 'write to status reg cmd
· GOSUB SHT_Write_Byte······· 'send command
· ioByte = status
· GOSUB SHT_Write_Byte
· RETURN
'returns "status"
'
SHT_Read_Status:
· GOSUB SHT_Start············ 'alert device
· ioByte = ShtStatW·········· 'write to status reg cmd
· GOSUB SHT_Read_Byte········ 'send command
· ackBit = NoAck············· 'only one byte to read
· GOSUB SHT_Read_Byte
· RETURN
'sends "ioByte"
'returns "ackBit"
'
SHT_Write_Byte:
· SHIFTOUT ShtData, Clock, MSBFIRST, [noparse][[/noparse]ioByte]·· 'send byte
· SHIFTIN· ShtData, Clock, LSBPRE,·· [noparse][[/noparse]ackBit\1] 'get ack bit
· RETURN
'returns "ioByte"
'sends "ackBit"
'
SHT_Read_Byte:
· SHIFTIN ShtData, Clock, MSBPRE, [noparse][[/noparse]ioByte]····· 'get byte
· SHIFTOUT ShtData, Clock, LSBFIRST, [noparse][[/noparse]ackBit\1] 'send ack bit
· INPUT ShtData································ 'release data line
· RETURN
SHT_Wait:
· INPUT ShtData································ 'data line is input
· timeOut = No································· 'assume no timeout
· FOR toDelay = 1 TO 250······················· 'wait ~1/4 second
··· IF (ShtData = 0) THEN EXIT
··· PAUSE 1
· NEXT
· IF (toDelay = 250) THEN timeOut = Yes········ 'loop completed = timeout
· RETURN
SHT_Soft_Reset:
· GOSUB SHT_Connection_Reset····· 'reset the connection
· ioByte = ShtReset·············· 'reset command
· ackBit = NoAck················· 'only one byte to send
· GOSUB SHT_Write_Byte··········· 'send it
· PAUSE 11······················· 'wait at least 11 ms
· RETURN
Code for READING·the data from the EEPROM (I don't think this·code is correct...it doesn't work.· I don't know how to· make it work!)·
' {$STAMP BS2}
' {$PBASIC 2.5}
tF· VAR Word
rhTrue· VAR Word
eeaddress VAR Byte
DEBUG "retrieving measurements", CR, CR
READ eeaddress, Word tF
READ eeaddress, Word rhTrue
DEBUG DEC3 eeaddress, "······ ", DEC3 tF, CR
DEBUG DEC3 eeaddress, "······ ", DEC3 rhTrue, CR
Comments
location var byte
location = 0··· (include this in the initialise routine)
WRITE· location,Word tF,Word rhTrue
location=location+4
To read the values
DO
READ· location,Word tF,Word rhTrue
location=location+4
DEBUG DEC tF," ",DEC rhTrue," ",CR
LOOP UNTIL location >········ (you will need a variable here to determine the number of samples you want to retrieve)
You said sample over a 24 hour period but how often are you collecting samples, maybe someone can help here but I would think your maximum sample rate would be every 15 minutes before you got close to overwriting program memory.
Jeff T.
You have to decide how often you can or need to log data in eeprom. As it stands, the program goes around the main loop once a second, but there won't be that much room to store data in the BS2. Find out how much room is left in the eeprom (using CTRL-M) and divide that into 24 hours to see how often you could store data. If you need more, you will have to add external memory or go for a BS2pe.
Do you have a real time clock on this system? I'm looking for a safe place to store the log pointer, where to put the next record and how many records are stored. You have to retrieve that number any time the Stamp is reset or powered up. It is possible to mark the data file so that the program can find the point where it left off and calculate how much is already stored.
The command to put data in memory will look like you have it except with a variable address that gets incremented:
And to read out the data, it has to use the eeaddress in a loop:
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Tracy Allen
www.emesystems.com
Post Edited (Tracy Allen) : 3/13/2007 12:37:34 AM GMT
After a phone conversation it appears that you will need 1392 data points which at 4 bytes each is 348 events you can log. So you can use Tracy’s example above and change the FOR…NEXT loop to be:
FOR eeaddress = 0 to 1391 STEP 4
What you will need to do is handle what happens when it is done (and memory is full). I hope this helps. Take care.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Chris Savage
Parallax Tech Support