The communication system between the controller (rPiZero) and print head (Arduino) I decided to simplify the code in the head by using low level functions. These take the hex code strings and pass them directly to the devices or trigger other functions. This allows flexibility and reduces the data that needs to be sent.
I've chosen a standard of 6 byte string with the first byte being the command, then up to four data bytes and finally a CRC byte.
When designing the communication between the head and the raspberry pi, I decided to include a level of error checking on the data passed, as my initial testing showed that signal integrity may be an issue. This has not proven to be a problem thus far. Anyway having a check is good practice. Also the setup process is not a time critical process but one bit wrong could cause problems with setup of the laser diode DACs and thus possible damage to the damage (means I can't blame my typos on interference).
In my research in learning about CRCs I've found the following references useful;
- Cyclic Redundancy Code (CRC) Polynomial Selection For Embedded Networks (Paper)
- Understanding and implementing CRC (Cyclic Redundancy Check) calculation
- Best CRC Polynomials (full data from paper)
The linked paper is interesting as the author has investigated the design space for a huge range of data lengths and code lengths, with the resulting corruption bit length protection. It turns out that the selection of CRC code has a huge impact on the resiliency afforded.
Whilst i'm not gong to try and explain how CRCs work; see the links and your own searches. Essentially there is a balance between the number of bits protected, the number of errors detected and the number of bits in the CRC polynomial.
In my case there is 5x 8bits of data (40bits), i'm using standard 8bit bytes so the CRC can be up to 8bits (may as well use them all). So in my case the 8-bit polynomial 0x83 also known as ATM-8 or CRC-8P is the bet option as it give protection of noticing if up to 4 bits are corrupted and is good for up to 119bits of data length.
If I could send only 7bits easily for the code I would thus use the polynomial 0x5B also known as CRC-7F/4.2 which can protect up to 56bits. This would then save 1bit per transmission/packet which in some situations may be a worth while saving.
Code - Arduino / C++ (good for both TX & RX)
/*=========================================================================================*/
/* ----------------------CRC ATM-8 check------------------------------*/
/*=========================================================================================*/
uint8_t crcTable[256]; //storage of CRC lookup table
void CalulateTable_CRC8() //fill table
{
uint8_t generator = 0x83; //ATM-8 CRC (8bit)
// iterate over all byte values 0- 255
for (int divident = 0; divident < 256; divident++)
{
uint8_t currByte = divident;
//calculate the CRC-8 value for current byte
for (uint8_t bitSec = 0; bitSec < 8; bitSec++)
{
if ((currByte & 0x80) != 0)
{
currByte <<= 1;
currByte ^= generator;
}
else
{
currByte <<= 1;
}
}
//store CRC value in lookup table
crcTable[divident] = currByte;
}
return;
}
uint8_t computeCRC(uint8_t message[], int nBytes)
{
uint8_t crc = 0x0;
for (int b = 0; b < nBytes; ++b)
{
//XOR in next input byte
uint8_t data = message[b] ^ crc;
//get current CRC value = remainder
crc = crcTable[data];
}
return crc;
}
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.