diff --git a/emb/buttons.cpp b/emb/buttons.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..7fc1fbdae925443e1a3317f7bdd8d30005950020
--- /dev/null
+++ b/emb/buttons.cpp
@@ -0,0 +1,43 @@
+#include "buttons.hpp"
+#include "uart.hpp"
+#include "time.hpp"
+#include <avr/io.h>
+
+static bool lastStateA = false;
+static bool lastStateB = false;
+static uint32_t lastMillisA = 0;
+static uint32_t lastMillisB = 0;
+
+void initButtons()
+{
+    DDRC &= ~(1 << DDC5) & ~(1 << DDC4);    // set PC5 and PC4 as inputs
+    PORTC |= (1 << PORTC5) | (1 << PORTC4); // enable pullups
+}
+
+void updateButtons()
+{
+    uint32_t currMillis = getCurrentMillis();
+    
+    bool currStateA = (PINC & (1 << PINC5));
+    bool currStateB = (PINC & (1 << PINC4));
+    
+    if (currStateA != lastStateA)
+    {
+        lastStateA = currStateA;
+        
+        if (!currStateA && (currMillis - lastMillisA) > 50) 
+            writeUart('a');
+        
+        lastMillisA = currMillis;
+    }
+    
+    if (currStateB != lastStateB)
+    {
+        lastStateB = currStateB;
+        
+        if (!currStateB && (currMillis - lastMillisB) > 50)
+            writeUart('b');
+        
+        lastMillisB = currMillis;
+    }
+}
diff --git a/emb/buttons.hpp b/emb/buttons.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..e4f6fcbabfd5d50b0e4143cd818a9725fb7d96c0
--- /dev/null
+++ b/emb/buttons.hpp
@@ -0,0 +1,15 @@
+#ifndef BUTTONS_H
+#define BUTTONS_H
+
+/**
+ * Initialises the button logic.
+ */
+void initButtons();
+
+/**
+ * Updates the button logic.
+ * Should be called periodically.
+ */
+void updateButtons();
+
+#endif /* BUTTONS_H */