Arduino/Python Data Framing Library - Using flags, byte stuffing, and CRC16

I have just pushed out a library onto github that I developed for my project. It is a arduino library and a complementary set of python modules which handle data framing for sending serial data between arduino and python.

These libraries could be used python to python, python to arduino, or arduino to arduino.

The packets that are created used start and end flags with byte stuffing and a CRC16 cyclical redundancy check at to ensure data is transmitted correctly.

This was originally designed for the Arduino DUE, but I made modifications to make it compatible with other arduinos as well (though that code is untested, but it should work).

Hopefully this is useful for someone!

May 5 May 1, 2013 - Repository updated with new version! Significantly reduced memory cost for Arduino (now usable on boards other than Due). Python program also improved.

Thanks, looks quite useful (doing some python once and a while)

after a quick look, 2 remarks:

  1. the CRC-16 is "quite" big as it uses 256 bytes that could be mapped in progmem or the crc could be calculated by algorithm (slower but less footprint, serial is slow anyway)
    [an UNO has only 2K RAM so 256 bytes is about 1/8 !]

  2. The frame receiving code looks quite complicated with 3 levels of while, but just need to be studied more in depth

Is there a design doc?

For my project I am using an arduino DUE so the memory requirements were not as big a deal for me!

I did actually implement the CRC-16 by algorithm at first, but I swapped that implementation out for the speed of the tabled CRC version. When I get a chance I will post a third arduino version designed for low memory applications that implements the algorithm version.

If memory is a concern then the framed data output buffer should be customized. It is currently set to be 'framed_data[1000]' in "void Framing::sendFramedData(byte* data, int length)". This can conservatively be set to a value which is equal to (2length_outbound_data + 8 ). The value (2length_outbound_data + 8 ) is chosen for the worst case where all data to be sent equals DLE and both CRC values equal DLE.

I do not have a design document but basically the packet is structured as follows:
[DLE] [STX] [Stuffed Data] [Stuffed CRC16] [DLE] [ETX]

Stuffing refers to adding an additional DLE character before any DLE that appears in the data to be sent or in the calculated CRC.

The CRC is calculated before byte stuffing occurs, or on the receiving end it is calculated after the data has been unstuffed.

The basic while loop structure is as follows:
-While a read timeout has NOT occurred
  -wait for an available byte to be received
  Once an available byte has been received:
    -While a timeout has NOT occured
        -Check for start flag [DLE] [STX]

    When the start flag has been received:
      -While a timeout has NOT occured AND end flag [DLE] [ETX] has not been received
        -Receive data and Unstuff data (replace all instances of [DLE] [DLE] with [DLE])

      When the end flag has been received:
        -Use last two bytes of data as CRC16 and check data validity against this CRC value
          -IF data valid, return data. IF data invalid return -1

IF a timeout occurs before any data is received return 0. IF timeout occurs during data read return -1.

If I were to make a design doc, what would you like to see in it?

your post is already descriptive enough to understand the framing , thanks.

Just for your guys information, I have updated the repository with a new version!

Improvements to Arduino program:
-Table calculation removed, replaced with algorithmic version! (memory requirement reduced drastically)

Improvements to Python program:
-Restructured receivingFramedData function, requires input buffer and returns a tuple which is the length of the data array and the result of running the function

(from post#1)

May 5, 2013 - Repository updated with new version! Significantly reduced memory cost for Arduino (now usable on boards other than Due). Python program also improved.

So I need to check in 3 days? :wink:

Thanks for the update