diff --git a/source/TransceiverConfig.hpp b/source/TransceiverConfig.hpp
index 9b7e56a4088363ddded3fd381f8d33795d112f55..e93bfa24abadee1d1de17a221ca3589059430745 100644
--- a/source/TransceiverConfig.hpp
+++ b/source/TransceiverConfig.hpp
@@ -53,6 +53,14 @@ namespace com_saxbophone {
          * @details We currently allow a ±10% timing margin
          */
         const static double DURATION_MARGIN = 0.1;
+
+        /**
+         * @brief This is the total amount of time allocated for one transmission
+         * @details This includes START/STOP bits, message bits and a bit of
+         * silence time for good measure. This is set to 600ms.
+         * @note This is the only duration in this struct to use ms for units
+         */
+        const static unsigned long TRANMISSION_WINDOW = 600;
     };
 
 };
diff --git a/source/main.cpp b/source/main.cpp
index 7dce448742acc4d8c83cc8377a3a22320ff95996..258df6a41c1ded73b65732eacf693c7a998a040f 100644
--- a/source/main.cpp
+++ b/source/main.cpp
@@ -96,6 +96,29 @@ public:
         }
     }
 
+    /**
+     * @brief Returns to the caller once the amount of time since synchronisation
+     * reaches a multiple of the transmission window.
+     * @details This is intended to be used to keep both Master and Slave
+     * synchronised. Assuming their clocks were synchronised correctly, both can
+     * call this and the calls should return at near enough the same point in time.
+     */
+    void barrier() {
+        // TODO: consider allowing for a ±10% margin of error
+        unsigned long time_now = ubit.systemTime(); // what time is it now?
+        // this is how much time we have left to next sync point
+        unsigned long time_left = TransceiverConfig::TRANSMISSION_WINDOW - (
+            (time_now - this->synchronisation_timestamp) %
+            TransceiverConfig::TRANSMISSION_WINDOW
+        );
+        /*
+         * systemTime() can only sleep to 6ms resolution, so sleep to the nearest
+         * multiple of 6ms, rounded down
+         */
+        ubit.sleep((time_left / 6) * 6);
+        // TODO: consider adding busy-wait loop to increase accuracy
+    }
+
 private:
     bool pair_as_master() {
         int pin_state = ubit.io.pin[COMMS_PIN_NUMBER].getDigitalValue();
@@ -572,11 +595,8 @@ int main() {
             ubit.display.scroll("PS");
         }
 
-        // display a "P" to indicate we're paired
-        ubit.display.print('P');
-
         // call barrier to synchronise both master and slave
-        // transceiver.barrier();
+        pairer.barrier();
 
         /* BEGIN COMMS */