Shop OBEX P1 Docs P2 Docs Learn Events
How do can we deconstruct/reconstruct variables as a series of other variables? [solved] — Parallax Forums

How do can we deconstruct/reconstruct variables as a series of other variables? [solved]

Robert GrahamRobert Graham Posts: 55
edited 2018-05-06 10:15 in Propeller 1
I know this a very boring code question, but I need to sample the binary version of some variables, and store those bits in separate variables to later be reconstructed into an integer.

For example: Say I am storing the integer 25 in a variable, which would be 00011001 in 8-bit binary. (I don't know exactly what format Propeller chips store the values of variable as, so I am using 8-bit as an example) I want to sample each bit, and store them in separate variables. So, here, I would be converting the original variable (equal to 25 in this example) into an eight variable array: Var[0..2] := 0, Var[3..4] := 1, Var[5..6] := 0, and Var[7] := 1. Like I said, I want to deconstruct the original variable's value, and store it as a series of binary values in a series of other variables. A different process will reconstruct this series of binary values back into a binary representation of an integer, which will be stored in separate variable.

Is there a Spin language command that will allow me to sample every bit in a looped command, one right after another? That would be hella sweet. If I need to heavily process the original variable, so be it. Obviously, the latter scenario would be less desirable, but life doesn't always go the way we would like.

I really don't want to have to use a zillion operators just to so something that any fool's eye could do. After all, basically, in the example, all the code needs to do is remember the we have got three zeros in a row, followed by two ones, and then two more zeros, and a one. Very simple concept. They human brain is so good at it, but did anyone build that feature into the Spin language?

And then the reconstruction would be the reverse. Simple concept again, but is there an easy way to do it in Spin?

I am deliberately leaving out what the device is for. This is because, I don't want to use some one else's object that I don't understand. Someday, the device might outgrow the capabilities of the Propeller, and, on that sad day, I will need to migrate to more powerful hardware. I have already used about half of the memory on one of the P1's I am using, and there are lots more features that I want to add. If I write the code, I can keep it as compact as possible. And I can easily rewrite it in another language on that sad day when I have to say goodby to the Prop chip (and Spin language).

I have a viable (and more compact) alternative to deconstructing/reconstructing integers in their binary form, but it will execute a certain process more slowly.

So, help would be appreciated! I was assuming there would be a tutorial on this sort of thing, but I can't find it anywhere!

Comments

  • evanhevanh Posts: 15,187
    edited 2016-04-05 21:26
    Convert to a string, might be what you want. I'm not experienced on Spin so will leave examples for others.
  • Why not just manipulate the bits directly, in place?

    Determining if a bit is on looks like this:

    if( (value & (1<<bit)) > 0 )

    Forcing a bit to on is just

    value |= (1<<bit)

    and forcing a bit to off is

    value &= ~(1<<bit)

    Pulling them into separate memory is going to bloat the storage for a variable by at least 8x (using bytes to store bits).

    If you want to jumble the bits, or do something non-trivial with them, it's relatively simple to use a second variable and just copy the bits from the original into the copy, writing them into their new order, then just copy the new value back over the first one.
  • AribaAriba Posts: 2,682
    There is a trick in Spin to access the bits of a long as an indexed array. You can do it for the special function registers like OUTA, DIRA... but nor for normal variables.
    The Prop1 has such special registers for PortB which is not physically implemented, but the registers are there. So you can copy the value to DIRB for example and access the bits with DIRB[0], DIRB[1] and so on. Even bitfields are accessible: DIRB[7..4].

    If you want the bits in a bytearray you can copy them with something like that:
    VAR
      long  theInteger
      byte  array[8]
    
    PUB ... | i
      theInteger := 25
      DIRB := theInteger
      repeat i from 0 to 7
        array[i] := DIRB[i]
      ...
    

    Andy
  • @Ariba this DIRB trick is absolutely great.

    Belongs into the manual. So obvious and I never was able to see it. Nice.

    Thank you!

    Mike
  • Thank you Ariba! I do appreciate the help.
    So, this is to encode/deconstruct:
    VAR
      long  theInteger
      byte  array[8]
    
    PUB ... | i
      theInteger := 25
      DIRB := theInteger
      repeat i from 0 to 7
        array[i] := DIRB[i]
      ...
    

    And I am assuming this would turn the indexed array back into an integer:
    VAR
      long  theInteger
      byte  array[8]   'This array will be defined by code that is not shown here.
    
    PUB ... | i
      repeat i from 0 to 7
        DIRB[i] := array[i]
      theInteger := DIRB
    ...
    

    There is no need to use different variable names, as the decode/reconstruct method will be running on a separate P1 chip. So, yes, I am looking for the syntax to upgrade my pet com protocol. I left that detail out, because I didn't want some well meaning person to tell me to just use FullDuplexSerial!

    Don't worry about the code to send/receive bits. It wrote that years ago. So, in the second example, array[8] is already loaded up with binary goodness.

    If I can get his right, I will have an very compact mux/demux pair that can send bytes! Bits are nice to send, and I think my existing com protocol is very nice for what it does (I can show it if anyone is interested), but I need to add the ability to send bytes from the control unit to the slave device.

    Again, thanks for the help Ariba! I will rig up a test, and see what it all does. If anyone else has anything to add to this new code idea, I am all eyes!
  • evanhevanh Posts: 15,187
    Reminds me of Modbus.
  • ElectrodudeElectrodude Posts: 1,621
    edited 2016-04-06 19:24
    VAR
      long  theInteger
      byte  array[8]   'This array will be defined by code that is not shown here.
    
    PUB ... | i
      repeat i from 0 to 7
        DIRB[i] := array[i]
      theInteger := DIRB
    ...
    

    You should make sure the top 3 bytes of DIRB don't interfere with the final value of theInteger. If you're sure they never get set to anything and that they always stay cleared, you'll be fine, but just to be safe you should probably add "DIRB~" above the loop to clear all of DIRB first, or you could change the declaration of theInteger to say "byte theInteger" so that the top three bytes of DIRB don't matter..
  • I will try that!

    Might be next week before I can get time to rig up an experiment. I can't wait! This will allow so many more features for my device : D
  • Ok, two years later I finally got back to trying DIRB for encoding bytes from bit.

    It does work :)

    Because DIRB is a 32 bit register, it can be used to make an entire long from binary data.

    I am going to be encoding four bytes with DIRB, for storage and transfer. This is going to save me A LOT of storage space and bandwidth.

    Each of those 32 bits represented a a single button press. I was having to store them separately, and this was inefficient.



  • JonnyMacJonnyMac Posts: 8,924
    edited 2018-05-02 16:58
    Since you don't know what's in the other 24-bits of DIRB, you should do one of two things:
    PUB ... | i
      DIRB := 0
      repeat i from 0 to 7
        DIRB[i] := array[i]
      theInteger := DIRB
    
    or...
    PUB ... | i
      repeat i from 0 to 7
        DIRB[i] := array[i]
      theInteger := DIRB & $FF
    

  • JonnyMac wrote:
    Since you don't know what's in the other 24-bits of DIRB, you should do one of two things:
    Aren't all the SFRs cleared to zero when a cog is instantiated?

    -Phil
  • Aren't all the SFRs cleared to zero when a cog is instantiated?
    Yes, but he seems to be indicating a general-purpose method -- who knows what he'll do with that register in between. Perhaps I'm being overly verbose, but I'm a "no surprises" kind of guy.
  • Robert GrahamRobert Graham Posts: 55
    edited 2018-05-04 07:31
    DIRB := 0 takes care of any unfortunate possibilities that one might encounter. Not that I am assuming that it would not start out as 32 zero's, but I really don't know, do I? Freshly declared variables don't have any value.

Sign In or Register to comment.