diff --git a/lib/cube/esp_config.py b/lib/cube/esp_config.py
index c87cafd3b0c47e7a6f5684c6152d5065044141b3..67cca4a9200346e441c9538fcd8f7dea4dfdba83 100644
--- a/lib/cube/esp_config.py
+++ b/lib/cube/esp_config.py
@@ -51,8 +51,7 @@ class Esp:
     def __init__(self, pcf_buttons, baud_rate=115200):
         self.uart = UART(INTERNAL_UART_HW_ID, baudrate=baud_rate, bits=8, parity=None, stop=1, 
                          tx=Pin(INTERNAL_UART_TX_PIN), rx=Pin(INTERNAL_UART_RX_PIN), flow=0, invert=0)
-        self.uart_timer = Timer(-1)
-        self.uart_timer.init(mode=Timer.PERIODIC, period=10, callback=self.UART_RX_handler)
+        self.uart.irq(trigger=UART.IRQ_RXIDLE, handler=self.UART_RX_handler)
         self.pcf_buttons = pcf_buttons
         # CONFIG
         self.name = ""
@@ -298,7 +297,7 @@ class Esp:
             self.esp_mode_prev = self.esp_mode
             self.esp_mode_prev = self.esp_mode
             self.esp_mode = Esp.MODE_CMD
-            self.pcf_buttons.set_pin(BUTTON_POWER_RPIN_BIT, False)
+            self.pcf_buttons.set_pin_no_irq(BUTTON_POWER_RPIN_BIT, False)
             utime.sleep(0.01)
             self.flush()
        
@@ -307,7 +306,7 @@ class Esp:
             utime.sleep(0.01)
             self.flush()
             self.esp_mode = self.esp_mode_prev
-            self.pcf_buttons.set_pin(BUTTON_POWER_RPIN_BIT, True)
+            self.pcf_buttons.set_pin_no_irq(BUTTON_POWER_RPIN_BIT, True)
             utime.sleep(0.01)
 
     def timeout(self):
diff --git a/lib/robot.py b/lib/robot.py
index 87c55c95463c36a3fc350ea73daa40b780964486..b6d262bdd539cb9789501d9f20635d051069e961 100644
--- a/lib/robot.py
+++ b/lib/robot.py
@@ -9,7 +9,7 @@ from lib.hw_defs.ports import SENSOR_PORT_PINS, MOTOR_PORT_PINS
 from lib.hw_defs.pins import *
 from lib.robot_consts import Sensor,Button, BAT_VOLTAGE_TURNOFF, BAT_TURNOFF_PERIODS, BAT_MEASURE_PERIOD
 from lib.robot_consts import I2C_INTERNAL_BUS, I2C_INTERNAL_FREQ, PCF_CHECK_PERIOD, DISPLAY_WIDTH, DISPLAY_HEIGHT, FW_VERSION
-from lib.robot_consts import WDT_TIMEOUT, WDT_FEED_TIMER_PERIOD 
+from lib.robot_consts import WDT_TIMEOUT, WDT_FEED_TIMER_PERIOD, ESP_BAUDRATE
 
 import motors_ll
 import brick_ll
@@ -43,7 +43,7 @@ class Robot:
         self.display = SH1106_I2C(DISPLAY_WIDTH, DISPLAY_HEIGHT, self.i2c, self.i2c_lock, rotate=180)
         self.buttons = brick_ll.Buttons()
         self.buttons.pressed_since()
-        self.esp = Esp(self.buttons)
+        self.esp = Esp(self.buttons, ESP_BAUDRATE)
 
         # Ensure pin that turns off the cube is low
         self.turn_off_pin = Pin(TURN_OFF_PIN, Pin.OUT)
@@ -63,7 +63,7 @@ class Robot:
                                 callback=self.check_battery_low)
         
         self.wdt = WDT(timeout=WDT_TIMEOUT)
-        print(f"Watch Dog Timer initialised with timeout {WDT_TIMEOUT/10} s.")
+        print(f"Watch Dog Timer initialised with timeout {WDT_TIMEOUT/1000} s.")
         self.wdt_feed_timer = Timer(-1)
         self.wdt_feed_timer.init(period=WDT_FEED_TIMER_PERIOD, mode=Timer.PERIODIC,
                                  callback=self.wdt_feed)
@@ -84,17 +84,17 @@ class Robot:
             
     # Read cube buttons state on timer interrupt ant turn off cube if power button pressed
     def read_buttons(self, p):
-        self.buttons.read_value()
-        pressed = self.buttons.pressed()
-        if self.cube_startup:
-            if not pressed[Button.POWER]:
-                self.cube_startup = False
-        elif pressed[Button.POWER]:
-            self.display.fill(0)
-            self.display.centered_text('Turning off', 30, 1)
-            self.display.show()
-            sleep(0.3)
-            self.turn_off()
+        if self.buttons.read_value():
+            pressed = self.buttons.pressed()
+            if self.cube_startup:
+                if not pressed[Button.POWER]:
+                    self.cube_startup = False
+            elif pressed[Button.POWER]:
+                self.display.fill(0)
+                self.display.centered_text('Turning off', 30, 1)
+                self.display.show()
+                sleep(0.3)
+                self.turn_off()
                 
     def fw_version(self):
         return FW_VERSION
diff --git a/lib/robot_consts.py b/lib/robot_consts.py
index 0f1c68bcf299bff0ff5e8abd22184c6a1e473b06..1ff807ef8a9df336268f1c081367befd7d3fdea7 100644
--- a/lib/robot_consts.py
+++ b/lib/robot_consts.py
@@ -86,7 +86,7 @@ PCF_CHECK_PERIOD = const(50)        # ms
 I2C_NXT_UTZ_BUS = const(0)
 I2C_INTERNAL_BUS = const(1)
 
-I2C_INTERNAL_FREQ = const(400000)           # Hz
+I2C_INTERNAL_FREQ = const(1000000)           # Hz
 I2C_NXT_UTZ_FREQ = const(30000)             # Hz
 I2C_MULTICUBE_FREQ = const(100000)          # Hz
 
diff --git a/micropython/modules/opencube_brick/buttons.c b/micropython/modules/opencube_brick/buttons.c
index f1e287910228a1647a32b73608e9090d58a4ef94..3e976af7b59992deccf963f0db544a4121e1dcfe 100644
--- a/micropython/modules/opencube_brick/buttons.c
+++ b/micropython/modules/opencube_brick/buttons.c
@@ -31,7 +31,14 @@ static mp_obj_t buttons_make_new(const mp_obj_type_t* type, size_t n_args, size_
 }
 
 static void buttons_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
-  mp_printf(print, "Buttons");
+    uint16_t pcf_last_read = PCF8575_read_value();
+    mp_printf(print, "Buttons (%d, %d, %d, %d, %d, %d)", 
+        (pcf_last_read & (1u << BUTTON_POWER_RPIN)) == 0, 
+        (pcf_last_read & (1u << BUTTON_LEFT_RPIN)) == 0, 
+        (pcf_last_read & (1u << BUTTON_RIGHT_RPIN)) == 0, 
+        (pcf_last_read & (1u << BUTTON_OK_RPIN)) == 0, 
+        (pcf_last_read & (1u << BUTTON_UP_RPIN)) == 0, 
+        (pcf_last_read & (1u << BUTTON_DOWN_RPIN)) == 0);
 }
 
 static mp_obj_t buttons_pressed(mp_obj_t self_in) {
@@ -69,8 +76,9 @@ static mp_obj_t buttons_read_value(mp_obj_t self_in) {
     {
         PCF8575_read();
         opencube_unlock_i2c();
+        return mp_obj_new_bool(true);
     }
-    return mp_const_none;
+    return mp_obj_new_bool(false);
 }
 static MP_DEFINE_CONST_FUN_OBJ_1(buttons_read_value_obj, buttons_read_value);
 
@@ -81,11 +89,26 @@ static mp_obj_t buttons_set_pin(mp_obj_t self_in, mp_obj_t pin, mp_obj_t value)
     {
         PCF8575_write_pin(pin_num, pin_value);
         opencube_unlock_i2c();
+        return mp_obj_new_bool(true);
     }
-    return mp_const_none;
+    return mp_obj_new_bool(false);
 }
 static MP_DEFINE_CONST_FUN_OBJ_3(buttons_set_pin_obj, buttons_set_pin);
 
+static mp_obj_t buttons_set_pin_no_irq(mp_obj_t self_in, mp_obj_t pin, mp_obj_t value) {
+    uint8_t pin_num = mp_obj_get_int(pin);
+    bool pin_value = mp_obj_get_int(value);
+    opencube_lock_i2c_or_raise();
+    PCF8575_write_pin(pin_num, pin_value);
+    if (pin_num == BUTTON_POWER_RPIN)
+    {
+        PCF8575_read(); // Read correct power button state after using the ESP command mode
+    }
+    opencube_unlock_i2c();
+    return mp_const_none;
+}
+static MP_DEFINE_CONST_FUN_OBJ_3(buttons_set_pin_no_irq_obj, buttons_set_pin_no_irq);
+
 static mp_obj_t buttons_turn_off_cube(mp_obj_t self_in) {
     gpio_put(TURN_OFF_PIN, true);
     return mp_const_none;
@@ -99,6 +122,7 @@ static const mp_rom_map_elem_t buttons_locals_dict[] = {
     { MP_ROM_QSTR(MP_QSTR_pressed_since), MP_ROM_PTR(&buttons_pressed_since_obj) },
     { MP_ROM_QSTR(MP_QSTR_read_value), MP_ROM_PTR(&buttons_read_value_obj) },
     { MP_ROM_QSTR(MP_QSTR_set_pin), MP_ROM_PTR(&buttons_set_pin_obj) },
+    { MP_ROM_QSTR(MP_QSTR_set_pin_no_irq), MP_ROM_PTR(&buttons_set_pin_no_irq_obj) },
     { MP_ROM_QSTR(MP_QSTR_turn_off_cube), MP_ROM_PTR(&buttons_turn_off_cube_obj) },
 };
 static MP_DEFINE_CONST_DICT(buttons_locals_dict_obj, buttons_locals_dict);