Shop OBEX P1 Docs P2 Docs Learn Events
Using the CRC calculator — Parallax Forums

Using the CRC calculator

kt88seampkt88seamp Posts: 112
edited 2010-04-30 23:06 in Propeller 1
I am creating my own program to transmit and receive data with the Parallax RF module. All I need is to add a CRC check (this is where I am in a snafu), and I can finish the rest. I downloaded and tried Beau's RF demo and it includes a CRC check. I am writing my own handshake algorithm. I looked at Beau's code and found working with the CRC object is a little tricky. For my code I need to know how to (see my program comments) using Beau's CRC:

Properly calculate and send the CRC.

Receive the CRC and validate it.

My program does successfully send data using straight RS-232. All I need to do now is packetize the data and implement the CRC and all should work fine.

Thanks,
kt88seamp [noparse]:)[/noparse]

Comments

  • CannibalRoboticsCannibalRobotics Posts: 535
    edited 2010-04-29 20:50
    See my post on CRC for CrystalFontz - it has the packetizer and it's in spin. If you use it on both ends of your system, you should be fine.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Signature space for rent!
    Send $1 to CannibalRobotics.com.

    Post Edited (CannibalRobotics) : 4/29/2010 9:51:35 PM GMT
  • kt88seampkt88seamp Posts: 112
    edited 2010-04-30 12:19
    I found your post.

    http://forums.parallax.com/showthread.php?p=902959

    Not all the code is there. Where is the portion that receives the data and validates the CRC?
  • CannibalRoboticsCannibalRobotics Posts: 535
    edited 2010-04-30 14:59
    OK,
    This is the transmit peice - it sends a 16bit·CRC byte pair at the end of the packet, reversed and inverted. You don't have to go to that trouble - it's device specific.
    The receive component would work similarly in that you would initialize the '_crc'·to $FFFF, cycle each new byte arrival through the updatecrc routine and when you have counted enough bytes - look to see if your calculated·CRC matches the transmitted CRC at the end of your arrived packet.
    Let me know how it goes.
    cheers
    Jim-
    Pub SendText(Line,ptr) | _crc,crch,crcl,i,size,PacketSize
    ' This code has some overhead for clarity and readability
    ' Line: is a device specific command and just inserted into Packet 0
    ' ptr: is a string pointer for an ASCII string to be sent as the payload
    ' the packet structure is: <command><PayloadSize><packet[noparse][[/noparse]0]...packet[noparse][[/noparse]packetsize]><!crcL><!crcH>
                                     
        PacketSize := 17            ' initialize packer size - inclued 0
        size := strsize(ptr)        ' get length of string              
        _crc := $FFFF               ' initialize _crc
        ' Start process of building 18 packet byte <<i = 0 to 17>>
        ' Build packet 0
        if Line == 1                ' if line number 1 then CF command is 6
          Packet[noparse][[/noparse]0] := 7
        if Line == 2
          Packet[noparse][[/noparse]0] := 8            ' if line number 2 then CF command is 7 
        ' Build packet 1
        Packet[noparse][[/noparse]1] := PacketSize - 1 ' Calculate remaining data payload size for packet 1
        ' Build packet 2 - 17
        
        repeat i from 2 to PacketSize  ' set next PacketSize bytes to string byte values or spaces
          if i < (2 + size)
            Packet[noparse][[/noparse]i] := byte[noparse][[/noparse]ptr + i - 2]
          else
            Packet[noparse][[/noparse]i] := 32            'dec 32 is the 'space' charactor for empty text  
        ' Packet now built
        ' so loop through &  calculate _crc, send byte by byte
        
        Repeat i from 0 to PacketSize       'Send front of packet 
          _crc := UpdateCRC(Packet[noparse][[/noparse]i],_crc) ' Calculate crc in the loop
          TSc.tx(Packet[noparse][[/noparse]i])                 ' send the byte
        ' Finished sending packet here so wrap up by sending crc low and high
        '   Watch the MSB/LSB order and inversion here - can be tricky
            
        crcl  :=  !(_crc & $00FF)      ' Bottom 8 bits into crc low & invert      
        crch  :=  !(_crc >> 8)         ' Top 8 bits into crc High & invert 
        
        TSc.tx(crcl)                   ' complete transmission with last two bytes
        TSc.tx(crch)
     
    Pri UpdateCRC(data,crc):newcrc|i,icrc 
    ' CRC calculation engine
    ' SPIN adapted from CrystalFontz generic 'c' algorythm
    ' data: 'new byte' or next byte in packet
    ' crc:  running crc mantained in calling pub/pri
     
      Repeat i from 0 to 7
        if ((crc ^ data) & $01)
          crc := crc >> 1
          crc := crc ^ $8408
        else
          crc := crc >> 1
        data := data >> 1
          
      return crc & $FFFF
    

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Signature space for rent!
    Send $1 to CannibalRobotics.com.
  • kt88seampkt88seamp Posts: 112
    edited 2010-04-30 21:37
    I modified your CRC transmit algorithm so it transmits data bytes instead of strings, as I will not be transmitting ASCII strings in my application. Will the CRC calculate OK with the modifications I made?
  • CannibalRoboticsCannibalRobotics Posts: 535
    edited 2010-04-30 23:06
    Yep, looks like it will work.

    Be careful on the byte count - it's easy to get it confused.

    J-

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Signature space for rent!
    Send $1 to CannibalRobotics.com.
Sign In or Register to comment.