working with external memory


Closed Thread
Results 1 to 16 of 16
  1. #1
    malc-c's Avatar
    malc-c Guest

    Default 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
    Code:
    1230300302297289
    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.

  2. #2
    Join Date
    May 2008
    Location
    Italy
    Posts
    825


    Did you find this post helpful? Yes | No

    Default

    I don't think one byte is enough to store your temperature . with one byte the maximum reading will be 25.5 degree then 25.6 will make your byte overflow to 0.

    Al.
    All progress began with an idea

  3. #3
    malc-c's Avatar
    malc-c Guest


    Did you find this post helpful? Yes | No

    Default

    Sorry, should of mentioned, they are words

    Code:
    Temperatures      VAR WORD[4]
      Temp1           VAR Temperatures[0]
      Temp2           VAR Temperatures[1]
      Temp3           VAR Temperatures[2]
      Temp4           VAR Temperatures[3]
    with bytes for time

    Code:
    	TimeH var byte     
    	TimeM var Byte
    Last edited by malc-c; - 10th September 2010 at 16:55.

  4. #4
    malc-c's Avatar
    malc-c Guest


    Did you find this post helpful? Yes | No

    Default

    One alternative (assuming I can find it in the UK) is this

    http://www.jianpingusa.com/datasheet...nstruction.pdf

    Basically an SD/MMC card reader that communicates via serial


    Ouch - $50

  5. #5
    Join Date
    Nov 2003
    Location
    Wellton, U.S.A.
    Posts
    5,924


    Did you find this post helpful? Yes | No

    Default

    Have you seen this?
    Need an 18F with a fair amount of memory. 18F2550 works great with it.
    Dave
    Always wear safety glasses while programming.

  6. #6
    malc-c's Avatar
    malc-c Guest


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by mackrackit View Post
    Have you seen this?
    Need an 18F with a fair amount of memory. 18F2550 works great with it.
    Seen what Dave ....

    Currently using an 18F4580 - The current version of my code compiles to around 24K

  7. #7
    Join Date
    Nov 2003
    Location
    Wellton, U.S.A.
    Posts
    5,924


    Did you find this post helpful? Yes | No

    Default

    Dave
    Always wear safety glasses while programming.

  8. #8
    malc-c's Avatar
    malc-c Guest


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by mackrackit View Post
    LOL - yeah right !!

    Interesting and seems a simple project... the only thing is that I don't have 6 pins available, at least not without changing the package to a 44 pin package and even then I still think it would be tight or short of a pin.... not to mention the re-design of the PCB

    Thanks for the link though...

    I've opted to do the logging in the PC application, for now

  9. #9
    Join Date
    Mar 2003
    Location
    Commerce Michigan USA
    Posts
    1,166


    Did you find this post helpful? Yes | No

    Default

    malc-c , Why on earth would you need 6 pins for external eeprom storage? I currently use 4, 24LC1025's to store data for a little over a month @ 1 minute intervals. The data is stored for approx. 750 minutes a day during daylight. The data stored is 16 bits per variable of: pointer,azminuth,elevation,up,down,east west and status words. The amount of data you are trying to store isn't much. besides, I only use 2 pins for the 4, 24lc1025's giving me a little over 4 Migabits...

    Dave Purola,
    N8NTA

  10. #10
    Join Date
    Nov 2003
    Location
    Wellton, U.S.A.
    Posts
    5,924


    Did you find this post helpful? Yes | No

    Default

    Six pins for an SD card.
    Dave
    Always wear safety glasses while programming.

  11. #11


    Did you find this post helpful? Yes | No

    Default 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

  12. #12
    malc-c's Avatar
    malc-c Guest


    Did you find this post helpful? Yes | No

    Default

    Brian, thanks for the input.

    As Dave has already mentioned, the 6 pins were for the SSD card shown in his link.

    I gather that using I2C type memory chips I could use the same CLK and DTA lines that hook up to the DS1307 RTC chip, and just give the memory chip a different address, so that would save me a couple of pins?

    Given that all I really want to store is date, time, temp1, temp2, temp3, temp4 probably every two minutes what would be the ideal memory chip to get to hold a minimum of 7 days worth of data (if longer so much the better). I was also thinking of a rolling data process, so that when full it would simply delete the oldest data to make space for the most current set, ie so it retails the past 7 days (or what every it amount to) worth. Any suggestions of code to do this would be welcome.

  13. #13
    Join Date
    Aug 2004
    Posts
    64


    Did you find this post helpful? Yes | No

    Default read M25P128 ?

    Brian:
    Do you can share the read routines for the M25P128 ?. I am using the M25P16 but my reading
    is a little erratic.
    Thanks in advance...
    Ruben de la Pena V.

  14. #14


    Did you find this post helpful? Yes | No

    Default 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

  15. #15
    Join Date
    Aug 2004
    Posts
    64


    Did you find this post helpful? Yes | No

    Default reading m25p16

    Brian:
    Thanks for your fast response...
    I am reading wav files stored in the M25P, and using this to send the address:
    cs1 = 0 'SEND COMMAND AND ADDRESS
    SHIFTOUT MOSI,SCK,1,[$03\8] 'read command $03
    SHIFTOUT MOSI,SCK,1 ,[PAGE.BYTE1\8,PAGE.BYTE0\8,00\7]'addr 000000
    I send the command and then the 24 bits address,but note in the last address byte I send
    only 7 bytes. then I go to a loop to read the data and send it to the port to convert to
    analog with a R2R network,until I find a special end of file char to stop the reading.
    If I send the 8 bits, I get shifted data. With 7 bits I got the correct data and I can identify
    the end of file byte. I do not know why.
    the read routine is this:
    ASM
    MOVLW 8
    MOVWF _CNT
    SIGUE
    BTFSS _MISO ;MOV BIT TO CHR,0
    BCF _CHR,0
    BTFSC _MISO
    BSF _CHR,0
    BSF _SCK ;READ AFTER SENDING THE CLOCK
    RLF _CHR,1
    BCF _SCK
    NOP
    NOP
    NOP
    NOP
    NOP
    DECFSZ _CNT,1
    GOTO SIGUE
    ENDASM

    Am I missing some previous command to set up the chip for reading..?

    I will test your routines to see if I got an improvement.
    Thanks again...
    Ruben de la Pena V.

  16. #16
    Join Date
    Aug 2004
    Posts
    64


    Did you find this post helpful? Yes | No

    Smile it works !...

    Brian:
    I only use the read routines for a little wav player. I use a 16F1826 at 16 mhz.(Internal Osc).
    The working routines:
    '************************************************* *****
    TESTREAD:
    CS1 = 1
    PAUSEUS 200
    CS1= 0
    code = 03 'read command
    gosub sendbyte
    code = 0 'higher add.
    gosub sendbyte
    code = 00 'high add.
    gosub sendbyte
    code = 0 'low add.
    gosub sendbyte
    nextread:
    GOSUB READBYTE
    SEROUT2 LED,32,[HEX2 REPLY," "]
    'PORTB = REPLY
    PAUSEUS 50
    GOTO nextread

    sendbyte:
    sclk = 0
    sclk = 0 : memd = code.7 : sclk = 1
    sclk = 0 : memd = code.6 : sclk = 1
    sclk = 0 : memd = code.5 : sclk = 1
    sclk = 0 : memd = code.4 : sclk = 1
    sclk = 0 : memd = code.3 : sclk = 1
    sclk = 0 : memd = code.2 : sclk = 1
    sclk = 0 : memd = code.1 : sclk = 1
    sclk = 0 : memd = code.0 : sclk = 1
    return
    Readbyte:
    sclk = 0 'data change point
    sclk = 1 : reply.7 = memq : sclk = 0
    sclk = 1 : reply.6 = memq : sclk = 0
    sclk = 1 : reply.5 = memq : sclk = 0
    sclk = 1 : reply.4 = memq : sclk = 0
    sclk = 1 : reply.3 = memq : sclk = 0
    sclk = 1 : reply.2 = memq : sclk = 0
    sclk = 1 : reply.1 = memq : sclk = 0
    sclk = 1 : reply.0 = memq : sclk = 0
    return
    '*********************************************
    I conected the M25P in port A and send the data to the PortB.
    It works up to 48 Mhz(audio), but I am using it at 16 KHZ.
    The M25P does not need anything aditional to work...
    Greetings and thanks again...
    Ruben de la Pena V.

Members who have read this thread : 1

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts