#include <Arduino.h>
#define PREFIX_LENGTH 4
#define MAX_MESSAGE_LENGTH 255
#define TRANSMITTER_ADDRESS 0x01
#define RECEIVER_ADDRESS 0x02
// Global variables
uint8_t messageBuffer[PREFIX_LENGTH + 1 + 1 + MAX_MESSAGE_LENGTH + 1]; // Buffer for constructed message
uint8_t receivedBuffer[MAX_MESSAGE_LENGTH + 1]; // Buffer for received message
volatile size_t messageIndex = 0; // Index for the message buffer
volatile size_t receivedIndex = 0; // Index for the received buffer
volatile bool newDataAvailable = false; // Flag to indicate new data
volatile bool timerStarted = false; // Flag to indicate if timer has started
unsigned long startTime = 0; // Timer for receiving data
int timerSimulator = 0; // Timer simulator
// Function to calculate CRC by XORing all bytes of the message
uint8_t calculate_crc(uint8_t *data, size_t length) {
uint8_t crc = 0; // Initialize CRC
for (size_t i = 0; i < length; i++) {
crc ^= data[i]; // XOR with each byte
}
return crc;
}
// Function to construct the message
void construct_message() {
const char *dataToSend = "Either lower the delay or reduce the message length for the algorithm to finish the execution in time"; // Example data to send
size_t length = strlen(dataToSend); // Calculate length of actual data
if (length > MAX_MESSAGE_LENGTH) {
Serial.println("Error: Message length exceeds maximum limit.");
return;
}
// Construct the message
uint8_t prefix[PREFIX_LENGTH] = {0x01, 0x02, 0x03, 0x04}; // Prefix
memcpy(messageBuffer, prefix, PREFIX_LENGTH); // Copy prefix to buffer
messageBuffer[PREFIX_LENGTH] = (uint8_t)length; // Message length
messageBuffer[PREFIX_LENGTH + 1] = TRANSMITTER_ADDRESS; // Transmitter address
messageBuffer[PREFIX_LENGTH + 2] = RECEIVER_ADDRESS; // Receiver address
memcpy(&messageBuffer[PREFIX_LENGTH + 3], dataToSend, length); // Actual data
// Calculate CRC for entire payload including prefix and data
messageBuffer[PREFIX_LENGTH + 3 + length] = calculate_crc(messageBuffer, PREFIX_LENGTH + 3 + length); // CRC for entire payload
// Loop through each character in the constructed message and send it with a fixed delay
for (size_t i = 0; i < PREFIX_LENGTH + 3 + length + 1; i++) {
delay(50); // Irrelevant Fixed delay
Serial.print("Sending byte: ");
Serial.println(messageBuffer[i], HEX);
receivedBuffer[receivedIndex++] = messageBuffer[i]; // Simulate writing to received buffer
if (receivedIndex >= sizeof(receivedBuffer)) {
break;
}
newDataAvailable = true; // Set flag to indicate new data is available
timerSimulator += random(10, 101); // Increment timer simulator by a random value between 10 and 100
if (timerSimulator > 1000) { // Check if timer exceeds 1000 ms
Serial.println("Error: Timeout waiting for complete message.");
return;
}
// Simulate receiving the character immediately after sending it.
Serial.print("Received byte: ");
Serial.println(receivedBuffer[receivedIndex - 1], HEX);
if (receivedIndex >= sizeof(receivedBuffer)) {
break;
}
}
}
// Receive function
void receive_message() {
if (!newDataAvailable) {
return; // No new data available
}
unsigned long currentTime = millis(); // Get current time
if (!timerStarted) {
startTime = currentTime; // Start timer on first execution of receive_message
timerStarted = true;
}
if (receivedBuffer[0] != 0x01 || receivedBuffer[1] != 0x02 ||
receivedBuffer[2] != 0x03 || receivedBuffer[3] != 0x04) {
Serial.println("Error: Invalid prefix.");
return; // Invalid prefix, refuse to accept more data
}
uint8_t length = receivedBuffer[PREFIX_LENGTH]; // Message length
if (length > MAX_MESSAGE_LENGTH) {
Serial.println("Error: Message length exceeds maximum limit.");
return;
}
uint8_t received_crc = receivedBuffer[PREFIX_LENGTH + 3 + length]; // Received CRC
uint8_t calculated_crc = calculate_crc(receivedBuffer, PREFIX_LENGTH + 3 + length); // Calculate expected CRC
if (calculated_crc != received_crc) {
Serial.print("Error: CRC mismatch. Expected: ");
Serial.print(calculated_crc, HEX);
Serial.print(", Received: ");
Serial.println(received_crc, HEX);
return;
}
Serial.println("=== RECEIVER ===");
Serial.print("Message received successfully:\n");
Serial.print("Length: ");
Serial.println(length);
char finalReceivedData[MAX_MESSAGE_LENGTH + 1];
memcpy(finalReceivedData, &receivedBuffer[PREFIX_LENGTH + 3], length); // Extract actual data
finalReceivedData[length] = '\0'; // Null-terminate the string
Serial.print("Data: '");
Serial.print(finalReceivedData);
Serial.println("'");
Serial.print("Received CRC: ");
Serial.println(received_crc, HEX);
Serial.print("Calculated CRC: ");
Serial.println(calculated_crc, HEX);
newDataAvailable = false; // Reset flag after processing the data
}
void setup() {
Serial.begin(115200);
delay(1000); // Allow time for serial monitor to open
construct_message(); // Construct and transmit the complete message
receive_message(); // Attempt to receive the transmitted data
}
void loop() {
// Not needed here as everything is handled in setup.
}