diff --git a/button_serial.c b/button_serial.c
new file mode 100644
index 0000000000000000000000000000000000000000..a8550503768203d30030895bdd38011d379f6644
--- /dev/null
+++ b/button_serial.c
@@ -0,0 +1,146 @@
+//
+//
+// serial_button.c
+//
+// 115200 baud FTDI connection that outputs '0' or '1' depending
+// on the state of a physical button
+//
+// set lfuse to 0x5E for 20 MHz xtal
+//
+// Neil Gershenfeld
+// 12/8/10
+// Erik Strand
+// 11/26/2018
+//
+#include <avr/io.h>
+#include <util/delay.h>
+#include <avr/pgmspace.h>
+
+#define output(directions,pin) (directions |= pin) // set port direction for output
+#define set(port,pin) (port |= pin) // set port pin
+#define clear(port,pin) (port &= (~pin)) // clear port pin
+#define pin_test(pins,pin) (pins & pin) // test for port pin
+#define bit_test(byte,bit) (byte & (1 << bit)) // test for bit set
+#define bit_delay_time 8.5 // bit delay for 115200 with overhead
+#define bit_delay() _delay_us(bit_delay_time) // RS232 bit delay
+#define half_bit_delay() _delay_us(bit_delay_time/2) // RS232 half bit delay
+#define char_delay() _delay_ms(10) // char delay
+
+#define serial_port PORTA
+#define serial_direction DDRA
+#define serial_pins PINA
+#define serial_pin_in (1 << PA0)
+#define serial_pin_out (1 << PA1)
+
+#define led_pin (1 << PB2)
+#define button_pin (1 << PA7)
+
+#define max_buffer 25
+
+void put_char(volatile unsigned char *port, unsigned char pin, char txchar) {
+    //
+    // send character in txchar on port pin
+    //    assumes line driver (inverts bits)
+    //
+    // start bit
+    //
+    clear(*port,pin);
+    bit_delay();
+    //
+    // unrolled loop to write data bits
+    //
+    if bit_test(txchar,0)
+        set(*port,pin);
+    else
+        clear(*port,pin);
+    bit_delay();
+    if bit_test(txchar,1)
+        set(*port,pin);
+    else
+        clear(*port,pin);
+    bit_delay();
+    if bit_test(txchar,2)
+        set(*port,pin);
+    else
+        clear(*port,pin);
+    bit_delay();
+    if bit_test(txchar,3)
+        set(*port,pin);
+    else
+        clear(*port,pin);
+    bit_delay();
+    if bit_test(txchar,4)
+        set(*port,pin);
+    else
+        clear(*port,pin);
+    bit_delay();
+    if bit_test(txchar,5)
+        set(*port,pin);
+    else
+        clear(*port,pin);
+    bit_delay();
+    if bit_test(txchar,6)
+        set(*port,pin);
+    else
+        clear(*port,pin);
+    bit_delay();
+    if bit_test(txchar,7)
+        set(*port,pin);
+    else
+        clear(*port,pin);
+    bit_delay();
+    //
+    // stop bit
+    //
+    set(*port,pin);
+    bit_delay();
+    //
+    // char delay
+    //
+    bit_delay();
+}
+
+void put_string(volatile unsigned char *port, unsigned char pin, char *str) {
+    //
+    // print a null-terminated string
+    //
+    static int index;
+    index = 0;
+    do {
+        put_char(port, pin, str[index]);
+        ++index;
+    } while (str[index] != 0);
+}
+
+int main(void) {
+    // Set clock divider to 1.
+    CLKPR = (1 << CLKPCE);
+    CLKPR = (0 << CLKPS3) | (0 << CLKPS2) | (0 << CLKPS1) | (0 << CLKPS0);
+
+    // Initialize output pins.
+    set(serial_port, serial_pin_out);
+    output(serial_direction, serial_pin_out);
+
+    // Configure led pin as an output.
+    DDRB |= led_pin;
+
+    // Configure button_pin as an input.
+    DDRA &= ~button_pin;
+
+    // Activate button_pin's pullup resistor.
+    PORTA |= button_pin;
+
+    while (1) {
+        // Turn on the LED when the button is pressed.
+        if (PINA & button_pin) {
+            // Turn off the LED.
+            PORTB &= ~led_pin;
+            put_char(&serial_port, serial_pin_out, '0');
+        } else {
+            PORTB |= led_pin;
+            put_char(&serial_port, serial_pin_out, '1');
+        }
+        _delay_us(10000);
+    }
+}
+