//packet header definition
//use packed attribute so compiler doesn't add filler bytes
typedef struct __attribute__((__packed__)) MsgHdr_s
{
uint16_t preamble;
}MsgHdr_t;
//packet checksum definition
typedef struct __attribute__((__packed__)) MsgSum_s
{
uint8_t checksum;
}MsgSum_t;
//packet payload definition
typedef struct __attribute__((__packed__)) MsgPayload_s
{
int16_t myInteger;
float myFloat;
}MsgPayload_t;
//packet definition
typedef struct __attribute__((__packed__)) DataPacket_s
{
MsgHdr_t pktHeader;
MsgPayload_t pktPayload;
MsgSum_t pktChksum;
}DataPacket_t;
//packet variables (TX and RX for this demo)
DataPacket_t myPacket;
DataPacket_t myRxPacket;
//giver serial ports human readable names
HardwareSerial *serMaster = (HardwareSerial *)&Serial1; //master (transmtitter)
HardwareSerial *serSlave = (HardwareSerial *)&Serial3; //slave (receiver)
HardwareSerial *serConsole = (HardwareSerial *)&Serial; //console (to see the result)
void setup()
{
//start serial ports
serMaster->begin(115200);
serSlave->begin(115200);
serConsole->begin(9600);
}//setup
void loop()
{
static uint32_t
tPacket = 0ul;
uint8_t *pPacket;
uint32_t tNow = millis();
//once per second send the packet
if( tNow - tPacket > 1000ul )
{
tPacket = tNow;
//make the packet
myPacket.pktHeader.preamble = 0xaa55;
//populate the payload
myPacket.pktPayload.myInteger = -4567;
myPacket.pktPayload.myFloat = 3.14159;
//get a byte pointer to the packet
pPacket = (uint8_t *)&myPacket;
//compute the checksum and populate the field in the packet
myPacket.pktChksum.checksum = 0x00;
for( int i=0; i<(sizeof( struct DataPacket_s ) - sizeof( struct MsgSum_s )) ; i++ )
myPacket.pktChksum.checksum += *(pPacket+i);
//send the packet
serMaster->write( pPacket, sizeof( struct DataPacket_s ) );
}
//every pass check the receiver
ReceiveMsg();
}//loop
void ReceiveMsg()
{
static uint8_t
*pRxBuffer = (uint8_t *)&myRxPacket;
static uint8_t
rxCount = 0;
uint8_t sum;
//byte available?
if( serSlave->available() > 0 )
{
//place character in the receive packet structure
*(pRxBuffer + rxCount) = serSlave->read();
rxCount++;
//if we've received all bytes of a packet, check it
if( rxCount == sizeof( struct DataPacket_s ) )
{
//calculate the checksum of the received packet
sum = 0x00;
for( int i=0; i<(sizeof( struct DataPacket_s ) - sizeof( struct MsgSum_s )); i++ )
sum += *(pRxBuffer+i);
//if the header preamble and checksum are correct print the values received
if( (myRxPacket.pktHeader.preamble == 0xaa55) && (sum == myRxPacket.pktChksum.checksum ) )
{
serConsole->print( "Int is : " ); serConsole->println( myRxPacket.pktPayload.myInteger );
serConsole->print( "Float is: " ); serConsole->println( myRxPacket.pktPayload.myFloat, 5 );
}//if
//zero the index, ready for next packet
rxCount = 0;
}//if
}//if
}//ReceiveMsg