diff --git a/components/badge23/leds.c b/components/badge23/leds.c
index ccd56d565a77d8f40c86cba2d733a2a8f75daf1d..70a15cb55996512481bd0ba5cfc8c870324e6ccb 100644
--- a/components/badge23/leds.c
+++ b/components/badge23/leds.c
@@ -211,6 +211,7 @@ static void renderLEDs(){
 #endif
 
 void leds_set_single_rgb(uint8_t index, uint8_t red, uint8_t green, uint8_t blue){
+    index = (index + 3) % 40;
     uint8_t c[3];
     c[0] = red;
     c[1] = green;
@@ -219,6 +220,7 @@ void leds_set_single_rgb(uint8_t index, uint8_t red, uint8_t green, uint8_t blue
 }
  
 void leds_set_single_hsv(uint8_t index, float hue, float sat, float val){
+    index = (index + 3) % 40;
     struct RGB rgb;
     struct HSV hsv;
     hsv.H = hue;
diff --git a/documentation/micropython_api/hardware.md b/documentation/micropython_api/hardware.md
new file mode 100644
index 0000000000000000000000000000000000000000..8c8e43d7ece0fd20ff9a6dfb027d781735082399
--- /dev/null
+++ b/documentation/micropython_api/hardware.md
@@ -0,0 +1,112 @@
+### user input
+
+```
+button_get(button_number)
+```
+RETURNS state of a shoulder button (0: not pressed, -1: left, 1: right, 2: down)
+
+`button_number` (int, range 0-1)
+: 0 is right shoulder button, 1 is left shoulder button
+
+---
+
+```
+captouch_get(petal_number)
+```
+RETURNS 0 if captouch petal is not touched, 1 if it is touched.
+
+note that captouch is somewhat buggy atm.
+
+`petal_number` (int, range 0-9)
+: which petal. 0 is the top petal above the USB-C port, increments ccw.
+
+---
+```
+captouch_autocalib()
+```
+recalibrates captouch "not touched" reference
+
+### LEDs
+
+```
+led_set_hsv(index, hue, sat, value)
+```
+prepares a single LED to be set to a color with the next `leds_update()` call.
+
+`index` (int, range 0-39)
+: indicates which LED is set. 0 is above the USB-C port, increments ccw. there are 8 LEDs per top petal.
+
+`hue` (float, range 0.0-359.0)
+: hue
+
+`val` (float, range 0.0-1.0)
+: value
+
+`sat` (float, range 0.0-1.0)
+: saturation
+
+---
+
+```
+led_set_rgb(index, hue, sat, value)
+```
+prepares a single LED to be set to a color with the next `leds_update()` call.
+
+`index` (int, range 0-39)
+: indicates which LED is set. 0 is above the USB-C port, increments ccw. there are 8 LEDs per top petal.
+`r` (int, range 0-255)
+: red
+`g` (int, range 0-255)
+: green
+`b` (int, range 0-255)
+: blue
+
+---
+
+```
+leds_update()
+```
+writes LED color configuration to the actual LEDs.
+
+### display (DEPRECATED SOON)
+
+```
+display_set_pixel(x, y, col)
+```
+write to a single pixel in framebuffer to be set to a color with the next `display_update()` call
+
+`x` (int, range 0-239)
+: sets x coordinate (0: right)
+`y` (int, range 0-239)
+: sets y coordinate (0: down)
+`col` (int, range 0-65535)
+: color as an rgb565 number
+
+---
+
+```
+display_get_pixel(x, y, col)
+```
+RETURNS color of a single pixel from the framebuffer as an rgb565 number
+
+`x` (int, range 0-239)
+: sets x coordinate (0: right)
+`y` (int, range 0-239)
+: sets y coordinate (0: down)
+
+---
+
+```
+display_fill(col)
+```
+writes to all pixels in framebuffer to be set to a color with the next `display_update()` call
+
+`col` (int, range 0-65535)
+: color as an rgb565 number
+
+---
+
+```
+display_update()
+```
+writes framebuffer to display
diff --git a/python_payload/harmonic_demo.py b/python_payload/harmonic_demo.py
index 70e99dfbcd290cd1c2a3a6b63a9f95794f58f541..902cfb612d0d38e628886babae6f71ea81084fda 100644
--- a/python_payload/harmonic_demo.py
+++ b/python_payload/harmonic_demo.py
@@ -20,10 +20,10 @@ def set_chord(i):
         chord_index = i
         for j in range(40):
             hue = int(72*(i+0.5)) % 360
-            set_led_hsv(j, hue, 1, 0.2)
+            led_set_hsv(j, hue, 1, 0.2)
         chord = chords[i]
         print("set chord " +str(i))
-        update_leds()
+        leds_update()
 
 
 def run():
@@ -31,7 +31,7 @@ def run():
     global chord
     global synths
     for i in range(10):
-        if(get_captouch(i)):
+        if(captouch_get(i)):
             if(i%2):
                 k = int((i-1)/2)
                 set_chord(k)
diff --git a/python_payload/main.py b/python_payload/main.py
index 1bbeed1cfff9bb45b2aa9908ae2252b7b762fe0a..5e47367323bac7a50821bbb83f462f4cdc25ed59 100644
--- a/python_payload/main.py
+++ b/python_payload/main.py
@@ -42,6 +42,7 @@ def run_menu():
     if selected_petal is not None:
         utils.clear_all_leds()
         utils.highlight_bottom_petal(selected_petal, 55, 0, 0)
+        leds_update()
         display_fill(BACKGROUND_COLOR)
         display_update()
         CURRENT_APP_RUN = selected_module.run
@@ -53,6 +54,7 @@ def foreground_menu():
     utils.clear_all_leds()
     utils.highlight_bottom_petal(0,0,55,55);
     utils.highlight_bottom_petal(1,55,0,55);
+    leds_update()
     display_fill(BACKGROUND_COLOR)
     utils.draw_text_big(SELECT_TEXT, 0, 0)
     display_update()
@@ -84,15 +86,15 @@ def main():
     set_global_volume_dB(VOLUME)
 
     while True:
-        if(get_button(0) == 2):
+        if(button_get(0) == 2):
             if CURRENT_APP_RUN == run_menu:
                 captouch_autocalib()
             else:
                 CURRENT_APP_RUN = run_menu
                 foreground_menu()
-        if(get_button(0) == 1):
+        if(button_get(0) == 1):
             set_rel_volume(+1)
-        if(get_button(0) == -1):
+        if(button_get(0) == -1):
             set_rel_volume(-1)
         CURRENT_APP_RUN()
 
diff --git a/python_payload/melodic_demo.py b/python_payload/melodic_demo.py
index 8ffee2979dd158cbfcf233259d63686ca92316bb..b11810c281ba260501b1cd317bcd1e5670068c25 100644
--- a/python_payload/melodic_demo.py
+++ b/python_payload/melodic_demo.py
@@ -1,14 +1,11 @@
 from synth import tinysynth
 from hardware import *
+from utils import *
 
 octave = 0
 synths = []
 scale = [0,2,4,5,7,9,11]
 
-def highlight_bottom_petal(num, r, g, b):
-    start = 4 + 8*num
-    for i in range(7):
-        set_led_rgb(((i+start)%40), r, g, b)
 
 def change_playing_field_color(r,g,b):
     highlight_bottom_petal(0, r, g, b)
@@ -16,11 +13,11 @@ def change_playing_field_color(r,g,b):
     highlight_bottom_petal(3, r, g, b)
     highlight_bottom_petal(4, r, g, b)
     highlight_bottom_petal(2, 55, 0, 55)
-    set_led_rgb(18, 55, 0, 55)
-    set_led_rgb(19, 55, 0, 55)
-    set_led_rgb(27, 55, 0, 55)
-    set_led_rgb(28, 55, 0, 55)
-    update_leds()
+    led_set_rgb(15, 55, 0, 55)
+    led_set_rgb(16, 55, 0, 55)
+    led_set_rgb(24, 55, 0, 55)
+    led_set_rgb(25, 55, 0, 55)
+    leds_update()
 
 def adjust_playing_field_to_octave():
     global octave
@@ -36,7 +33,7 @@ def run():
     global octave
     global synths
     for i in range(10):
-        if(get_captouch(i)):
+        if(captouch_get(i)):
             if(i == 4):
                 octave = -1
                 adjust_playing_field_to_octave()
diff --git a/python_payload/utils.py b/python_payload/utils.py
index 88ca4d3ba33ff0c8f5f66d5182b3f4dc97871ba9..ca86bde17af7db7635db664a794ed8f4b6e78496 100644
--- a/python_payload/utils.py
+++ b/python_payload/utils.py
@@ -7,8 +7,8 @@ BLUE = 0b0000000000011111
 
 def clear_all_leds():
     for i in range(40):
-        set_led_rgb(i, 0, 0, 0)
-    update_leds()
+        led_set_rgb(i, 0, 0, 0)
+    leds_update()
 
 def draw_text_big(text, x, y):
     ypos = 120+int(len(text)) + int(y)
@@ -16,28 +16,27 @@ def draw_text_big(text, x, y):
     for l, line in enumerate(text):
         for p, pixel in enumerate(line):
             if(pixel == '#'):
-                display_draw_pixel(xpos - 2*p, ypos - 2*l, RED)
-                display_draw_pixel(xpos - 2*p, ypos - 2*l-1, BLUE)
-                display_draw_pixel(xpos - 2*p-1, ypos - 2*l, BLUE)
-                display_draw_pixel(xpos - 2*p-1, ypos - 2*l-1, RED)
+                display_set_pixel(xpos - 2*p, ypos - 2*l, RED)
+                display_set_pixel(xpos - 2*p, ypos - 2*l-1, BLUE)
+                display_set_pixel(xpos - 2*p-1, ypos - 2*l, BLUE)
+                display_set_pixel(xpos - 2*p-1, ypos - 2*l-1, RED)
 
 def highlight_bottom_petal(num, RED, GREEN, BLUE):
-    start = 4 + 8*num
+    start = 1 + 8*num
     for i in range(7):
-        set_led_rgb(((i+start)%40), RED, GREEN, BLUE)
-    update_leds()
+        led_set_rgb(((i+start)%40), RED, GREEN, BLUE)
 
 def long_bottom_petal_captouch_blocking(num, ms):
-    if(get_captouch((num*2) + 1) == 1):
+    if(captouch_get((num*2) + 1) == 1):
         time.sleep_ms(ms)
-        if(get_captouch((num*2) + 1) == 1):
+        if(captouch_get((num*2) + 1) == 1):
             return True
     return False
 
 def draw_rect(x,y,w,h,col):
     for j in range(w):
         for k in range(h):
-            display_draw_pixel(x+j,y+k,col)
+            display_set_pixel(x+j,y+k,col)
 
 def draw_volume_slider(volume):
     length = 96 + ((volume - 20) * 1.6)
diff --git a/usermodule/mp_hardware.c b/usermodule/mp_hardware.c
index 36ecb91ea367cdb4a6696a51c1974de1f9025d65..bc8099355da24d5e425e54b75d9072d34cb82698 100644
--- a/usermodule/mp_hardware.c
+++ b/usermodule/mp_hardware.c
@@ -24,14 +24,14 @@ STATIC mp_obj_t mp_display_update(size_t n_args, const mp_obj_t *args) {
 }
 STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_display_update_obj, 0, 1, mp_display_update);
 
-STATIC mp_obj_t mp_display_draw_pixel(size_t n_args, const mp_obj_t *args) {
+STATIC mp_obj_t mp_display_set_pixel(size_t n_args, const mp_obj_t *args) {
     uint16_t x = mp_obj_get_int(args[0]);
     uint16_t y = mp_obj_get_int(args[1]);
     uint16_t col = mp_obj_get_int(args[2]);
     display_draw_pixel(x, y, col);
     return mp_const_none;
 }
-STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_display_draw_pixel_obj, 3, 4, mp_display_draw_pixel);
+STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_display_set_pixel_obj, 3, 4, mp_display_set_pixel);
 
 STATIC mp_obj_t mp_display_get_pixel(size_t n_args, const mp_obj_t *args) {
     uint16_t x = mp_obj_get_int(args[0]);
@@ -47,14 +47,14 @@ STATIC mp_obj_t mp_display_fill(size_t n_args, const mp_obj_t *args) {
 }
 STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_display_fill_obj, 1, 2, mp_display_fill);
 
-STATIC mp_obj_t mp_get_captouch(size_t n_args, const mp_obj_t *args) {
+STATIC mp_obj_t mp_captouch_get(size_t n_args, const mp_obj_t *args) {
     uint16_t captouch = read_captouch();
     uint16_t pad = mp_obj_get_int(args[0]);
     uint8_t output = (captouch >> pad) & 1;
 
     return mp_obj_new_int(output);
 }
-STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_get_captouch_obj, 1, 2, mp_get_captouch);
+STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_captouch_get_obj, 1, 2, mp_captouch_get);
 
 STATIC mp_obj_t mp_captouch_autocalib(size_t n_args, const mp_obj_t *args) {
     captouch_force_calibration();
@@ -62,12 +62,12 @@ STATIC mp_obj_t mp_captouch_autocalib(size_t n_args, const mp_obj_t *args) {
 }
 STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_captouch_autocalib_obj, 0, 2, mp_captouch_autocalib);
 
-STATIC mp_obj_t mp_get_button(size_t n_args, const mp_obj_t *args) {
+STATIC mp_obj_t mp_button_get(size_t n_args, const mp_obj_t *args) {
     uint8_t leftbutton = mp_obj_get_int(args[0]);
     int8_t ret = get_button_state(leftbutton);
     return mp_obj_new_int(ret);
 }
-STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_get_button_obj, 1, 2, mp_get_button);
+STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_button_get_obj, 1, 2, mp_button_get);
 
 STATIC mp_obj_t mp_set_global_volume_dB(size_t n_args, const mp_obj_t *args) {
     mp_float_t x = mp_obj_get_float(args[0]);
@@ -94,7 +94,7 @@ STATIC mp_obj_t mp_dump_all_sources(size_t n_args, const mp_obj_t *args) {
 STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_dump_all_sources_obj, 0, 2, mp_dump_all_sources);
 
 
-STATIC mp_obj_t mp_set_led_rgb(size_t n_args, const mp_obj_t *args) {
+STATIC mp_obj_t mp_led_set_rgb(size_t n_args, const mp_obj_t *args) {
     uint8_t index =  mp_obj_get_int(args[0]);
     uint8_t red =  mp_obj_get_int(args[1]);
     uint8_t green =  mp_obj_get_int(args[2]);
@@ -102,9 +102,9 @@ STATIC mp_obj_t mp_set_led_rgb(size_t n_args, const mp_obj_t *args) {
     leds_set_single_rgb(index, red, green, blue);
     return mp_const_none;
 }
-STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_set_led_rgb_obj, 4, 5, mp_set_led_rgb);
+STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_led_set_rgb_obj, 4, 5, mp_led_set_rgb);
 
-STATIC mp_obj_t mp_set_led_hsv(size_t n_args, const mp_obj_t *args) {
+STATIC mp_obj_t mp_led_set_hsv(size_t n_args, const mp_obj_t *args) {
     uint8_t index =  mp_obj_get_int(args[0]);
     float hue =  mp_obj_get_float(args[1]);
     float sat =  mp_obj_get_float(args[2]);
@@ -112,13 +112,13 @@ STATIC mp_obj_t mp_set_led_hsv(size_t n_args, const mp_obj_t *args) {
     leds_set_single_hsv(index, hue, sat, val);
     return mp_const_none;
 }
-STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_set_led_hsv_obj, 4, 5, mp_set_led_hsv);
+STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_led_set_hsv_obj, 4, 5, mp_led_set_hsv);
 
-STATIC mp_obj_t mp_update_leds(size_t n_args, const mp_obj_t *args) {
+STATIC mp_obj_t mp_leds_update(size_t n_args, const mp_obj_t *args) {
     leds_update();
     return mp_const_none;
 }
-STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_update_leds_obj, 0, 2, mp_update_leds);
+STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_leds_update_obj, 0, 2, mp_leds_update);
 
 STATIC mp_obj_t mp_version(void) {
     mp_obj_t str = mp_obj_new_str(badge23_hw_name, strlen(badge23_hw_name));
@@ -128,17 +128,17 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_0(mp_version_obj, mp_version);
 
 STATIC const mp_rom_map_elem_t mp_module_hardware_globals_table[] = {
     { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_badge_audio) },
-    { MP_ROM_QSTR(MP_QSTR_get_captouch), MP_ROM_PTR(&mp_get_captouch_obj) },
+    { MP_ROM_QSTR(MP_QSTR_captouch_get), MP_ROM_PTR(&mp_captouch_get_obj) },
     { MP_ROM_QSTR(MP_QSTR_captouch_autocalib), MP_ROM_PTR(&mp_captouch_autocalib_obj) },
-    { MP_ROM_QSTR(MP_QSTR_get_button), MP_ROM_PTR(&mp_get_button_obj) },
+    { MP_ROM_QSTR(MP_QSTR_button_get), MP_ROM_PTR(&mp_button_get_obj) },
     { MP_ROM_QSTR(MP_QSTR_set_global_volume_dB), MP_ROM_PTR(&mp_set_global_volume_dB_obj) },
     { MP_ROM_QSTR(MP_QSTR_count_sources), MP_ROM_PTR(&mp_count_sources_obj) },
     { MP_ROM_QSTR(MP_QSTR_dump_all_sources), MP_ROM_PTR(&mp_dump_all_sources_obj) },
-    { MP_ROM_QSTR(MP_QSTR_set_led_rgb), MP_ROM_PTR(&mp_set_led_rgb_obj) },
-    { MP_ROM_QSTR(MP_QSTR_set_led_hsv), MP_ROM_PTR(&mp_set_led_hsv_obj) },
-    { MP_ROM_QSTR(MP_QSTR_update_leds), MP_ROM_PTR(&mp_update_leds_obj) },
+    { MP_ROM_QSTR(MP_QSTR_led_set_rgb), MP_ROM_PTR(&mp_led_set_rgb_obj) },
+    { MP_ROM_QSTR(MP_QSTR_led_set_hsv), MP_ROM_PTR(&mp_led_set_hsv_obj) },
+    { MP_ROM_QSTR(MP_QSTR_leds_update), MP_ROM_PTR(&mp_leds_update_obj) },
     { MP_ROM_QSTR(MP_QSTR_display_update), MP_ROM_PTR(&mp_display_update_obj) },
-    { MP_ROM_QSTR(MP_QSTR_display_draw_pixel), MP_ROM_PTR(&mp_display_draw_pixel_obj) },
+    { MP_ROM_QSTR(MP_QSTR_display_set_pixel), MP_ROM_PTR(&mp_display_set_pixel_obj) },
     { MP_ROM_QSTR(MP_QSTR_display_get_pixel), MP_ROM_PTR(&mp_display_get_pixel_obj) },
     { MP_ROM_QSTR(MP_QSTR_display_fill), MP_ROM_PTR(&mp_display_fill_obj) },
     { MP_ROM_QSTR(MP_QSTR_version), MP_ROM_PTR(&mp_version_obj) },