working with external memory
Hi,
I'm looking at using an external Eprom (something like an 24LC256) to store time and temperatures, which can then be downloaded to a PC application via the serial port. However I need some pointers from you guys.
I currently have a RTC chip from which I use just time information at present.
Code:
I2CRead SDApin,SCLpin,$D0,$00,[RTCSec,RTCMin,RTCHour,RTCWDay,RTCDay,RTCMonth,RTCYear,RTCCtrl] ; read DS1307 chip
I then have the following routine to give me Hrs and Mins which I use in parts of the program where I need to compare the current time to pre-sets
Code:
timeH=(RTCHour>>4) 'convert the BCD format of the hours register and store in variable timeH
timeH=(timeH &$03)*10
timeH=timeH+(RTCHour&$0F)
timeM=(RTCMin>>4)
timeM=(timeM &$07)*10
timeM=timeM+(RTCMin&$0F) 'convert the BCD format of the mins register and store in variable timeM
Temperatures are read from a DS18B20 (4 off) and simply end up and an array variable - Temperatures[0] - [3], and are represented by a 3 digit decimal, so 234 would be 23.4C.
There should not be much change in the temperatures as this is for my thermostat project, so the logging interval doesn't need to be too frequent (as in realtime !) probably once per minute, maybe once every 5 min - depending on the amount of data I could store in the chip. So I guess I need to use something like
Code:
IC2write, address, timeH, timeM, temperatures[0], temperatures[1], temperatures[2], temperatures[3]
I would then have a "download data" button on the PC application which would send something like "D" to the RS232 port and then once detected jumps to a subroutine where it then reads the chips contents, sends them as a data stream back to the PC application, so a single data line would probably look like
So sending that via serial
Code:
Hserout [dec TimeH, TimeM]
Hserout [DEC3 Temperatures(0)]
Hserout [DEC3 Temperatures(1)]
Hserout [DEC3 Temperatures(2)]
Hserout [DEC3 Temperatures(3)]
This is where I get stumpped !
I would probably need to use some form of delimiting character to indicate the end of a data line, or could simply send a long data stream and let the software start a new line after every 16 digits. Either way I would need to loop the above in some way for each line of data. I would also would like the memory contents cleared after the "log file" has been downloaded, so would need suggestions on how to do that.
I would welcome your ideas, and if possible some sample code.
Character delimiters recommended
Your suggested data output string needs comma delimiters since you cannot be certain of the character length of each value. You could serout each word as Dec3 mYvAR to force them all to a known length but that can complicate the end use of the data. If you comma delimit each value, terminate the line with <cr><lf> and label the file as MyLog.csv then Excel can open the file and graphing the data is a breeze.
I use word variables for TemperatureLogged = 1000 + (10*MeasuredTemperature) and depending on actual temperatures the number can have two or three digits. By adding 1000 I can send negative values without needind a sign bit. e.g 890 means -1.1C and 1234 +23.4C
My data loggers record date & time, temperature, pressure, accelerometers for an activity indication and heart rate. I log the data to M25P128 serial memory chips.
HTH
BrianT
Code to read and write to M25P128
Hi Ruben,
Try this. I have several methods for reading and writing to the M25Pxxx family. All work but the ones not commented out are the fastest. In some infrequent calls I have left the slow routines in place as they don't add any significan time to the download of data from the M25Pxxx memory.
[code]
ReadFromM25P128:
memclk = 0 'data change point
memclk = 1 : reply.7 = memq : memclk = 0
memclk = 1 : reply.6 = memq : memclk = 0
memclk = 1 : reply.5 = memq : memclk = 0
memclk = 1 : reply.4 = memq : memclk = 0
memclk = 1 : reply.3 = memq : memclk = 0
memclk = 1 : reply.2 = memq : memclk = 0
memclk = 1 : reply.1 = memq : memclk = 0
memclk = 1 : reply.0 = memq : memclk = 0
'takes 50 uSecs per character
debug #reply, ", " 'Debug takes 6.7 mSecs
return
RDSRWIP: 'reads the Status Register - waits for WIP bit to go low
'Data from M25P128 changes on fall of clock so sample on rise of clock.
code = $05 'Read Status Register code
gosub sendcode
WIPclr:
for shift = 7 to 0 step -1 'read 8 bit reply
high memclk : reply.0[shift] = memq : low memclk : pauseus 1
next shift
if reply.0 = 1 then wipclr
return
SendCode: 'Serial MSB first sends the CODE byte from PIC to M25P128
TRISE.0 = 0 : PortE.0 = 0 : memclk = 0 'MemClk
TRISC.0 = 0 : PortC.0 = 0 : memd = 0 'MemD
' for shift = 7 to 0 step -1 'send MSB first
' memclk = 0 : memd = code.0[shift] : memclk = 1: pauseus 1 : memclk = 0
' next shift 'this is SLOW ~500 uSecs per character
memclk = 0
memclk = 0 : memd = code.7 : memclk = 1
memclk = 0 : memd = code.6 : memclk = 1
memclk = 0 : memd = code.5 : memclk = 1
memclk = 0 : memd = code.4 : memclk = 1
memclk = 0 : memd = code.3 : memclk = 1
memclk = 0 : memd = code.2 : memclk = 1
memclk = 0 : memd = code.1 : memclk = 1
memclk = 0 : memd = code.0 : memclk = 1
' much faster, takes about 52 uSecs per character
return
/[code]
You can see here I have several methods for reading from the M25P128. The decrementing loop "... for shift = 7 to 0 step -1..." works and is simple BUT it takes about 500 uSecs per character.
HTH
BrianT