diff --git a/README.md b/README.md
index 009902ff64965bbd7447ad2f27f76e6ea02e3c03..2efe3c14e1b8c725cd430a14bdd1c2a78826db2e 100644
--- a/README.md
+++ b/README.md
@@ -204,3 +204,47 @@ $ idf.py  menuconfig
 Then, either save into the temporary sdkconfig by using 'S', or save into a
 defconfig by using 'D'. The resulting `build/defconfig` file can then be copied
 into `sdkconfig.$generation` to change the defaults for a given generation.
+
+### Badge link
+
+Badge link lets you have UART between badges or other devices using a 3.5mm
+audio cable.
+
+Baud rates up to 5mbit are supported in theory, but data corruption is likely
+with higher rates.
+
+Use baud rate 31250 for MIDI.
+
+Note that `badge_link.enable()` will refuse to enable line out if the cable is
+not connected. Connect it first. Connecting headphones with badge link enabled
+is not recommended, especially not when wearing them.
+
+Example usage:
+
+On both badges:
+
+```
+import badge_link
+from machine import UART
+badge_link.enable(badge_link.PIN_MASK_ALL)
+```
+
+On badge 1, connect the cable to line out, and configure uart with tx on tip
+(as an example)
+
+```
+uart = UART(1, baudrate=115200, tx=badge_link.PIN_INDEX_LINE_OUT_TIP, rx=badge_link.PIN_INDEX_LINE_OUT_RING)
+```
+
+On badge 2, connect the cable to line in, and configure uart with tx on ring:
+
+```
+uart = UART(1, baudrate=115200, tx=badge_link.PIN_INDEX_LINE_IN_RING, rx=badge_link.PIN_INDEX_LINE_IN_TIP)
+```
+
+Then write and read from each side:
+
+```
+uart.write("hiiii")
+uart.read(5)
+```
diff --git a/components/badge23/audio.c b/components/badge23/audio.c
index f30dd972e80007540a53a42c6cc02c955f235381..9072ec887d4b931c874be1acb557192a2e996da9 100644
--- a/components/badge23/audio.c
+++ b/components/badge23/audio.c
@@ -159,7 +159,7 @@ static void init_codec()
     ESP_ERROR_CHECK(max98091_i2c_write_readback(0x41, 0x0));
 
     ESP_ERROR_CHECK(max98091_i2c_write_readback(0x3D, 1<<7)); // jack detect enable
-    printf("4 readbacks failing here is normal dw ^w^");
+    printf("4 readbacks failing here is normal dw ^w^\n");
 }
 
 static void i2s_init(void){
diff --git a/components/badge23/include/badge23/spio.h b/components/badge23/include/badge23/spio.h
index 085dc306e88ba812e6b1d8acde6c47ca37da2247..039a0ed61367b6a489b636aef64b51f513516694 100644
--- a/components/badge23/include/badge23/spio.h
+++ b/components/badge23/include/badge23/spio.h
@@ -6,18 +6,18 @@
 #define BUTTON_PRESSED_RIGHT 1
 #define BUTTON_NOT_PRESSED 0
 
-#define BADGE_LINK_LINE_IN_TIP      0b0001
-#define BADGE_LINK_LINE_IN_RING     0b0010
-#define BADGE_LINK_LINE_OUT_TIP     0b0100
-#define BADGE_LINK_LINE_OUT_RING    0b1000
-#define BADGE_LINK_LINE_IN ((BADGE_LINK_LINE_IN_TIP) | (BADGE_LINK_LINE_IN_RING))
-#define BADGE_LINK_LINE_OUT ((BADGE_LINK_LINE_OUT_TIP) | (BADGE_LINK_LINE_OUT_RING))
-#define BADGE_LINK_ALL ((BADGE_LINK_LINE_IN) | (BADGE_LINK_LINE_OUT))
+#define BADGE_LINK_PIN_MASK_LINE_IN_TIP      0b0001
+#define BADGE_LINK_PIN_MASK_LINE_IN_RING     0b0010
+#define BADGE_LINK_PIN_MASK_LINE_OUT_TIP     0b0100
+#define BADGE_LINK_PIN_MASK_LINE_OUT_RING    0b1000
+#define BADGE_LINK_PIN_MASK_LINE_IN ((BADGE_LINK_PIN_MASK_LINE_IN_TIP) | (BADGE_LINK_PIN_MASK_LINE_IN_RING))
+#define BADGE_LINK_PIN_MASK_LINE_OUT ((BADGE_LINK_PIN_MASK_LINE_OUT_TIP) | (BADGE_LINK_PIN_MASK_LINE_OUT_RING))
+#define BADGE_LINK_PIN_MASK_ALL ((BADGE_LINK_PIN_MASK_LINE_IN) | (BADGE_LINK_PIN_MASK_LINE_OUT))
 
-#define BADGE_LINK_LINE_IN_TIP_PIN 4
-#define BADGE_LINK_LINE_IN_RING_PIN 5
-#define BADGE_LINK_LINE_OUT_TIP_PIN 6
-#define BADGE_LINK_LINE_OUT_RING_PIN 7
+#define BADGE_LINK_PIN_INDEX_LINE_IN_TIP 4
+#define BADGE_LINK_PIN_INDEX_LINE_IN_RING 5
+#define BADGE_LINK_PIN_INDEX_LINE_OUT_TIP 6
+#define BADGE_LINK_PIN_INDEX_LINE_OUT_RING 7
 
 /* Initializes GPIO modes, prefills structs, etc. Call before using library.
  */
@@ -53,19 +53,19 @@ int8_t spio_application_button_get();
 int8_t spio_left_button_get();
 int8_t spio_right_button_get();
 
-/* Gets active badge links ports. Mask with BADGE_LINK_LINE_{IN/OUT}_{TIP/RING}. The corresponding
- * GPIO indices are listed in BADGE_LINK_LINE_{OUT/IN}_{TIP/RING}_PIN.
+/* Gets active badge links ports. Mask with BADGE_LINK_PIN_MASK_LINE_{IN/OUT}_{TIP/RING}. The corresponding
+ * GPIO indices are listed in BADGE_LINK_PIN_INDEX_LINE_{OUT/IN}_{TIP/RING}.
  */
 uint8_t spio_badge_link_get_active(uint8_t pin_mask);
 
-/* Disables badge link ports. Mask with BADGE_LINK_LINE_{IN/OUT}_{TIP/RING}. The corresponding
- * GPIO indices are listed in BADGE_LINK_LINE_{OUT/IN}_{TIP/RING}_PIN.
+/* Disables badge link ports. Mask with BADGE_LINK_PIN_MASK_LINE_{IN/OUT}_{TIP/RING}. The corresponding
+ * GPIO indices are listed in BADGE_LINK_PIN_INDEX_LINE_{OUT/IN}_{TIP/RING}.
  * Returns the output of spio_badge_link_get_active after execution.
  */
 uint8_t spio_badge_link_disable(uint8_t pin_mask);
 
-/* Enables badge link ports. Mask with BADGE_LINK_LINE_{IN/OUT}_{TIP/RING}. The corresponding
- * GPIO indices are listed in BADGE_LINK_LINE_{OUT/IN}_{TIP/RING}_PIN.
+/* Enables badge link ports. Mask with BADGE_LINK_PIN_MASK_LINE_{IN/OUT}_{TIP/RING}. The corresponding
+ * GPIO indices are listed in BADGE_LINK_PIN_INDEX_LINE_{OUT/IN}_{TIP/RING}_PIN.
  * Returns the output of spio_badge_link_get_active after execution.
  *
  * Do NOT connect headphones to a badge link port. You might hear a ringing for a while. Warn user.
diff --git a/components/badge23/spio.c b/components/badge23/spio.c
index 22946bee312ffefb54c34b0a6c8a838811cad4e7..9caebc24de73081dbc2c1798339f94c6c19eb22b 100644
--- a/components/badge23/spio.c
+++ b/components/badge23/spio.c
@@ -297,10 +297,10 @@ static uint8_t spio_badge_link_set(uint8_t pin_mask, uint8_t state){
 
 static int8_t spio_badge_link_set(uint8_t pin_mask, bool state){
     if(state) {
-        if((pin_mask & BADGE_LINK_LINE_OUT_RING) || (pin_mask & BADGE_LINK_LINE_OUT_TIP)){
+        if((pin_mask & BADGE_LINK_PIN_MASK_LINE_OUT_RING) || (pin_mask & BADGE_LINK_PIN_MASK_LINE_OUT_TIP)){
             if(!audio_headphones_are_connected()) {
-                pin_mask &= ~BADGE_LINK_LINE_OUT_RING;
-                pin_mask &= ~BADGE_LINK_LINE_OUT_TIP;
+                pin_mask &= ~BADGE_LINK_PIN_MASK_LINE_OUT_RING;
+                pin_mask &= ~BADGE_LINK_PIN_MASK_LINE_OUT_TIP;
 #ifdef USER_WARNINGS_ENABLED
                 printf("cannot enable line out badge link without cable plugged in for safety reasons\n");
             } else {
@@ -310,15 +310,15 @@ static int8_t spio_badge_link_set(uint8_t pin_mask, bool state){
         }
     }
 
-    if(pin_mask & BADGE_LINK_LINE_IN_RING) max7321s_set_pinmode_output(BADGE_LINK_LINE_IN_RING_ENABLE_PIN, 1);
-    if(pin_mask & BADGE_LINK_LINE_IN_TIP) max7321s_set_pinmode_output(BADGE_LINK_LINE_IN_TIP_ENABLE_PIN, 1);
-    if(pin_mask & BADGE_LINK_LINE_OUT_RING) max7321s_set_pinmode_output(BADGE_LINK_LINE_OUT_RING_ENABLE_PIN, 1);
-    if(pin_mask & BADGE_LINK_LINE_OUT_TIP) max7321s_set_pinmode_output(BADGE_LINK_LINE_OUT_TIP_ENABLE_PIN, 1);
+    if(pin_mask & BADGE_LINK_PIN_MASK_LINE_IN_RING) max7321s_set_pinmode_output(BADGE_LINK_LINE_IN_RING_ENABLE_PIN, 1);
+    if(pin_mask & BADGE_LINK_PIN_MASK_LINE_IN_TIP) max7321s_set_pinmode_output(BADGE_LINK_LINE_IN_TIP_ENABLE_PIN, 1);
+    if(pin_mask & BADGE_LINK_PIN_MASK_LINE_OUT_RING) max7321s_set_pinmode_output(BADGE_LINK_LINE_OUT_RING_ENABLE_PIN, 1);
+    if(pin_mask & BADGE_LINK_PIN_MASK_LINE_OUT_TIP) max7321s_set_pinmode_output(BADGE_LINK_LINE_OUT_TIP_ENABLE_PIN, 1);
 
-    if(pin_mask & BADGE_LINK_LINE_IN_RING) max7321s_set_pin(BADGE_LINK_LINE_IN_RING_ENABLE_PIN, !state);
-    if(pin_mask & BADGE_LINK_LINE_IN_TIP) max7321s_set_pin(BADGE_LINK_LINE_IN_TIP_ENABLE_PIN, !state);
-    if(pin_mask & BADGE_LINK_LINE_OUT_RING) max7321s_set_pin(BADGE_LINK_LINE_OUT_RING_ENABLE_PIN, !state);
-    if(pin_mask & BADGE_LINK_LINE_OUT_TIP) max7321s_set_pin(BADGE_LINK_LINE_OUT_TIP_ENABLE_PIN, !state);
+    if(pin_mask & BADGE_LINK_PIN_MASK_LINE_IN_RING) max7321s_set_pin(BADGE_LINK_LINE_IN_RING_ENABLE_PIN, !state);
+    if(pin_mask & BADGE_LINK_PIN_MASK_LINE_IN_TIP) max7321s_set_pin(BADGE_LINK_LINE_IN_TIP_ENABLE_PIN, !state);
+    if(pin_mask & BADGE_LINK_PIN_MASK_LINE_OUT_RING) max7321s_set_pin(BADGE_LINK_LINE_OUT_RING_ENABLE_PIN, !state);
+    if(pin_mask & BADGE_LINK_PIN_MASK_LINE_OUT_TIP) max7321s_set_pin(BADGE_LINK_LINE_OUT_TIP_ENABLE_PIN, !state);
 
     max7321s_update();
 
diff --git a/usermodule/mp_badge_link.c b/usermodule/mp_badge_link.c
index cfb8fb4104af8468a2e594cbde1e5714744b5d5f..4111816972ab25e3b98f0fb7268fdacdb1902ea4 100644
--- a/usermodule/mp_badge_link.c
+++ b/usermodule/mp_badge_link.c
@@ -42,15 +42,17 @@ STATIC const mp_rom_map_elem_t mp_module_badge_link_globals_table[] = {
     { MP_ROM_QSTR(MP_QSTR_enable), MP_ROM_PTR(&mp_enable_obj) },
     { MP_ROM_QSTR(MP_QSTR_disable), MP_ROM_PTR(&mp_disable_obj) },
 
-    { MP_ROM_QSTR(MP_QSTR_BADGE_LINK_LINE_IN_TIP), MP_ROM_INT(BADGE_LINK_LINE_IN_TIP) },
-    { MP_ROM_QSTR(MP_QSTR_BADGE_LINK_LINE_IN_RING), MP_ROM_INT(BADGE_LINK_LINE_IN_RING) },
-    { MP_ROM_QSTR(MP_QSTR_BADGE_LINK_LINE_OUT_TIP), MP_ROM_INT(BADGE_LINK_LINE_OUT_TIP) },
-    { MP_ROM_QSTR(MP_QSTR_BADGE_LINK_LINE_OUT_RING), MP_ROM_INT(BADGE_LINK_LINE_OUT_RING) },
-    { MP_ROM_QSTR(MP_QSTR_BADGE_LINK_ALL), MP_ROM_INT(BADGE_LINK_ALL) },
-    { MP_ROM_QSTR(MP_QSTR_BADGE_LINK_LINE_IN_TIP_PIN), MP_ROM_INT(BADGE_LINK_LINE_IN_TIP_PIN) },
-    { MP_ROM_QSTR(MP_QSTR_BADGE_LINK_LINE_IN_RING_PIN), MP_ROM_INT(BADGE_LINK_LINE_IN_RING_PIN) },
-    { MP_ROM_QSTR(MP_QSTR_BADGE_LINK_LINE_OUT_TIP_PIN), MP_ROM_INT(BADGE_LINK_LINE_OUT_TIP_PIN) },
-    { MP_ROM_QSTR(MP_QSTR_BADGE_LINK_LINE_OUT_RING_PIN), MP_ROM_INT(BADGE_LINK_LINE_OUT_RING_PIN) },
+    { MP_ROM_QSTR(MP_QSTR_PIN_MASK_LINE_IN_TIP), MP_ROM_INT(BADGE_LINK_PIN_MASK_LINE_IN_TIP) },
+    { MP_ROM_QSTR(MP_QSTR_PIN_MASK_LINE_IN_RING), MP_ROM_INT(BADGE_LINK_PIN_MASK_LINE_IN_RING) },
+    { MP_ROM_QSTR(MP_QSTR_PIN_MASK_LINE_OUT_TIP), MP_ROM_INT(BADGE_LINK_PIN_MASK_LINE_OUT_TIP) },
+    { MP_ROM_QSTR(MP_QSTR_PIN_MASK_LINE_OUT_RING), MP_ROM_INT(BADGE_LINK_PIN_MASK_LINE_OUT_RING) },
+    { MP_ROM_QSTR(MP_QSTR_PIN_MASK_LINE_IN), MP_ROM_INT(BADGE_LINK_PIN_MASK_LINE_IN) },
+    { MP_ROM_QSTR(MP_QSTR_PIN_MASK_LINE_OUT), MP_ROM_INT(BADGE_LINK_PIN_MASK_LINE_OUT) },
+    { MP_ROM_QSTR(MP_QSTR_PIN_MASK_ALL), MP_ROM_INT(BADGE_LINK_PIN_MASK_ALL) },
+    { MP_ROM_QSTR(MP_QSTR_PIN_INDEX_LINE_IN_TIP), MP_ROM_INT(BADGE_LINK_PIN_INDEX_LINE_IN_TIP) },
+    { MP_ROM_QSTR(MP_QSTR_PIN_INDEX_LINE_IN_RING), MP_ROM_INT(BADGE_LINK_PIN_INDEX_LINE_IN_RING) },
+    { MP_ROM_QSTR(MP_QSTR_PIN_INDEX_LINE_OUT_TIP), MP_ROM_INT(BADGE_LINK_PIN_INDEX_LINE_OUT_TIP) },
+    { MP_ROM_QSTR(MP_QSTR_PIN_INDEX_LINE_OUT_RING), MP_ROM_INT(BADGE_LINK_PIN_INDEX_LINE_OUT_RING) },
 };
 
 STATIC MP_DEFINE_CONST_DICT(mp_module_badge_link_globals, mp_module_badge_link_globals_table);