Tx Code Description

#include <LiquidCrystal_I2C.h>

// Transmit rate in bps
#define TX_RATE 10

#define TX_CLOCK 2
#define TX_DATA 3
#define PARITY 7

const char *message = "Hello World!";

The above code snippet provides the library that connects us to the LCDs. The pin assignments are typical and the message string is a char* reference to a memory location. This indicates and array start.

void setup() {

pinMode(TX_CLOCK, OUTPUT);
pinMode(TX_DATA, OUTPUT);
pinMode(PARITY, INPUT);

// Initialize the LCD screen
LiquidCrystal_I2C lcd(0x27,16,2);
lcd.init();
lcd.backlight();
lcd.setCursor(0, 0);
lcd.print(message); //Prints the message on line one

for (int byte_idx = 0; byte_idx < strlen(message); byte_idx++) {

char tx_byte = message[byte_idx];

// Clear the second line of the display
lcd.noCursor();
lcd.setCursor(0, 1);
lcd.print(" ");
lcd.setCursor(byte_idx, 0);
lcd.cursor();

The first FOR loop indexes all the chars in the message, then clears the second line of the LCD. It then places the cursor on the first line under the first character of the message.

for (int bit_idx = 0; bit_idx < 8; bit_idx++) {

bool tx_bit = tx_byte & (0x80 >> bit_idx);

// Clocking is 2x the bit rate so low-to-high takes place
// at mid-point of the bit level
digitalWrite(TX_DATA, tx_bit);
delay((1000 / TX_RATE) / 2);

// Update the LCD
lcd.noCursor();
lcd.setCursor(bit_idx, 1);
lcd.print(tx_bit ? "1" : "0");
lcd.setCursor(byte_idx, 0);
lcd.cursor();

// Pulse clock (guarintees clock mid-point)
digitalWrite(TX_CLOCK, HIGH);
delay((1000 / TX_RATE) / 2);
digitalWrite(TX_CLOCK, LOW);

}

}

The second FOR loop move to each char in the message from the first FOR loop and walks through the binary bits. Each bit is AND with a "high". It prints the result to the LCD second line. The value of the first bit is applied to the Data line. The clock advances to the 1/2 bit cycle time and sends a high. The cursor is advance to the next letter and the bit value printed to line two of the LCD. Then the clock is advanced another 1/2 cycle. Each bit is read as the FOR loops cycle until the message length is reached.

//Clock parity circuit to show even parity
digitalWrite(TX_DATA, digitalRead(PARITY));
delay((1000 / TX_RATE) / 2);
digitalWrite(TX_CLOCK, HIGH);
delay((1000 / TX_RATE) / 2);
digitalWrite(TX_CLOCK, LOW);

digitalWrite(TX_DATA, LOW);

At the end of the message, all bit are transmitted, but the parity generator needs one more clock to push the parity value onto the Data line. So this code does that and then clears the Data line if ODD parity left the line high.

}// close of setup()


void loop() {
// no loop activity needed
}