Shop OBEX P1 Docs P2 Docs Learn Events
Split 12 bit number into two separate bytes for data transmission - then put them back together — Parallax Forums

Split 12 bit number into two separate bytes for data transmission - then put them back together

Hello,
I have a 12 bit number (0 to 4095) that I need to transmit through RF. The RF module I am using (nRF24L01) transmits data on a per byte.

I was wondering if there was an elegant way to convert a 12 bit number into two separate bytes, load them into the payload byte array, then transmit?

Then on the other side I receive this array of bytes, and I re-assemble these 2 bytes back into the original 12 bit number?

Thanks and any help/advice is greatly appreciated!

EDIT:
I am imagining I would have 2 variables:
VAR
    Byte part1
    Byte part2

The original number is currently being stored in a long... I suppose it could also be stored in a word.
So it seems I need to shift the long over 16 times, and collect these bits and store them in part1. Then the remainder would be part2. Is this correct?

Comments

  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2015-12-21 21:54
    If your long variable is named data, the least significant byte can be accessed as byte[@data], and the remaining 4 bits as byte[@data + 1].

    -Phil
  • JonnyMacJonnyMac Posts: 9,105
    edited 2015-12-21 22:07
    I do this quite frequently. On a recent project I had to send two 16-values via XBee to a remote. At the core is:
      xbee.tx(value1.byte[0])
      xbee.tx(value1.byte[1])
      xbee.tx(value2.byte[0])
      xbee.tx(value2.byte[1])
    
    And on the other side:
      value1 := xbee.rx
      value1.byte[1] := xbee.rx
      value2 := xbee.rx
      value2.byte[1] := xbee.rx
    
    If the values you're sending could be negative and still fit into 16 bits, you can do this on the receiving end (if your receiving values are longs [should be for signed values]):
      ~~value1
      ~~value2
    
  • jmgjmg Posts: 15,173
    edited 2015-12-21 23:22
    Mahonroy wrote: »
    I was wondering if there was an elegant way to convert a 12 bit number into two separate bytes, load them into the payload byte array, then transmit?

    This is basic shifting & masking, but you may want to think about how to spread those two halves.

    8bits in one byte plus 4 in the next is simple, but that gives no protection against reverse order from dropped bytes in Txmit, so you may want to pack as 6 data bits per byte, and use one of the 2 spare bits to signal HI/LO halves.
    That leaves one more bit as a user flag :
    eg Bytes as
    [00_Data6] = Low 6b
    [01_Data6] = High 6b
    [1_Data7] = Spare user 7b

  • JonnyMac wrote: »
    I do this quite frequently. On a recent project I had to send two 16-values via XBee to a remote. At the core is:
      xbee.tx(value1.byte[0])
      xbee.tx(value1.byte[1])
      xbee.tx(value2.byte[0])
      xbee.tx(value2.byte[1])
    
    And on the other side:
      value1 := xbee.rx
      value1.byte[1] := xbee.rx
      value2 := xbee.rx
      value2.byte[1] := xbee.rx
    
    If the values you're sending could be negative and still fit into 16 bits, you can do this on the receiving end (if your receiving values are longs [should be for signed values]):
      ~~value1
      ~~value2
    

    Thanks a lot for these snippets this was exactly what I was looking for! I did not realize the syntax existed for the ".byte[x]" thats pretty useful!
  • This is a preliminary test I did to pass a 24 bit value. It worked but It was inefficient because CSN went high and low for each byte offset that I transmitted. I thought it was too slow for what I wanted.
    CON
      _clkmode = xtal1 + pll16x                           
      _xinfreq = 5_000_000   
      
    OBJ   
      Debug  : "FullDuplexSerialPlus"   
    
    PUB largeByteValue  | offset_var, value_holder, idx
    
      Debug.start(31, 30, 0, 57600)
      waitcnt(clkfreq * 2 + cnt)     
    
      value_holder := 180000
    
      repeat idx from 0 to 3
        byte[@offset_var][idx]  += byte[@value_holder][idx] 
        debug.dec(offset_var)
        Debug.tx(13)
        debug.bin(offset_var, 32)
        Debug.tx(13)
        waitcnt(clkfreq+cnt)
    

    If you're curious I'll zip my PTX and PRX for you to try. I want to control motors so I decided it would be quicker to transmit an 8 bit value and scale it on the PRX side
Sign In or Register to comment.