Shop OBEX P1 Docs P2 Docs Learn Events
Need help saving variables to EEPROM so they come back after resetting Prop — Parallax Forums

Need help saving variables to EEPROM so they come back after resetting Prop

brianm734brianm734 Posts: 29
edited 2012-08-06 05:22 in Propeller 1
Hello,
I have a little program I put together from a couple of OBEX objects I found. It reads a rotary quadrature encoder and presents the binary count on some pins. When I press a button, the count value is saved to EEPROM so the Prop can be reset or power cycled and the value will come back. This code works fine.

QuadDecodeWithMemory.spin

But now I need three encoders- So I tried using Jeff Martin's wonderful "Quadrature Encoder" object at: http://obex.parallax.com/objects/24/

Now I can read as many encoders as I need to, but this object does not seem to let me give it a starting position value, and it re-zeros the position values every time it starts up. I don't know enough about PASM to be able to modify the code.

Any help would be appreciated.

Comments

  • kwinnkwinn Posts: 8,697
    edited 2012-08-05 10:52
    I have not had time to thoroughly analyze the code but it looks like the " longfill(Pos, 0, TotEnc+TotDelta) ' Sets encoder position and delta position to 0" line clears the data to 0. If you comment out that line and put your saved data back to PosAddr before starting the encoder object it should start with the saved position.
    PUB Start(StartPin, NumEnc, NumDelta, PosAddr): Pass
    ''Record configuration, clear all encoder positions and launch a continuous encoder-reading cog.
    ''PARAMETERS: StartPin = (0..63) 1st pin of encoder 1.  2nd pin of encoder 1 is StartPin+1.
    ''                       Additional pins for other encoders are contiguous starting with StartPin+2 but MUST NOT cross port boundry (31).
    ''            NumEnc   = Number of encoders (1..16) to monitor.
    ''            NumDelta = Number of encoders (0..16) needing delta value support (can be less than NumEnc).
    ''            PosAddr  = Address of a buffer of longs where each encoder's position (and delta position, if any) is to be stored.
    ''RETURNS:    True if successful, False otherwise.
    
      Pin := StartPin                                                                                     
      TotEnc := NumEnc                                                                                    
      TotDelta := NumDelta
      Pos := PosAddr
      Stop
      longfill(Pos, 0, TotEnc+TotDelta) ' Sets encoder position and delta position to 0
      Pass := (Cog := cognew(@Update, Pos) + 1) > 0
    
  • brianm734brianm734 Posts: 29
    edited 2012-08-05 11:11
    kwinn wrote: »
    If you comment out that line and put your saved data back to PosAddr before starting the encoder object it should start with the saved position.

    That was the first thing I tried, because it looked like it was filling those long variables with zeros, but it did not work. It looks like the code down in the PASM area sets the values to zero again.
  • kwinnkwinn Posts: 8,697
    edited 2012-08-05 11:58
    Yes, it does look like the PASM code initializes the variables to 0. Modifying and testing that code to do what you want would take more time than I have right now.

    Have you considered storing the absolute position as a variable in your code and adding the delta (relative position value since last time read) to that ? Unless I misunderstand what you are trying to do this should accomplish the same thing modifying the code would do.
  • brianm734brianm734 Posts: 29
    edited 2012-08-05 12:06
    kwinn wrote: »
    Have you considered storing the absolute position as a variable in your code and adding the delta (relative position value since last time read) to that ? .

    That's a good idea. I will try that. Thanks.
  • Jeff MartinJeff Martin Posts: 760
    edited 2012-08-05 14:53
    Hi brianm734,

    From what you described and what was said in this thread, I thought for sure I had accidentally cleared it in two places. I just reviewed the code and it turns out I clear the Spin memory (Main RAM) and then clear the internal memory (Cog RAM) buffer to "match." The Update routine (PASM) is designed to maintain an internal buffer where every absolute value is kept (for speed reasons) and then, once every sample, the buffer's contents are written out to main RAM.

    So the problem you were having was because, 1) the Spin buffer is being cleared, 2) the PASM buffer is being cleared as a separate operation, and 3) the Spin buffer's values are never read into the Cog RAM buffer.

    The solution just suggested (keeping absolute separate and adding deltas will certainly work, but if you want to fix it the original way you were trying:

    1) Either comment out or remove the line in Start that looks like this:
    longfill(Pos, 0, TotEnc+TotDelta)
    

    2) Then change the assembly code near the start of Update from this:
    mov     IPosAddr, #IntPos               'Clear all internal encoder position values
                            movd    :IClear, IPosAddr               '  set starting internal pointer
                            mov     Idx, TotEnc                     '  for all encoders...  
            :IClear         mov     0, #0                           '  clear internal memory
                            add     IPosAddr, #1                    '  increment pointer
                            movd    :IClear, IPosAddr               
                            djnz    Idx, #:IClear                   '  loop for each encoder
    

    to this:
    mov     IPosAddr, #IntPos               'Initialize all internal encoder position values
                            movd    :IInit, IPosAddr                '  set starting internal pointer
                            mov     MPosAddr, PAR                   '  set starting external pointer                           
                            mov     Idx, TotEnc                     '  for all encoders...  
            :IInit          rdlong  0, MPosAddr                     '    Read initial position from main memory
                            add     MPosAddr, #4                    '      increment external pointer                                            
                            add     IPosAddr, #1                    '      increment internal pointer
                            movd    :IInit, IPosAddr               
                            djnz    Idx, #:IInit                    '      loop for each encoder
    

    I haven't had a chance to test this code, but I think it will work. :)

    Here's the version I just hacked together...

    Quadrature Encoder (not cleared).spin
  • brianm734brianm734 Posts: 29
    edited 2012-08-05 16:19
    Yes, that works great Jeff. Thank you.
  • Jeff MartinJeff Martin Posts: 760
    edited 2012-08-06 05:22
    You're welcome, Brian!
Sign In or Register to comment.