Shop OBEX P1 Docs P2 Docs Learn Events
Breaking up a long into eight bytes for serial transmission — Parallax Forums

Breaking up a long into eight bytes for serial transmission

kt88seampkt88seamp Posts: 112
edited 2009-11-26 22:07 in Propeller 1
I have a number 640000, which is a qword if I am not mistaking. It is %10011100010000000000 in bianary. I want to break it up into eight bytes (in an array)·so I can transmit it over a serial connection. At the other end I wish to reassemble it into the qword. How is this done?

Comments

  • SRLMSRLM Posts: 5,045
    edited 2009-11-26 01:48
    One way would be to use a mask for the lowest eight bits and AND it, then transmit the result. Shift the number to transmit right by eight bits and repeat the masking. Do this four times and you transmit all four bytes of the long.
  • kt88seampkt88seamp Posts: 112
    edited 2009-11-26 04:24
    OK, is this for breaking up the long or reassembling it?
  • kwinnkwinn Posts: 8,697
    edited 2009-11-26 04:30
    640,000 is only 20 bits, and the binary representation would fit in 24 bits or 3 bytes. If it is stored as a long (64 bits) you could send it as 8 bytes of binary data.
  • JonnyMacJonnyMac Posts: 9,208
    edited 2009-11-26 04:38
    What SLRM describes is for breaking up and sending -- it might be coded like this:

    pub sendlong(value)
    
      repeat 4
        serial.tx(value & $FF)
        value >>= 8
    



    You might re-assemble like this:

    pub getlong
    
      result~
      
      repeat 4
        result <<= 8
        result |= serial.rx
    
  • Jim FouchJim Fouch Posts: 395
    edited 2009-11-26 14:58
    For sending more than one byte from one side and being able to understand it on the other side you need to use a message or packet system. You need something to say you are starting the packet and something to say you are ending it. Something to check that all bytes are correct is good too.

    In the example here, a used a cog to watch for bytes coming through a serial port. This was only for receiving and I didn't need to send data ack the other way, so this is pretty simple.

    I created a state machine that looks for the starting marker then each byte after that had a special meaning. The packet system I created used a simple checksum to make sure the packets were good. If not, it will just wait for the next packet. My system just needed to get the current reading·for several values. If a packet was bad, it wasn't the end of the world. However, it would·accept bad data, just skip it and wait for the next good packet.

    Not sure if this is what you're looking for, but it could be a good start to a much better system.
    Var
      Long Stack[noparse][[/noparse]45]       
      byte cog
      Long Signals,Gear,Speed,TachValue,CoolantTemp,BatteryVoltage
      word  dpin, cpin, rst, started
    Con
    
    Obj
      UART   : "FullDuplexSerial"
      delay  : "timing" 
                 
    Pub Start(GlobalPointer): Success | i
      Stop
      Success := (Cog := CogNew(Run(GlobalPointer), @Stack) + 1)
    Pub Stop
      if cog
        CogStop(Cog~ - 1)
    Pub Run(GlobalPointer)|T,State,SubState, PC ,T2, CheckSum, Pass
      'DirA[noparse][[/noparse]16..23]~~
      
      Uart.Start(25,26,%1,115200)   
      LongFill(@Signals,0,6) ' Default All Vals to ZEROS  State:=0
      State:=0
      PC:=0
       { State #    State
          0          Waiting for next Packet
          1          Confirming Packet Header
          2          Reading Packet                                                 
       }
      Repeat
        Repeat
          T:=Uart.rxTime(1000) ' Get Next Byte
          If T==-1
            State:=0
            LongFill(@Signals,0,6) ' Default All Vals to ZEROS  State:=0
            Next
          Case State    
            0:
              Case T
                1 :
                  State:=1
                Other:
            1:
              Case T
                254:
                  ' We have received the Packet Header Now Set the state for receiving the
                  ' Packet
                  State:=2
                  PC:=0 ' Reset Position Counter
                  CheckSum:=255
                  LongFill(@Signals,0,6) ' Default All Vals to ZEROS                                                        
                OTHER: State:=0 ' Abort back to State 0
            2:
              PC++
              If PC<11
                CheckSum ^= T
              Case PC
                1:  Signals.Byte[noparse][[/noparse]0]:=T
                2:  Signals.Byte[noparse][[/noparse]1]:=T
                3:  TachValue.Byte[noparse][[/noparse]0]:=T
                4:  TachValue.Byte[noparse][[/noparse]1]:=T
                5:  Gear:=T
                6:  Speed:=T
                7:  CoolantTemp.Byte[noparse][[/noparse]0]:=T
                8: CoolantTemp.Byte[noparse][[/noparse]1]:=T
                9: BatteryVoltage.Byte[noparse][[/noparse]0]:=T
                10: BatteryVoltage.Byte[noparse][[/noparse]1]:=T
                11:
                  Pass:=(CheckSum==T)
                  State:=0 
                  Quit
        If Pass 
          LongMove(GlobalPointer,@Signals,6) ' pass data back to parent object
     
    




    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Jim Fouch

    FOUCH SOFTWARE

    Post Edited (Jim Fouch) : 11/26/2009 3:31:34 PM GMT
  • kt88seampkt88seamp Posts: 112
    edited 2009-11-26 20:17
    Here is what I am doing:

    My computer transmits a long from a C# program to the propeller by breaking up a long into a byte array. The propeller recieves the four bytes and stores it into its own byte array with this code.

    PUB Program | buffer, i
    
    dira[noparse][[/noparse]0..7] := 255
    i := 0
    
    repeat
      
        i := 0
    
        repeat while i < 4 'Read bytes from C# program.
          if SER.rx == "*" 'A star needs to be recieved to keep garbage data from noise out of the buffer.
            buffer[i] := SER.rx 'Store each byte in buffer.
            i++
    
        i := 0
    
        repeat while i < 4 'Display each array element on LED's on one second intervals.
          outa[noparse][[/noparse]7..0] := buffer[i]
          waitcnt(clkfreq + cnt)
          i++
    [/i][/i]
    



    I still am trying to figure out how to reassemble the four bytes (in the array) into a long variable.
  • MagIO2MagIO2 Posts: 2,243
    edited 2009-11-26 21:07
    How do you send it in C#??? Call a function that sends a qword or do you send it byte by byte?

    You could of course do it byte by byte by yourself, then you know in which order you receive it.

    Otherwise simply find out in which order you receive it by sending $11223344 instead. Then your little display routine will show you the order.

    Either it's MSB first or LSB first. When MSB first you can change the reading-loop by
    buffer <<= 8
    buffer |= SER.rx & $ff

    If it's LSB first you'd do
    buffer >>= 8
    buffer |= (SER.rx << 24) & $ff00_0000

    Remember to set buffer to 0 before starting the loop.
  • kt88seampkt88seamp Posts: 112
    edited 2009-11-26 21:14
    Here is the C# code. I send the data byte by byte. I constructed the display so I could visualise the order. It transmits the MSB first
            private void mnuUpload_Click(object sender, EventArgs e)
            {
                byte[noparse][[/noparse]] test = new byte;
                test = BitConverter.GetBytes(640000);   // 00000000000010011100010000000000
                serCommunicate.Open();
                for (int i = 0; i < 4; i++)
                {
                    serCommunicate.Write("*");
                    serCommunicate.Write(test, i, 1);
                }
                serCommunicate.Close();
                
            }
    
    

    Post Edited (kt88seamp) : 11/26/2009 9:31:25 PM GMT
  • MagIO2MagIO2 Posts: 2,243
    edited 2009-11-26 21:24
    Come on ...

    You don't show what GetBytes is doing ...
    But when you wrote that by yourself as well I don't understand why you have to ask. Just do the opposite.

    $ff_00_00_00 is the most significant byte of the long
    $00_ff_00_00
    $00_00_ff_00
    $00_00_00_ff is the least significant byte.

    So, when you receive the byte simply put it back to the place where it belongs by shift operation.
  • kt88seampkt88seamp Posts: 112
    edited 2009-11-26 21:30
    blush.gif·Sorry, I should of shown somehow that I used a class that microsoft provided to break up the long into bytes. Microsoft does not show you how they do it (closed source model). All they did was package it into one of their classes.

    Post Edited (kt88seamp) : 11/26/2009 9:45:50 PM GMT
  • kt88seampkt88seamp Posts: 112
    edited 2009-11-26 22:07
    I got the byte assembly to work. I'll come back to this post if I have more questions about breaking up a byte from the propeller side.

    Thanks. [noparse]:)[/noparse]
Sign In or Register to comment.