#include <LiquidCrystal.h>

// Transmit rate in bps
#define TX_RATE 2

// Pin assignments
#define TX_DATA 3
#define LCD_D4 4
#define LCD_D5 5
#define LCD_D6 6
#define LCD_D7 7
#define LCD_RS 8
#define LCD_EN 9

const char *message = "Hello, world!";

void setup() {
  pinMode(TX_DATA, OUTPUT);

  // Initialize the LCD screen
  LiquidCrystal lcd(LCD_RS, LCD_EN, LCD_D4, LCD_D5, LCD_D6, LCD_D7);
  lcd.begin(16, 2);
  lcd.setCursor(0, 0);
  lcd.print(message);

  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();

    for (int bit_idx = 0; bit_idx < 8; bit_idx++){
      bool tx_bit = tx_byte & (0x80 >> bit_idx);

      digitalWrite(TX_DATA, tx_bit);

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

      delay(1000 / TX_RATE);
    }
  }
  digitalWrite(TX_DATA, LOW);
}

void loop() {
  // put your main code here, to run repeatedly:

}
nano:12
nano:11
nano:10
nano:9
nano:8
nano:7
nano:6
nano:5
nano:4
nano:3
nano:2
nano:GND.2
nano:RESET.2
nano:0
nano:1
nano:13
nano:3.3V
nano:AREF
nano:A0
nano:A1
nano:A2
nano:A3
nano:A4
nano:A5
nano:A6
nano:A7
nano:5V
nano:RESET
nano:GND.1
nano:VIN
nano:12.2
nano:5V.2
nano:13.2
nano:11.2
nano:RESET.3
nano:GND.3
r1:1
r1:2
led1:A
led1:C
lcd1:VSS
lcd1:VDD
lcd1:V0
lcd1:RS
lcd1:RW
lcd1:E
lcd1:D0
lcd1:D1
lcd1:D2
lcd1:D3
lcd1:D4
lcd1:D5
lcd1:D6
lcd1:D7
lcd1:A
lcd1:K
nano1:12
nano1:11
nano1:10
nano1:9
nano1:8
nano1:7
nano1:6
nano1:5
nano1:4
nano1:3
nano1:2
nano1:GND.2
nano1:RESET.2
nano1:0
nano1:1
nano1:13
nano1:3.3V
nano1:AREF
nano1:A0
nano1:A1
nano1:A2
nano1:A3
nano1:A4
nano1:A5
nano1:A6
nano1:A7
nano1:5V
nano1:RESET
nano1:GND.1
nano1:VIN
nano1:12.2
nano1:5V.2
nano1:13.2
nano1:11.2
nano1:RESET.3
nano1:GND.3