Shop OBEX P1 Docs P2 Docs Learn Events
High Byte, Low Byte Help — Parallax Forums

High Byte, Low Byte Help

DiablodeMorteDiablodeMorte Posts: 238
edited 2008-04-10 12:33 in Propeller 1
Hello all,

I'm working on a project which requires me to send the high and low bytes of a variable seperatly over a com port. I know how to send individual bytes via the com port but I don't know how to split an individual variable into high and low bytes. Before, with the basic stamp I think you use .HIGHBYTE and .LOWBYTE but that doesn't seem to exist in Spin.

Any suggestions?

I was thinking something like

var * %1100 but I'm not that proficient with spin.

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Current Projects:
Robot Control Via Skype API - Dev Stage(50% Complete) - Total(25%)
Robot Localization Via Xbee's - Research Stage
IR Tracking with Propeller - Research Stage

Comments

  • RaymanRayman Posts: 14,813
    edited 2008-04-09 00:21
    I think you can do something like this:

    a:=Variable.Byte[noparse][[/noparse]3]

    b:=Variable.Byte[noparse][[/noparse]2]

    c:=Variable.Byte[noparse][[/noparse]1]

    d:=variable.Byte[noparse][[/noparse]0]

    Usual variables are longs, so have 4 bytes...
  • DiablodeMorteDiablodeMorte Posts: 238
    edited 2008-04-09 00:25
    Another question:
    When I have a negative variable.. what do I get?

    In the manual, if I wanted to express a -200 it tells me to put 255 as the high byte and 56 as the low byte... Why is that?

    Also, if I use the above example: Which is the high byte? Which is the low byte?

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Current Projects:
    Robot Control Via Skype API - Dev Stage(50% Complete) - Total(25%)
    Robot Localization Via Xbee's - Research Stage
    IR Tracking with Propeller - Research Stage
  • Paul BakerPaul Baker Posts: 6,351
    edited 2008-04-09 00:28
    Negative numbers are expressed in two's compliment: http://en.wikipedia.org/wiki/Two's_complement

    The Propeller is little endian so the least significant byte occupies the lower address. (see page 332 of the manual)

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Paul Baker
    Propeller Applications Engineer

    Parallax, Inc.

    Post Edited (Paul Baker (Parallax)) : 4/9/2008 12:35:11 AM GMT
  • RaymanRayman Posts: 14,813
    edited 2008-04-09 00:30
    Ok, I think this is 2's compliment binary:

    0=00000000_00000000_00000000_00000000
    and
    -1=11111111_11111111_11111111_11111111
  • hippyhippy Posts: 1,981
    edited 2008-04-09 01:51
    DiablodeMorte said...
    In the manual, if I wanted to express a -200 it tells me to put 255 as the high byte and 56 as the low byte... Why is that?

    A trick to get a negative value in two's compliment form is to invert the bits and add one. So the steps required are ...

    1) Convert to binary ( two 8-bit bytes ) 200 = 00000000 11001000
    2) Invert the bits                             11111111 00110111
    3) Add 1                                       11111111 00111000
    4) Convert each byte to decimal                255      56
    
    
    
  • DiablodeMorteDiablodeMorte Posts: 238
    edited 2008-04-09 02:19
    Ok, Thanks for the help. Here's my try:

    I have the following function:
    PUB Main
    test(-495)
    
    PUB test(var)
    'Ok, so the variable is -495... What do I do now...
    'Can I simply do this?
    Com.tx(var.Byte)
    waitcnt(10_000 + cnt) 
    Com.tx(var.Byte[noparse][[/noparse]0])
    waitcnt(10_000 + cnt) 
    'or do I need to convert via two's compliment?
    
    

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Current Projects:
    Robot Control Via Skype API - Dev Stage(50% Complete) - Total(25%)
    Robot Localization Via Xbee's - Research Stage
    IR Tracking with Propeller - Research Stage
  • hippyhippy Posts: 1,981
    edited 2008-04-09 10:04
    DiablodeMorte said...
    'Can I simply do this?
    Com.tx(var.Byte[noparse][[/noparse] 1 ])
    waitcnt(10_000 + cnt) 
    Com.tx(var.Byte[noparse][[/noparse] 0 ])
    waitcnt(10_000 + cnt) 
    'or do I need to convert via two's compliment?
    
    


    When including square brackets in the forum it's necessary to add spaces or the forum text parser treats them as formatting commands and what gets displayed isn't what's intended and can be confusing.

    Yes, you can do that. Not sure the way you're doing waitcnt() is ideal but that's not the issue.

    You don't need to worry about explicitly handling two's complementing here because where you specify "test(-495)" the compiler will have done the work for you; it will convert "-" and "495" into the required 32-bit two's complement number.
  • mparkmpark Posts: 1,305
    edited 2008-04-09 21:49
    People are spelling it "compliment" and "complement" in this thread, sometimes in the same post(!)

    Fyi, the correct spelling is "two's complement". "Compliment" means something entirely different (and nonsensical in this context).

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Michael Park

    PS, BTW, and FYI:
    To search the forum, use search.parallax.com (do not use the Search button).
    Check out the Propeller Wiki: propeller.wikispaces.com/
  • DiablodeMorteDiablodeMorte Posts: 238
    edited 2008-04-10 00:37
    I'm back everybody, and I still need alittle help. Here's my code:

    Here's what I call in my MAIN function:
    Drive(32768,10)
    



    and here's my drive function:
    PUB Drive(Velocity, Radius)
    ''Velocity is mm/s - Max = 510
    ''Radius in mm, Positive = Left, Negative = Right - Max = 510
      Com.tx(CmdDrive)
      waitcnt(10_000 + cnt)
      Com.tx(Velocity)
      waitcnt(10_000 + cnt)
      Com.tx(Velocity[noparse][[/noparse]0])
      waitcnt(10_000 + cnt)
      Com.tx(Radius)
      waitcnt(10_000 + cnt)
      Com.tx(Radius[noparse][[/noparse]0])
      waitcnt(10_000 + cnt)
      return
    
    



    and here's the excerp from the manual I'm following:
    • Serial sequence: [noparse][[/noparse]137] [noparse][[/noparse]Velocity high byte] [noparse][[/noparse]Velocity low byte]
    [noparse][[/noparse]Radius high byte] [noparse][[/noparse]Radius low byte]
    • Available in modes: Safe or Full
    • Changes mode to: No Change
    • Drive data byte 1: Velocity (-500 – 500 mm/s)
    • Drive data byte 2: Radius (-2000 – 2000 mm)
    Special cases:
    Straight = 32768 or 32767 = hex 8000 or 7FFF
    Turn in place clockwise = hex FFFF
    Turn in place counter-clockwise = hex 0001
    Example:
    To drive in reverse at a velocity of -200 mm/s while
    turning at a radius of 500mm, send the following serial
    byte sequence:
    [noparse][[/noparse]137] [noparse][[/noparse]255] [noparse][[/noparse]56]  [noparse][[/noparse]244]
    Velocity = -200 = hex FF38 = [noparse][[/noparse]hex FF] [noparse][[/noparse]hex 38] = [noparse][[/noparse]255] [noparse][[/noparse]56]
    Radius = 500 = hex 01F4 = [noparse][[/noparse]hex 01] [noparse][[/noparse]hex F4] =  [noparse][[/noparse]244]
    
    



    When I run my code the little thing doesn't do anything, any suggestions as to what I'm doing wrong?

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Current Projects:
    Robot Control Via Skype API - Dev Stage(50% Complete) - Total(25%)
    Robot Localization Via Xbee's - Research Stage
    IR Tracking with Propeller - Research Stage
  • hippyhippy Posts: 1,981
    edited 2008-04-10 01:00
    As previously said ...

    When including square brackets in the forum it's necessary to add spaces or the forum text parser treats them as formatting commands and what gets displayed isn't what's intended and can be confusing.

    What you have looks like it should be correct. Maybe the delays between each byte are introducing a problem ? You can add some debugging code to show what you're sending. You could re-direct the serial to a terminal emulator which can show binary values of bytes sent and check that you are sending what you should be, at the right baud rate, correct polarity etc.

    Added : Velocity[noparse][[/noparse] 1 ] and Velocity[noparse][[/noparse] 0 ] are not bytes, ditto for Radius[noparse][[/noparse] 1 ] and Radius[noparse][[/noparse] 0 ].
  • DiablodeMorteDiablodeMorte Posts: 238
    edited 2008-04-10 01:05
    Somebody said...

    Added : Velocity[noparse][[/noparse] 1 ] and Velocity[noparse][[/noparse] 0 ] are not bytes, ditto for Radius[noparse][[/noparse] 1 ] and Radius[noparse][[/noparse] 0 ].

    What do you mean? I am confused.. I'll try your suggestions of removing the pauses.

    EDIT: Nope, I removed the pauses and I got nothing.. Any other suggestions?

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Current Projects:
    Robot Control Via Skype API - Dev Stage(50% Complete) - Total(25%)
    Robot Localization Via Xbee's - Research Stage
    IR Tracking with Propeller - Research Stage

    Post Edited (DiablodeMorte) : 4/10/2008 1:15:37 AM GMT
  • stevenmess2004stevenmess2004 Posts: 1,102
    edited 2008-04-10 01:11
    Is the com object fullduplexserial and where is the setup routine for it?
  • DiablodeMorteDiablodeMorte Posts: 238
    edited 2008-04-10 01:15
    stevenmess2004 said...
    Is the com object fullduplexserial and where is the setup routine for it?
    Yes it is, here's the setup code:
    PUB Start(CREATE_RXPIN, CREATE_TXPIN, CREATE_CHGSEN,WAIT_FOR_CHARGE)
      ''''''''''''''''''''''''''
      ''Init
      ''''''''''''''''''''''''''
      dira[noparse][[/noparse] 16 ]~~
      Com.Start(CREATE_RXPIN,CREATE_TXPIN,%0000, 57_600)  ''RX,TX,UNKNOWN,BAUD
      outa[noparse][[/noparse] 16 ]~~
      
      ''''''''''''''''''''''''''
      ''Check to see if the create is docked/charging
      ''If it isn't, turn pin 16 on, if so, blink pin 16
      ''''''''''''''''''''''''''
      if WAIT_FOR_CHARGE == 1
        repeat while ina[noparse][[/noparse] CREATE_CHGSEN ] == 1
          !outa[noparse][[/noparse] 16 ]                                           ''Toggle Pin 16 
          waitcnt(2_500_000 + cnt)                            ''Wait 1/2 a second
      outa[noparse][[/noparse] 16 ]~~
      return
    



    Note: the code works fine, I can get the robot to sing and do demos, I just can't seem to get it to move under my control.

    EDIT: I just tried manually this code:
    Com.tx(CmdDrive)
      'waitcnt(10_000 + cnt)
      Com.tx(255)
      'waitcnt(10_000 + cnt)
      Com.tx(56)
      'waitcnt(10_000 + cnt)
      Com.tx(1)
      'waitcnt(10_000 + cnt)
      Com.tx(244)
      'waitcnt(10_000 + cnt)
    



    and it works fine. My problem must be with the high byte low byte thing. Hope that is more helpful!

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Current Projects:
    Robot Control Via Skype API - Dev Stage(50% Complete) - Total(25%)
    Robot Localization Via Xbee's - Research Stage
    IR Tracking with Propeller - Research Stage
  • hippyhippy Posts: 1,981
    edited 2008-04-10 02:18
    DiablodeMorte said...
    Somebody said...

    Added : Velocity[noparse][[/noparse] 1 ] and Velocity[noparse][[/noparse] 0 ] are not bytes, ditto for Radius[noparse][[/noparse] 1 ] and Radius[noparse][[/noparse] 0 ].

    What do you mean? I am confused.. I'll try your suggestions of removing the pauses.

    EDIT: Nope, I removed the pauses and I got nothing.. Any other suggestions?

    Apologies, that was a bit terse.

    var[noparse]/noparse is an array of long, var.byte[noparse]/noparse selects a byte of the long, so as in you earlier example where you were using the later to get at the bytes you need to do the same here ...

    PUB Drive( Velocity, Radius )
      Com.tx( CmdDrive )
      Com.tx( Velocity.byte[noparse][[/noparse] 1 ] )
      Com.tx( Velocity.byte[noparse][[/noparse] 0 ] )
      Com.tx( Radius.byte[noparse][[/noparse] 1 ]   )
      Com.tx( Radius.byte[noparse][[/noparse] 0 ]   )
      return
    
    
    
  • DiablodeMorteDiablodeMorte Posts: 238
    edited 2008-04-10 03:13
    While I will indeed try you suggestion hippy, I actually found my own solution. I'm taking from Norris56's code, this is the code he uses to do what I wanted to do:
    PUB DriveDirect(RightVelocity, LeftVelocity)

    if m_Init
    Link.tx(Cmd_DriveWheels)

    Link.tx(~~RightVelocity >> 8)
    Link.tx(RightVelocity)

    Link.tx(~~LeftVelocity >> 8)
    Link.tx(LeftVelocity[noparse][[/noparse]0])

    Anybody want to explain that to me?. I kind get the >> 8.. but not really, I'm looking up the ~~ right now but doubt i'll understand it.

    Ok, yep, I get the >> part.. Still don't really see why ~~ is needed...Answers anyone?

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Current Projects:
    Robot Control Via Skype API - Dev Stage(50% Complete) - Total(25%)
    Robot Localization Via Xbee's - Research Stage
    IR Tracking with Propeller - Research Stage

    Post Edited (DiablodeMorte) : 4/10/2008 3:19:37 AM GMT
  • hippyhippy Posts: 1,981
    edited 2008-04-10 12:33
    The "var >> N" operation is shift variable right by N bits, and each shift right is the same as divide by two, so shift right is divide by 256. To get the individual high and low bytes you can use either of the following ...

     hiByte := ( var >> 8 ) & $FF
     loByte := ( var      ) & $FF
    
     hiByte := var.byte[noparse][[/noparse] 1 ]
     loByte := var.byte[noparse][[/noparse] 0 ]
    
    
    



    The "& $FF" is important but it is not always necessary - as with calling link.tx() - if that truncates the output to 8-bit bytes.

    The ~~ is used to sign extend a 16-bit value to fill the entire 32-bits of a long variable. As the code only deals with 16-bit values it is pointless to do in this case.
Sign In or Register to comment.