Shop OBEX P1 Docs P2 Docs Learn Events
Eerpm write going wrong — Parallax Forums

Eerpm write going wrong

Igor_RastIgor_Rast Posts: 357
edited 2012-03-03 08:07 in Propeller 1
Can anyone tell me wht this code after a power up the program locks up
I want to save the tempmin to the eeprom so with power out next power on the data is still there

What Am I overlooking ??
PUB getTemperature 
  ow.reset                                              ' send convert temperature command
  ow.writeByte(SKIP_ROM)
  ow.writeByte(CONVERT_T)
                               
                                 
  repeat                                                ' wait for conversion
    waitcnt(cnt+clkfreq/1000*25)
    if ow.readBits(1)
      quit

  ow.reset                                              ' read DS1822 scratchpad
  ow.writeByte(SKIP_ROM)
  ow.writeByte(READ_SCRATCHPAD)
                                                        ' read temperature
  temp := F.FDiv(F.FFloat(ow.readByte + ow.readByte << 8), 16.0) ' convert to floating point

  temp1:=f.FRound(f.fmul(temp,10.0))               {integer valvue of temp}
  
  if tempmin == 0
     rom.readLong($4000)
       if tempmin == 0
         tempmin:=temp1
           
                 
  if temp1 > tempmax
    tempmax := temp1
    
           
  if temp1 < tempmin
    tempmin := temp1   
    rom.writeLong($4000,temp1)

Comments

  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2012-03-02 18:53
    Which object are you using for "rom", how big is your EEPROM, and from where did you obtain the $4000 address? It would probably b e best to attach an archive of your entire program.

    -Phil
  • T ChapT Chap Posts: 4,223
    edited 2012-03-02 19:47
    Regardless the eeprom size, if there is only ONE eeprom and rom.writelong is affecting it, the eeprom location $4000 is not ideal to be using for a storage location. However on first programming the eeprom, it should run unless there is another problem. Stack size is often a crash culprit.

    When you say it crashes on power up, is that AFTER the eeprom has already been programmed.... and the eeprom has had a value stored in $4000... and THEN you reboot?
  • Duane DegnDuane Degn Posts: 10,588
    edited 2012-03-02 22:19
    To go along with what Phil and T Chap are asking, what size is your EEPROM?

    I frequently see (and use) the locations starting at $8000 for storing data to an EEPROM since $8000 is the start of the upper half of a 64K EEPROM chip.

    There's a link in post #3 of my index to a program that will determine if your EEPROM is 32K of 64K (in case you're not sure of its size).
  • Igor_RastIgor_Rast Posts: 357
    edited 2012-03-03 03:51
    ok , im using a 256 kb eeprom from microchip technologies. and like T chap said the program crashes after the on power up after the eeprom already has been programed, and the first program does runn .

    datasheet
    http://ww1.microchip.com/downloads/en/DeviceDoc/21203R.pdf

    schematic
    ssss.jpg


    about the $8000 location , this value I found around in some post , I don't realy understand the ram locations completly . so that is probably the problem
    wich value is good to store I don't know
    wanting to store 3 long values to be safe after power op.

    hope I get the good advise
    CON
    
       _clkmode = xtal1 + pll16x
       _xinfreq = 5_000_000
    
      buton1 =9                    {input buttons }
      buton2 =10                    {input buttons }
      buton3 =11                    {input buttons }
      buton4 =12                     {input buttons }
      
      RS = 0                         {lcd control}
      RW = 1                         {lcd control}
      E  = 2                         {lcd control}
      DBLow  = 3                      {lcd control}
      DBHigh = 6                      {lcd control}
    
      CR  = 13
      LF  = 10
      PSTClearScreen = 16
    
      tempsensor = 14
    
    
      SKIP_ROM          = $CC                               ' 1-wire commands
      READ_SCRATCHPAD   = $BE
      CONVERT_T         = $44
    
      CLS               = $00                               ' clear screen
      HOME              = $01                               ' home
                                   ' carriage return
      DEG               = $B0                               ' degree symbol
       #8, BKSP, TAB
    VAR
    
    long stack1[128]        ,idx,tc 
    long temp,temp1,tempmax,tempmin,ph,delta_ph ,kk ,gg
    byte messageBuffer[50]
    
    byte  nstr[64] ,h_menu
    OBJ
    
     
      ow            : "OneWire"
      fp             : "FloatString"
      f             : "FloatMath"   
      LCD : "LCD_20x4"
    
        rom: "I2C_ROMEngine.spin"
    

    PUB main
    
    dira[pomp1]~~
    dira[pomp2]~~
    
    dira[buton1]~                                                         {make button input}
    dira[buton2]~                                                         {make button input}
    dira[buton3]~                                                         {make button input}
    dira[buton4]~
    
    cognew(Monitor,@stack1)
    
    LCD.Init( E, RS, RW, DBHigh, DBLow )                            {LCD init}
    LCD.usDelay( 5_000 )                                            {LCD init}
    LCD.Clear
    
    
      h_menu:=  1                                           {Set LCD to home menu}
        
      repeat
         if ina[buton2]==0                           { down scroll button}
            h_menu:= h_menu + 1
            
            if h_menu == 4                            {menu size = 3}
              h_menu := 1
            waitcnt (clkfreq + cnt)
                                                 
         
    
        if ina[buton3]==0  and h_menu == 1                                  {enter submenu2 }
            waitcnt (clkfreq / 2+ cnt)
            tempmax:=temp1
             
        if ina[buton3]==0  and h_menu == 2                                  {enter submenu2 }
            waitcnt (clkfreq / 2+ cnt)
            tempmin:=temp1
    
    
    
        LCD.RawSetPos( $00 )                            {set lcd position}  
        LCD.PrintStr( String("Temperture"))
        LCD.RawSetPos( $0B )                               {set lcd position}
        LCD.PrintStr(fp.FloatToFormat(temp, 4, 1))         {float to sting}
        LCD.PrintStr( string(" C" ))
    
        LCD.RawSetPos( $40 )                            {set lcd position}  
        LCD.PrintStr( String("maximaal"))
        LCD.RawSetPos( $4B )                               {set lcd position}
        LCD.PrintStr(decx(tempmax,3))         {float to sting}
        LCD.PrintStr( string(" C" ))
    
        LCD.RawSetPos( $14 )                            {set lcd position}  
        LCD.PrintStr( String("Minimaal"))
        LCD.RawSetPos( $1f )                               {set lcd position}
        LCD.PrintStr(decx(tempmin,3))         {float to sting}
        LCD.PrintStr( string(" C" ))
    
       case h_menu      
             
             1:
                LCD.RawSetPos( $55 )
                LCD.PrintStr( string("Max" ))
    
             2:
                LCD.RawSetPos( $55 )
                LCD.PrintStr( string("Min" ))
    
             3:
                LCD.RawSetPos( $55 )
                LCD.PrintStr( string("Set" ))
                   
    
      waitcnt(clkfreq + cnt)
    

    PUB Monitor    
      rom.ROMEngineStart(29,28, -1)
      ow.start(tempsensor)                                            {temp sensor start}
      waitcnt(clkfreq / 4 + cnt)                                      {Ph sensor start}
     repeat
        getTemperature                                                 { Get Temp Reading}
                              
       waitcnt(clkfreq    + cnt)
                          
    PUB getTemperature 
      ow.reset                                              ' send convert temperature command
      ow.writeByte(SKIP_ROM)
      ow.writeByte(CONVERT_T)
                                   
                                     
      repeat                                                ' wait for conversion
        waitcnt(cnt+clkfreq/1000*25)
        if ow.readBits(1)
          quit
    
      ow.reset                                              ' read DS1822 scratchpad
      ow.writeByte(SKIP_ROM)
      ow.writeByte(READ_SCRATCHPAD)
                                                            ' read temperature
      temp := F.FDiv(F.FFloat(ow.readByte + ow.readByte << 8), 16.0) ' convert to floating point
    
      temp1:=f.FRound(f.fmul(temp,10.0))               {integer valvue of temp}
      
      
           if tempmin == 0
             tempmin:=temp1
               
                     
      if temp1 > tempmax
        tempmax := temp1
        
               
      if temp1 < tempmin
        tempmin := temp1   
       
    
        
    DAT                            
    endCmd        byte "E", 13, 0
    readCmd       byte "r", 13, 0
    continuousCmd byte "C", 13, 0
    tt            byte  "2","5",".","5",13,0
    temp2         byte
    
    PUB decx(value, digits) | div
    
    '' Returns pointer to zero-padded, signed-decimal string
    '' -- if value is negative, field width is digits+1
    
      clrstr(@nstr, 64)  
      digits := 1 #> digits <# 10
    
      if (value < 0)                                        ' negative value?   
        -value                                              '   yes, make positive
        nstr[idx++] := "-"                                  '   and print sign indicator
    
      div := 1_000_000_000                                  ' initialize divisor
      if digits < 10                                        ' less than 10 digits?
        repeat (10 - digits)                                '   yes, adjust divisor
          div /= 10
      
      value //= (div * 10)                                  ' truncate unused digits
      
      repeat digits
        nstr[idx++] := (value / div + "0")                  ' convert digit to ASCII
        value //= div                                       ' update value
        div /= 10                                           ' update divisor
    
      return @nstr
    PRI clrstr(strAddr, size)
    
    ' Clears string at strAddr
    ' -- also resets global character pointer (idx)
    
      bytefill(strAddr, 0, size)                            ' clear string to zeros
      idx~                                                  ' reset index
    

    esentialy what this code needs to do is :p

    1 read the temp value and display it on lcd ( working complete )

    2 remember what value was the highs temp value and store it to tempmax ( must be saved to eeprom not to get lost on powerup, max value doing what is needs to remember , only not at power out)

    3 remember what value was the lowest temp value and store it to tempmin ( must be saved to eeprom not to get lost on powerup ,min value doing what is needs to remember , only not at power out))

    4 set an offset value ( must be saved to eeprom not to get lost on powerup)

    hope I make myself clear
    1024 x 820 - 178K
    ssss.jpg 178.3K
  • T ChapT Chap Posts: 4,223
    edited 2012-03-03 06:10
    Using the Propeller Tool, Press F8, then if not already showing the HEX info, press SHOW HEX. Scroll down and you can see where there are values other than 0 which are used in the Eeprom. Go to the blue section, and you can use any address there in blue. For example, the last row is a good place to write, which starts at $7FF0 and that row runs all the way to $7FFF. So you can use $7FF0 if you want. Keep in mind every time you program the Propeller(the eeprom), the values you have written will be gone until your program puts the temp back again.
  • Igor_RastIgor_Rast Posts: 357
    edited 2012-03-03 06:34
    ok so I understand the memory map

    but what's wrong with my code, because it still doesn't remember the value at powerup
    PUB getTemperature 
      ow.reset                                              ' send convert temperature command
      ow.writeByte(SKIP_ROM)
      ow.writeByte(CONVERT_T)
                                    
                                     
      repeat                                                ' wait for conversion
        waitcnt(cnt+clkfreq/1000*25)
        if ow.readBits(1)
          quit
    
      ow.reset                                              ' read DS1822 scratchpad
      ow.writeByte(SKIP_ROM)
      ow.writeByte(READ_SCRATCHPAD)
                                                            ' read temperature
      temp := F.FDiv(F.FFloat(ow.readByte + ow.readByte << 8), 16.0) ' convert to floating point
    
      temp1:=f.FRound(f.fmul(temp,10.0))               {integer valvue of temp}
      
        if tempmin == 0
           rom.readLong($7FF0)
           if tempmin == 0
             tempmin:=temp1
                     
      if temp1 > tempmax
        tempmax := temp1
        
               
      if temp1 < tempmin
         tempmin := temp1   
         rom.writeLong($7FF0,temp1)
         temp1:=f.FRound(f.fmul(temp,10.0))
    

    so the rom.readLong($7FF0)

    and the rom.writeLong($7FF0,temp1) folowed by a temp1:=f.FRound(f.fmul(temp,10.0)) to restore the value in temp1 because what you sugested it gets lost

    it's getting me crazy :p
  • T ChapT Chap Posts: 4,223
    edited 2012-03-03 06:51
    Gets lost? What is the value that is coming back?

    For a test, forget about your full code. Write a test method that writes a value ie 7 to the location, then read the location and show the result that is currently in the eeprom address.


    Also, it is a good practice to not have code hard left, only the PUB, VAR, OBJ, designators. DAT is ok to have declarations hard left
  • Duane DegnDuane Degn Posts: 10,588
    edited 2012-03-03 07:23
    Igor_Rast wrote: »
    it's getting me crazy

    Take a look at the PEK sticky at the top of the Propeller forum. There's an EEPROM data logging lab that shows you how to same variables to EEPROM. A very common way to do this is to just use the same EEPROM address as the variables' RAM location.

    I think you're making this harder than it needs to be.
  • T ChapT Chap Posts: 4,223
    edited 2012-03-03 07:42
    I am not familiar with the i2cromengine. I use MinimalI2Cdriver and the following example to read/write eeprom.
    PUB WriteTempLow
        WritePage(eeprom1, $F100, @TempLow, 4)    '  1 =byte. 2=2word, 4=long
    
    PUB ReadTempLow
        ReadPage(EEPROM1, $F100, @TempLow, 4)
    
    PUB WritePage(devid, address, pointer, count)
        i2c1.i2cWritepage(28, devid, address, pointer, count)
        waitcnt(clkfreq/200 + cnt)
        i2c1.i2cstop(28)
    
    PUB ReadPage(devid, address, pointer, count)           'boot eeprom $A0
        i2c1.i2cstart(28)
        i2c1.i2cReadPage(28, devid, address, pointer, count)    '$7000test
        i2c1.i2cstop(28)
        return  pointer
    

    Not sure in the case of your i2c object, but in my example it is required to pass the address of the variable with@, not just using the var itself.
  • Igor_RastIgor_Rast Posts: 357
    edited 2012-03-03 08:07
    Thanks for the advice guy's

    I Got it working , thnx
Sign In or Register to comment.