diff --git a/micropython/modules/ev3_sensors/messages.h b/micropython/modules/ev3_sensors/messages.h
index 6afffdd2e425c3fe74ba5797560fafdb579fb0d5..a1be21582eea7e398cc23d6756d3d57c445bc4c7 100644
--- a/micropython/modules/ev3_sensors/messages.h
+++ b/micropython/modules/ev3_sensors/messages.h
@@ -5,7 +5,7 @@
 #define EV3_SENSOR_MESSAGES_H
 
 #include <stdint.h>
-#include <pico/platform.h>
+#include <pico.h>
 
 // Known sensor IDs
 typedef enum {
diff --git a/micropython/modules/ev3_sensors/micropython_api.c b/micropython/modules/ev3_sensors/micropython_api.c
index 717ed84416dca9e9dbda74a33a142f406546df20..75a5b58574fdc0f7bd93c335efc54e243d7da490 100644
--- a/micropython/modules/ev3_sensors/micropython_api.c
+++ b/micropython/modules/ev3_sensors/micropython_api.c
@@ -26,13 +26,15 @@ typedef struct {
   int proper_id;
 } ev3_api_obj_t;
 
+const mp_obj_type_t ev3_api;
+
 static mp_obj_t new_data_memoryview(ev3_api_obj_t *self);
 static void raise_error_if_closed(ev3_api_obj_t *self);
 static void try_wait_for_sensor(ev3_api_obj_t *self, uint timeout_ms);
 static void try_wait_for_any_sensor(ev3_api_obj_t *self, uint timeout_ms);
 static void try_check_sensor_id(ev3_api_obj_t *self);
 
-STATIC mp_obj_t ev3_api_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
+static mp_obj_t ev3_api_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
   mp_arg_check_num(n_args, n_kw, 2, 2, false);
 
   int port = mp_obj_get_int(args[0]);
@@ -56,7 +58,7 @@ STATIC mp_obj_t ev3_api_make_new(const mp_obj_type_t *type, size_t n_args, size_
     }
   }
 
-  ev3_api_obj_t *self = m_new_obj_with_finaliser(ev3_api_obj_t);
+  ev3_api_obj_t *self = mp_obj_malloc_with_finaliser(ev3_api_obj_t, &ev3_api);
   self->base.type = (mp_obj_type_t *) type;
   self->is_closed = false;
   self->proper_id = sensor_id;
@@ -74,7 +76,7 @@ STATIC mp_obj_t ev3_api_make_new(const mp_obj_type_t *type, size_t n_args, size_
 }
 
 
-STATIC mp_obj_t ev3_api_finalizer(mp_obj_t self_in) {
+static mp_obj_t ev3_api_finalizer(mp_obj_t self_in) {
   ev3_api_obj_t *self = MP_OBJ_TO_PTR(self_in);
 
   if (!self->is_closed) {
@@ -84,10 +86,10 @@ STATIC mp_obj_t ev3_api_finalizer(mp_obj_t self_in) {
   return mp_const_none;
 }
 
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(ev3_api_finalizer_obj, ev3_api_finalizer);
+static MP_DEFINE_CONST_FUN_OBJ_1(ev3_api_finalizer_obj, ev3_api_finalizer);
 
 
-STATIC mp_obj_t ev3_api_is_connected(mp_obj_t self_in) {
+static mp_obj_t ev3_api_is_connected(mp_obj_t self_in) {
   ev3_api_obj_t *self = MP_OBJ_TO_PTR(self_in);
 
   return mp_obj_new_bool(
@@ -95,10 +97,10 @@ STATIC mp_obj_t ev3_api_is_connected(mp_obj_t self_in) {
   );
 }
 
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(ev3_api_is_connected_obj, ev3_api_is_connected);
+static MP_DEFINE_CONST_FUN_OBJ_1(ev3_api_is_connected_obj, ev3_api_is_connected);
 
 
-STATIC mp_obj_t ev3_api_is_ready(mp_obj_t self_in) {
+static mp_obj_t ev3_api_is_ready(mp_obj_t self_in) {
   ev3_api_obj_t *self = MP_OBJ_TO_PTR(self_in);
 
   return mp_obj_new_bool(
@@ -106,10 +108,10 @@ STATIC mp_obj_t ev3_api_is_ready(mp_obj_t self_in) {
   );
 }
 
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(ev3_api_is_ready_obj, ev3_api_is_ready);
+static MP_DEFINE_CONST_FUN_OBJ_1(ev3_api_is_ready_obj, ev3_api_is_ready);
 
 
-STATIC mp_obj_t ev3_api_set_mode(mp_obj_t self_in, mp_obj_t mode_in) {
+static mp_obj_t ev3_api_set_mode(mp_obj_t self_in, mp_obj_t mode_in) {
   ev3_api_obj_t *self = MP_OBJ_TO_PTR(self_in);
   raise_error_if_closed(self);
   try_wait_for_sensor(self, DEFAULT_WAIT_TIMEOUT_MS);
@@ -129,10 +131,10 @@ STATIC mp_obj_t ev3_api_set_mode(mp_obj_t self_in, mp_obj_t mode_in) {
   return mp_const_none;
 }
 
-STATIC MP_DEFINE_CONST_FUN_OBJ_2(ev3_api_set_mode_obj, ev3_api_set_mode);
+static MP_DEFINE_CONST_FUN_OBJ_2(ev3_api_set_mode_obj, ev3_api_set_mode);
 
 
-STATIC mp_obj_t ev3_api_write_command(mp_obj_t self_in, mp_obj_t buffer_in) {
+static mp_obj_t ev3_api_write_command(mp_obj_t self_in, mp_obj_t buffer_in) {
   ev3_api_obj_t *self = MP_OBJ_TO_PTR(self_in);
   raise_error_if_closed(self);
   try_wait_for_sensor(self, DEFAULT_WAIT_TIMEOUT_MS);
@@ -150,10 +152,10 @@ STATIC mp_obj_t ev3_api_write_command(mp_obj_t self_in, mp_obj_t buffer_in) {
   return mp_const_none;
 }
 
-STATIC MP_DEFINE_CONST_FUN_OBJ_2(ev3_api_write_command_obj, ev3_api_write_command);
+static MP_DEFINE_CONST_FUN_OBJ_2(ev3_api_write_command_obj, ev3_api_write_command);
 
 
-STATIC mp_obj_t ev3_api_reset(mp_obj_t self_in) {
+static mp_obj_t ev3_api_reset(mp_obj_t self_in) {
   ev3_api_obj_t *self = MP_OBJ_TO_PTR(self_in);
   raise_error_if_closed(self);
 
@@ -161,10 +163,10 @@ STATIC mp_obj_t ev3_api_reset(mp_obj_t self_in) {
   return mp_const_none;
 }
 
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(ev3_api_reset_obj, ev3_api_reset);
+static MP_DEFINE_CONST_FUN_OBJ_1(ev3_api_reset_obj, ev3_api_reset);
 
 
-STATIC mp_obj_t ev3_api_read(mp_obj_t self_in) {
+static mp_obj_t ev3_api_read(mp_obj_t self_in) {
   ev3_api_obj_t *self = MP_OBJ_TO_PTR(self_in);
   raise_error_if_closed(self);
   try_wait_for_sensor(self, DEFAULT_WAIT_TIMEOUT_MS);
@@ -181,10 +183,10 @@ STATIC mp_obj_t ev3_api_read(mp_obj_t self_in) {
   }
 }
 
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(ev3_api_read_obj, ev3_api_read);
+static MP_DEFINE_CONST_FUN_OBJ_1(ev3_api_read_obj, ev3_api_read);
 
 
-STATIC mp_obj_t ev3_api_read_mode(mp_obj_t self_in, mp_obj_t mode_in) {
+static mp_obj_t ev3_api_read_mode(mp_obj_t self_in, mp_obj_t mode_in) {
   ev3_api_obj_t *self = MP_OBJ_TO_PTR(self_in);
   raise_error_if_closed(self);
   try_wait_for_sensor(self, DEFAULT_WAIT_TIMEOUT_MS);
@@ -218,10 +220,10 @@ STATIC mp_obj_t ev3_api_read_mode(mp_obj_t self_in, mp_obj_t mode_in) {
   return new_data_memoryview(self);
 }
 
-STATIC MP_DEFINE_CONST_FUN_OBJ_2(ev3_api_read_mode_obj, ev3_api_read_mode);
+static MP_DEFINE_CONST_FUN_OBJ_2(ev3_api_read_mode_obj, ev3_api_read_mode);
 
 
-STATIC mp_obj_t ev3_api_get_sensor_id(mp_obj_t self_in) {
+static mp_obj_t ev3_api_get_sensor_id(mp_obj_t self_in) {
   ev3_api_obj_t *self = MP_OBJ_TO_PTR(self_in);
   raise_error_if_closed(self);
 
@@ -233,9 +235,9 @@ STATIC mp_obj_t ev3_api_get_sensor_id(mp_obj_t self_in) {
   }
 }
 
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(ev3_api_get_sensor_id_obj, ev3_api_get_sensor_id);
+static MP_DEFINE_CONST_FUN_OBJ_1(ev3_api_get_sensor_id_obj, ev3_api_get_sensor_id);
 
-STATIC mp_obj_t ev3_api_waitfor(size_t n_args, const mp_obj_t *args) {
+static mp_obj_t ev3_api_waitfor(size_t n_args, const mp_obj_t *args) {
   ev3_api_obj_t *self = MP_OBJ_TO_PTR(args[0]);
   raise_error_if_closed(self);
 
@@ -248,7 +250,7 @@ STATIC mp_obj_t ev3_api_waitfor(size_t n_args, const mp_obj_t *args) {
   return mp_const_none;
 }
 
-STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(ev3_api_waitfor_obj, 1, 2, ev3_api_waitfor);
+static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(ev3_api_waitfor_obj, 1, 2, ev3_api_waitfor);
 
 
 mp_obj_t new_data_memoryview(ev3_api_obj_t *self) {
@@ -325,7 +327,7 @@ void try_check_sensor_id(ev3_api_obj_t *self) {
   }
 }
 
-STATIC const mp_rom_map_elem_t ev3_api_locals_dict_table[] = {
+static const mp_rom_map_elem_t ev3_api_locals_dict_table[] = {
     {MP_ROM_QSTR(MP_QSTR_close),               MP_ROM_PTR(&ev3_api_finalizer_obj)},
     {MP_ROM_QSTR(MP_QSTR___del__),             MP_ROM_PTR(&ev3_api_finalizer_obj)},
     {MP_ROM_QSTR(MP_QSTR_is_connected),        MP_ROM_PTR(&ev3_api_is_connected_obj)},
@@ -338,7 +340,7 @@ STATIC const mp_rom_map_elem_t ev3_api_locals_dict_table[] = {
     {MP_ROM_QSTR(MP_QSTR_sensor_id),           MP_ROM_PTR(&ev3_api_get_sensor_id_obj)},
     {MP_ROM_QSTR(MP_QSTR_wait_for_connection), MP_ROM_PTR(&ev3_api_waitfor_obj)},
 };
-STATIC MP_DEFINE_CONST_DICT(ev3_api_locals_dict, ev3_api_locals_dict_table);
+static MP_DEFINE_CONST_DICT(ev3_api_locals_dict, ev3_api_locals_dict_table);
 
 MP_DEFINE_CONST_OBJ_TYPE(
     ev3_api,
@@ -348,14 +350,14 @@ MP_DEFINE_CONST_OBJ_TYPE(
     locals_dict, &ev3_api_locals_dict
 );
 
-STATIC const mp_rom_map_elem_t ev3_module_globals_table[] = {
+static const mp_rom_map_elem_t ev3_module_globals_table[] = {
     {MP_ROM_QSTR(MP_QSTR___name__),             MP_ROM_QSTR(MP_QSTR_ev3_sensor_ll)},
     {MP_ROM_QSTR(MP_QSTR_EV3Sensor),            MP_ROM_PTR(&ev3_api)},
     {MP_ROM_QSTR(MP_QSTR_SensorNotReadyError),  MP_ROM_PTR(&mp_type_SensorNotReadyError)},
     {MP_ROM_QSTR(MP_QSTR_PortAlreadyOpenError), MP_ROM_PTR(&mp_type_PortAlreadyOpenError)},
     {MP_ROM_QSTR(MP_QSTR_SensorMismatchError),  MP_ROM_PTR(&mp_type_SensorMismatchError)},
 };
-STATIC MP_DEFINE_CONST_DICT(ev3_module_globals, ev3_module_globals_table);
+static MP_DEFINE_CONST_DICT(ev3_module_globals, ev3_module_globals_table);
 
 const mp_obj_module_t ev3_module = {
     .base = {&mp_type_module},
diff --git a/micropython/modules/jv_motors/jv_motor_api.c b/micropython/modules/jv_motors/jv_motor_api.c
index 28acf98a6173995f4f0c5f29077f3acb51b95d5a..8f14f262b6fe1b4b2af83cbcc5de0613b0e8fc70 100644
--- a/micropython/modules/jv_motors/jv_motor_api.c
+++ b/micropython/modules/jv_motors/jv_motor_api.c
@@ -31,7 +31,7 @@ static motor_obj_t *to_initialized_motor(mp_obj_t obj) {
   return self;
 }
 
-STATIC mp_obj_t motor_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
+static mp_obj_t motor_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
   enum {
     ARG_port, ARG_type, ARG_positive_direction
   };
@@ -64,7 +64,7 @@ STATIC mp_obj_t motor_make_new(const mp_obj_type_t *type, size_t n_args, size_t
     mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("Unknown motor direction %d"), mdir);
   }
 
-  motor_obj_t *obj = m_new_obj_with_finaliser(motor_obj_t);
+  motor_obj_t *obj = mp_obj_malloc_with_finaliser(motor_obj_t, &motor_type);
   obj->base.type = type;
   if (!reg_motor_init(&obj->motor, port, mtype, mdir == DIRECTION_CLOCKWISE)) {
     m_del_obj(motor_obj_t, obj);
@@ -79,7 +79,7 @@ static void motor_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind
   mp_printf(print, "Motor(MOTOR_PORT%d)", self->motor.encoder.port + 1);
 }
 
-STATIC mp_obj_t motor_finalizer(mp_obj_t self_in) {
+static mp_obj_t motor_finalizer(mp_obj_t self_in) {
   motor_obj_t *self = MP_OBJ_TO_PTR(self_in);
 
   if (self->initialized) {
@@ -89,17 +89,17 @@ STATIC mp_obj_t motor_finalizer(mp_obj_t self_in) {
   return mp_const_none;
 }
 
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(motor_finalizer_obj, motor_finalizer);
+static MP_DEFINE_CONST_FUN_OBJ_1(motor_finalizer_obj, motor_finalizer);
 
-STATIC mp_obj_t motor_angle(mp_obj_t self_in) {
+static mp_obj_t motor_angle(mp_obj_t self_in) {
   motor_obj_t *self = to_initialized_motor(self_in);
 
   return mp_obj_new_int(reg_motor_get_angle(&self->motor));
 }
 
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(motor_angle_obj, motor_angle);
+static MP_DEFINE_CONST_FUN_OBJ_1(motor_angle_obj, motor_angle);
 
-STATIC mp_obj_t motor_reset_angle(size_t n, const mp_obj_t *objs) {
+static mp_obj_t motor_reset_angle(size_t n, const mp_obj_t *objs) {
   motor_obj_t *self = to_initialized_motor(objs[0]);
 
   int32_t new_angle = 0;
@@ -111,25 +111,25 @@ STATIC mp_obj_t motor_reset_angle(size_t n, const mp_obj_t *objs) {
   return mp_const_none;
 }
 
-STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(motor_reset_angle_obj, 1, 2, motor_reset_angle);
+static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(motor_reset_angle_obj, 1, 2, motor_reset_angle);
 
-STATIC mp_obj_t motor_speed(mp_obj_t self_in) {
+static mp_obj_t motor_speed(mp_obj_t self_in) {
   motor_obj_t *self = to_initialized_motor(self_in);
 
   return mp_obj_new_int(reg_motor_get_speed(&self->motor));
 }
 
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(motor_speed_obj, motor_speed);
+static MP_DEFINE_CONST_FUN_OBJ_1(motor_speed_obj, motor_speed);
 
-STATIC mp_obj_t motor_get_cur_power(mp_obj_t self_in) {
+static mp_obj_t motor_get_cur_power(mp_obj_t self_in) {
   motor_obj_t *self = to_initialized_motor(self_in);
 
   return mp_obj_new_int(reg_motor_get_current_power(&self->motor));
 }
 
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(motor_get_cur_power_obj, motor_get_cur_power);
+static MP_DEFINE_CONST_FUN_OBJ_1(motor_get_cur_power_obj, motor_get_cur_power);
 
-STATIC mp_obj_t motor_attr(mp_obj_t self_in, qstr attribute, mp_obj_t *dest) {
+static mp_obj_t motor_attr(mp_obj_t self_in, qstr attribute, mp_obj_t *dest) {
   if (dest[0] == MP_OBJ_SENTINEL && dest[1] == MP_OBJ_NULL) {
     mp_raise_msg(&mp_type_NotImplementedError, MP_ERROR_TEXT("attribute deletion not supported"));
   }
@@ -251,24 +251,24 @@ STATIC mp_obj_t motor_attr(mp_obj_t self_in, qstr attribute, mp_obj_t *dest) {
 }
 
 
-STATIC mp_obj_t motor_is_complete(mp_obj_t self_in) {
+static mp_obj_t motor_is_complete(mp_obj_t self_in) {
   motor_obj_t *self = to_initialized_motor(self_in);
 
   return mp_obj_new_bool(reg_motor_is_complete(&self->motor));
 }
 
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(motor_is_complete_obj, motor_is_complete);
+static MP_DEFINE_CONST_FUN_OBJ_1(motor_is_complete_obj, motor_is_complete);
 
-STATIC mp_obj_t motor_wait_complete(mp_obj_t self_in) {
+static mp_obj_t motor_wait_complete(mp_obj_t self_in) {
   motor_obj_t *self = to_initialized_motor(self_in);
 
   reg_motor_wait_complete(&self->motor);
   return mp_const_none;
 }
 
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(motor_wait_complete_obj, motor_wait_complete);
+static MP_DEFINE_CONST_FUN_OBJ_1(motor_wait_complete_obj, motor_wait_complete);
 
-STATIC mp_obj_t motor_coast(mp_obj_t self_in) {
+static mp_obj_t motor_coast(mp_obj_t self_in) {
   motor_obj_t *self = to_initialized_motor(self_in);
 
   if (!reg_motor_coast(&self->motor)) {
@@ -278,9 +278,9 @@ STATIC mp_obj_t motor_coast(mp_obj_t self_in) {
   return mp_const_none;
 }
 
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(motor_coast_obj, motor_coast);
+static MP_DEFINE_CONST_FUN_OBJ_1(motor_coast_obj, motor_coast);
 
-STATIC mp_obj_t motor_brake(mp_obj_t self_in) {
+static mp_obj_t motor_brake(mp_obj_t self_in) {
   motor_obj_t *self = to_initialized_motor(self_in);
 
   if (!reg_motor_brake(&self->motor)) {
@@ -290,19 +290,19 @@ STATIC mp_obj_t motor_brake(mp_obj_t self_in) {
   return mp_const_none;
 }
 
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(motor_brake_obj, motor_brake);
+static MP_DEFINE_CONST_FUN_OBJ_1(motor_brake_obj, motor_brake);
 
-STATIC mp_obj_t motor_hold(mp_obj_t self_in) {
+static mp_obj_t motor_hold(mp_obj_t self_in) {
   motor_obj_t *self = to_initialized_motor(self_in);
 
   reg_motor_hold(&self->motor);
   return mp_const_none;
 }
 
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(motor_hold_obj, motor_hold);
+static MP_DEFINE_CONST_FUN_OBJ_1(motor_hold_obj, motor_hold);
 
 
-STATIC mp_obj_t motor_run_unregulated(mp_obj_t self_in, mp_obj_t power) {
+static mp_obj_t motor_run_unregulated(mp_obj_t self_in, mp_obj_t power) {
   motor_obj_t *self = to_initialized_motor(self_in);
 
   if (!reg_motor_run_unregulated(&self->motor, mp_obj_get_int(power))) {
@@ -312,10 +312,10 @@ STATIC mp_obj_t motor_run_unregulated(mp_obj_t self_in, mp_obj_t power) {
   return mp_const_none;
 }
 
-STATIC MP_DEFINE_CONST_FUN_OBJ_2(motor_run_unregulated_obj, motor_run_unregulated);
+static MP_DEFINE_CONST_FUN_OBJ_2(motor_run_unregulated_obj, motor_run_unregulated);
 
 
-STATIC mp_obj_t motor_run_to_angle(size_t n, const mp_obj_t *pos, mp_map_t *kws) {
+static mp_obj_t motor_run_to_angle(size_t n, const mp_obj_t *pos, mp_map_t *kws) {
   enum {
     ARG_speed,
     ARG_target_angle,
@@ -346,9 +346,9 @@ STATIC mp_obj_t motor_run_to_angle(size_t n, const mp_obj_t *pos, mp_map_t *kws)
   return mp_const_none;
 }
 
-STATIC MP_DEFINE_CONST_FUN_OBJ_KW(motor_run_to_angle_obj, 3, motor_run_to_angle);
+static MP_DEFINE_CONST_FUN_OBJ_KW(motor_run_to_angle_obj, 3, motor_run_to_angle);
 
-STATIC mp_obj_t motor_run_by_angle(size_t n, const mp_obj_t *pos, mp_map_t *kws) {
+static mp_obj_t motor_run_by_angle(size_t n, const mp_obj_t *pos, mp_map_t *kws) {
   enum {
     ARG_speed, ARG_rotation_angle, ARG_then, ARG_wait
   };
@@ -376,9 +376,9 @@ STATIC mp_obj_t motor_run_by_angle(size_t n, const mp_obj_t *pos, mp_map_t *kws)
   return mp_const_none;
 }
 
-STATIC MP_DEFINE_CONST_FUN_OBJ_KW(motor_run_by_angle_obj, 3, motor_run_by_angle);
+static MP_DEFINE_CONST_FUN_OBJ_KW(motor_run_by_angle_obj, 3, motor_run_by_angle);
 
-STATIC mp_obj_t motor_run_timed(size_t n, const mp_obj_t *pos, mp_map_t *kws) {
+static mp_obj_t motor_run_timed(size_t n, const mp_obj_t *pos, mp_map_t *kws) {
   enum {
     ARG_speed, ARG_time, ARG_then, ARG_wait
   };
@@ -406,9 +406,9 @@ STATIC mp_obj_t motor_run_timed(size_t n, const mp_obj_t *pos, mp_map_t *kws) {
   return mp_const_none;
 }
 
-STATIC MP_DEFINE_CONST_FUN_OBJ_KW(motor_run_timed_obj, 3, motor_run_timed);
+static MP_DEFINE_CONST_FUN_OBJ_KW(motor_run_timed_obj, 3, motor_run_timed);
 
-STATIC mp_obj_t motor_run_ext_ref(size_t n, const mp_obj_t *pos, mp_map_t *kws) {
+static mp_obj_t motor_run_ext_ref(size_t n, const mp_obj_t *pos, mp_map_t *kws) {
   enum {
     ARG_target_angle,
     ARG_target_speed,
@@ -438,19 +438,19 @@ STATIC mp_obj_t motor_run_ext_ref(size_t n, const mp_obj_t *pos, mp_map_t *kws)
   return mp_const_none;
 }
 
-STATIC MP_DEFINE_CONST_FUN_OBJ_KW(motor_run_ext_ref_obj, 2, motor_run_ext_ref);
+static MP_DEFINE_CONST_FUN_OBJ_KW(motor_run_ext_ref_obj, 2, motor_run_ext_ref);
 
-STATIC mp_obj_t motor_run_unlimited(mp_obj_t self_in, mp_obj_t speed) {
+static mp_obj_t motor_run_unlimited(mp_obj_t self_in, mp_obj_t speed) {
   motor_obj_t *self = to_initialized_motor(self_in);
 
   reg_motor_run_unlimited(&self->motor, mp_obj_get_float_to_f(speed));
   return mp_const_none;
 }
 
-STATIC MP_DEFINE_CONST_FUN_OBJ_2(motor_run_unlimited_obj, motor_run_unlimited);
+static MP_DEFINE_CONST_FUN_OBJ_2(motor_run_unlimited_obj, motor_run_unlimited);
 
 
-STATIC const mp_rom_map_elem_t motor_dict_table[] = {
+static const mp_rom_map_elem_t motor_dict_table[] = {
     // lifetime management
     {MP_ROM_QSTR(MP_QSTR___del__),          MP_ROM_PTR(&motor_finalizer_obj)},
     {MP_ROM_QSTR(MP_QSTR_close),            MP_ROM_PTR(&motor_finalizer_obj)},
@@ -489,7 +489,7 @@ STATIC const mp_rom_map_elem_t motor_dict_table[] = {
     {MP_ROM_QSTR(MP_QSTR_CLOCKWISE),        MP_ROM_INT(DIRECTION_CLOCKWISE)},
     {MP_ROM_QSTR(MP_QSTR_COUNTERCLOCKWISE), MP_ROM_INT(DIRECTION_COUNTERCLOCKWISE)},
 };
-STATIC MP_DEFINE_CONST_DICT(motor_dict, motor_dict_table);
+static MP_DEFINE_CONST_DICT(motor_dict, motor_dict_table);
 
 
 MP_DEFINE_CONST_OBJ_TYPE(
@@ -502,11 +502,11 @@ MP_DEFINE_CONST_OBJ_TYPE(
     print, &motor_print
 );
 
-STATIC const mp_rom_map_elem_t jv_motors_module_globals_table[] = {
+static const mp_rom_map_elem_t jv_motors_module_globals_table[] = {
     {MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_jv_motors)},
     {MP_ROM_QSTR(MP_QSTR_Motor),    MP_ROM_PTR(&motor_type)},
 };
-STATIC MP_DEFINE_CONST_DICT(jv_motors_module_globals, jv_motors_module_globals_table);
+static MP_DEFINE_CONST_DICT(jv_motors_module_globals, jv_motors_module_globals_table);
 
 const mp_obj_module_t jv_motors_module = {
     .base = {&mp_type_module},
diff --git a/micropython/modules/lib/i2c_master.c b/micropython/modules/lib/i2c_master.c
deleted file mode 100644
index b0e633a58e3edca869f81439e4f0d3085c1c6599..0000000000000000000000000000000000000000
--- a/micropython/modules/lib/i2c_master.c
+++ /dev/null
@@ -1,23 +0,0 @@
-#include "hardware/i2c.h"
-
-#include "PCF8575.h"
-#include <opencube_hw.h>
-
-void opencube_i2c_master_init() {
-    PCF8575_init();
-    PCF8575_write_pin(I2C_STRONG_PULL_RPIN, false); // activate external pull-ups
-
-    gpio_init(UTZ_I2C_SDA_PIN);
-    gpio_set_function(UTZ_I2C_SDA_PIN, GPIO_FUNC_I2C);
-
-    gpio_init(UTZ_I2C_SCK_PIN);
-    gpio_set_function(UTZ_I2C_SCK_PIN, GPIO_FUNC_I2C);
-
-    i2c_init(UTZ_I2C_BUS, MULTICUBE_I2C_BAUD_RATE);
-}
-
-// I2C reserves some addresses for special purposes. We exclude these from the scan.
-// These are any addresses of the form 000 0xxx or 111 1xxx
-bool reserved_addr(uint8_t addr) {
-    return (addr & 0x78) == 0 || (addr & 0x78) == 0x78;
-}
\ No newline at end of file
diff --git a/micropython/modules/lib/i2c_master.h b/micropython/modules/lib/i2c_master.h
deleted file mode 100644
index df83c5e7169ce3e42f78f89024486d730e09b638..0000000000000000000000000000000000000000
--- a/micropython/modules/lib/i2c_master.h
+++ /dev/null
@@ -1,7 +0,0 @@
-/**
- *  Library for I2C master multicube communication
- */
-#ifndef OPENCUBE_I2C_MASTER_H
-#define OPENCUBE_I2C_MASTER_H
-
-#endif //OPENCUBE_I2C_MASTER_H
\ No newline at end of file
diff --git a/micropython/modules/lib/i2c_slave.c b/micropython/modules/lib/i2c_slave.c
deleted file mode 100644
index cae8f336b972f8e2b6c5282bb567523c748c948c..0000000000000000000000000000000000000000
--- a/micropython/modules/lib/i2c_slave.c
+++ /dev/null
@@ -1,66 +0,0 @@
-#include <hardware/i2c.h>
-#include "pico/i2c_slave.h"
-
-#include <opencube_hw.h>
-
-// The slave implements a 256 byte memory. To write a series of bytes, the master first
-// writes the memory address, followed by the data. The address is automatically incremented
-// for each byte transferred, looping back to 0 upon reaching the end. Reading is done
-// sequentially from the current memory address.
-static struct
-{
-    uint8_t mem[256];
-    uint8_t mem_address;
-    bool mem_address_written;
-} context;
-
-static void opencube_i2c_slave_handler(i2c_inst_t *i2c, i2c_slave_event_t event);
-
-// Our handler is called from the I2C ISR, so it must complete quickly. Blocking calls /
-// printing to stdio may interfere with interrupt handling.
-static void opencube_i2c_slave_handler(i2c_inst_t *i2c, i2c_slave_event_t event) {
-    switch (event) {
-    case I2C_SLAVE_RECEIVE: // master has written some data
-        if (!context.mem_address_written) {
-            // writes always start with the memory address
-            context.mem_address = i2c_read_byte_raw(i2c);
-            context.mem_address_written = true;
-        } else {
-            // save into memory
-            context.mem[context.mem_address] = i2c_read_byte_raw(i2c);
-            context.mem_address++;
-        }
-        break;
-    case I2C_SLAVE_REQUEST: // master is requesting data
-        // load from memory
-        i2c_write_byte_raw(i2c, context.mem[context.mem_address]);
-        context.mem_address++;
-        break;
-    case I2C_SLAVE_FINISH: // master has signalled Stop / Restart
-        context.mem_address_written = false;
-        break;
-    default:
-        break;
-    }
-}
-
-void opencube_i2c_slave_init(uint8_t address) {
-    PCF8575_init();
-    PCF8575_write_pin(I2C_STRONG_PULL_RPIN, true)
-
-    gpio_init(UTZ_I2C_SDA_PIN);
-    gpio_set_function(UTZ_I2C_SDA_PIN, GPIO_FUNC_I2C);
-
-    gpio_init(UTZ_I2C_SCK_PIN);
-    gpio_set_function(UTZ_I2C_SCK_PIN, GPIO_FUNC_I2C);
-
-    i2c_init(UTZ_I2C_BUS, MULTICUBE_I2C_BAUD_RATE);
-    // configure for slave mode
-    i2c_slave_init(i2c0, address, &opencube_i2c_slave_handler);
-}
-
-// I2C reserves some addresses for special purposes. We exclude these from the scan.
-// These are any addresses of the form 000 0xxx or 111 1xxx
-bool reserved_addr(uint8_t addr) {
-    return (addr & 0x78) == 0 || (addr & 0x78) == 0x78;
-}
\ No newline at end of file
diff --git a/micropython/modules/lib/i2c_slave.h b/micropython/modules/lib/i2c_slave.h
deleted file mode 100644
index 0d46b08a2060e2fff8804982603723bdd1adfb1e..0000000000000000000000000000000000000000
--- a/micropython/modules/lib/i2c_slave.h
+++ /dev/null
@@ -1,7 +0,0 @@
-/**
- *  Library for I2C slave multicube communication
- */
-#ifndef OPENCUBE_I2C_SLAVE_H
-#define OPENCUBE_I2C_SLAVE_H
-
-#endif //OPENCUBE_I2C_SLAVE_H
\ No newline at end of file
diff --git a/micropython/modules/nxt_sensors/analog_sensor.c b/micropython/modules/nxt_sensors/analog_sensor.c
index 9e80a7f2ba384a07e15711b7fb3701b5073891a5..ea9700526184c5902d286521c38b17ff0758c342 100644
--- a/micropython/modules/nxt_sensors/analog_sensor.c
+++ b/micropython/modules/nxt_sensors/analog_sensor.c
@@ -32,7 +32,7 @@ typedef struct {
     analog_port ports[NUM_SENSOR_PORTS];
     alarm_pool_t *timer_pool;
     repeating_timer_t timer;
-    ADS1119_adc_t *adc;
+    ADS1119_adc_t adc;
     bool continuous;
     uint8_t continuous_state;
     uint8_t current_port;
@@ -78,13 +78,11 @@ void opencube_analog_sensors_init(void) {
         }
     }
 
-    ADS1119_adc_t *adc = (ADS1119_adc_t*)malloc(sizeof(ADS1119_adc_t));
-    sensors.adc = adc;
     opencube_lock_i2c_or_raise();
-    ADS1119_init(sensors.adc);
-    ADS1119_set_vref(sensors.adc, 1);
-    ADS1119_set_data_rate(sensors.adc, 3);
-    ADS1119_write_config(sensors.adc);
+    ADS1119_init(&sensors.adc);
+    ADS1119_set_vref(&sensors.adc, 1);
+    ADS1119_set_data_rate(&sensors.adc, 3);
+    ADS1119_write_config(&sensors.adc);
     opencube_unlock_i2c();
     sensors.current_port = 255;
     sensors.enabled = true;
@@ -113,7 +111,6 @@ void opencube_analog_sensors_deinit(void) {
     {
 		opencube_analog_sensor_deinit(i);
 	}
-    sensors.adc = NULL;
     sensors.enabled = false;
 }
 
@@ -161,8 +158,8 @@ void opencube_analog_sensor_set_switching(uint8_t port, bool switching) {
 
 void opencube_analog_sensor_set_channel(uint8_t port) {
     if (sensors.ports[port].enabled) {
-        ADS1119_set_channel(sensors.adc, sensors.ports[port].channel);
-        ADS1119_write_config(sensors.adc);
+        ADS1119_set_channel(&sensors.adc, sensors.ports[port].channel);
+        ADS1119_write_config(&sensors.adc);
         sensors.current_port = port;
     }
 }
@@ -176,7 +173,7 @@ void opencube_analog_sensor_read_value(uint8_t port) {
             opencube_unlock_i2c();
         }
         // blocking ADC value read
-        uint16_t value = ADS1119_lockBusAndReadTwoBytes(sensors.adc);
+        uint16_t value = ADS1119_lockBusAndReadTwoBytes(&sensors.adc);
         // if in switching mode update value depending on led state
         if (sensors.ports[port].switching) {
             if (sensors.ports[port].pin_state) {
@@ -274,7 +271,7 @@ bool opencube_analog_sensor_continuous(repeating_timer_t *timer) {
         return true;
     }
 
-    uint16_t value = ADS1119_read(sensors.adc);
+    uint16_t value = ADS1119_read(&sensors.adc);
     sensors.ports[sensors.current_port].scanned = true;
 
     // in switching mode save read value to desired variable
@@ -326,7 +323,7 @@ bool opencube_analog_sensor_continuous(repeating_timer_t *timer) {
     // Switch to a different adc channel and start new conversion
     if (start_next_read) {
         opencube_analog_sensor_set_channel(sensors.current_port);
-        ADS1119_commandStart(sensors.adc);
+        ADS1119_commandStart(&sensors.adc);
     }
 
     opencube_unlock_i2c();
diff --git a/micropython/modules/nxt_sensors/analog_sensor_api.c b/micropython/modules/nxt_sensors/analog_sensor_api.c
index 3b1778e1b6abda5ef72eb9f82e2f9ca5fac2a76f..c39af3fb23064eb656c30fecafdc558a0b004f36 100644
--- a/micropython/modules/nxt_sensors/analog_sensor_api.c
+++ b/micropython/modules/nxt_sensors/analog_sensor_api.c
@@ -12,15 +12,17 @@ typedef struct _analog_sensor_obj_t {
     uint8_t port;
 } analog_sensor_obj_t;
 
+const mp_obj_type_t opencube_analog_sensor;
+
 // Called on AnalogSensor init
 // Initialize AnalogSensor on given port
-STATIC mp_obj_t analog_sensor_make_new(const mp_obj_type_t* type, size_t n_args, size_t n_kw, const mp_obj_t* args) {
+static mp_obj_t analog_sensor_make_new(const mp_obj_type_t* type, size_t n_args, size_t n_kw, const mp_obj_t* args) {
     mp_arg_check_num(n_args, n_kw, 1, 1, false);
     int port = mp_obj_get_int(args[0]);
     if (port < 0 || port > 3) {
         mp_raise_msg_varg(&mp_type_ValueError, "Port %d is not a valid sensor port", port+1);
     }
-    analog_sensor_obj_t *self = m_new_obj_with_finaliser(analog_sensor_obj_t);
+    analog_sensor_obj_t *self = mp_obj_malloc_with_finaliser(analog_sensor_obj_t, &opencube_analog_sensor);
 
     self->port = port;
     self->base.type = type;
@@ -36,93 +38,93 @@ static void analog_sensor_print(const mp_print_t *print, mp_obj_t self_in) {
 }
 
 // Turn on output pin
-STATIC mp_obj_t analog_sensor_on(mp_obj_t self_in) {
+static mp_obj_t analog_sensor_on(mp_obj_t self_in) {
     analog_sensor_obj_t *self = MP_OBJ_TO_PTR(self_in);
     opencube_analog_sensor_turn_on(self->port);
     return mp_const_none;
 }
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(analog_sensor_on_obj, analog_sensor_on);
+static MP_DEFINE_CONST_FUN_OBJ_1(analog_sensor_on_obj, analog_sensor_on);
 
 // Turn off output pin
-STATIC mp_obj_t analog_sensor_off(mp_obj_t self_in) {
+static mp_obj_t analog_sensor_off(mp_obj_t self_in) {
     analog_sensor_obj_t *self = MP_OBJ_TO_PTR(self_in);
     opencube_analog_sensor_turn_off(self->port);
     return mp_const_none;
 }
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(analog_sensor_off_obj, analog_sensor_off);
+static MP_DEFINE_CONST_FUN_OBJ_1(analog_sensor_off_obj, analog_sensor_off);
 
 // Toggle output pin 
-STATIC mp_obj_t analog_sensor_toggle(mp_obj_t self_in) {
+static mp_obj_t analog_sensor_toggle(mp_obj_t self_in) {
     analog_sensor_obj_t *self = MP_OBJ_TO_PTR(self_in);
     opencube_analog_sensor_toggle(self->port);
     return mp_const_none;
 }
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(analog_sensor_toggle_obj, analog_sensor_toggle);
+static MP_DEFINE_CONST_FUN_OBJ_1(analog_sensor_toggle_obj, analog_sensor_toggle);
 
 // In normal mode - measure and return analog value
 // In continuous mode - return last measured analog value
 // If pin_on is True - last value when output pin was on, False - last value when output pin was off
-STATIC mp_obj_t analog_sensor_get_value(mp_obj_t self_in, mp_obj_t pin_on) {
+static mp_obj_t analog_sensor_get_value(mp_obj_t self_in, mp_obj_t pin_on) {
     analog_sensor_obj_t *self = MP_OBJ_TO_PTR(self_in);
     bool on = (mp_obj_get_int(pin_on) == 1);
 
     uint16_t value = opencube_analog_sensor_get_value(self->port, on);
     return mp_obj_new_int(value);
 }
-STATIC MP_DEFINE_CONST_FUN_OBJ_2(analog_sensor_get_value_obj, analog_sensor_get_value);
+static MP_DEFINE_CONST_FUN_OBJ_2(analog_sensor_get_value_obj, analog_sensor_get_value);
 
 // Check if new data is available
-STATIC mp_obj_t analog_sensor_new_data(mp_obj_t self_in, mp_obj_t led_on) {
+static mp_obj_t analog_sensor_new_data(mp_obj_t self_in, mp_obj_t led_on) {
     analog_sensor_obj_t *self = MP_OBJ_TO_PTR(self_in);
     bool led_on_bool = (mp_obj_get_int(led_on) == 1);
     return mp_obj_new_int(opencube_analog_sensor_new_data(self->port, led_on_bool));
 }
-STATIC MP_DEFINE_CONST_FUN_OBJ_2(analog_sensor_new_data_obj, analog_sensor_new_data);
+static MP_DEFINE_CONST_FUN_OBJ_2(analog_sensor_new_data_obj, analog_sensor_new_data);
 
 // Set sensor port switching mode for continuous measurement.
 // Output value is measured automaticaly with the output pin on and with the output pin off
-STATIC mp_obj_t analog_sensor_set_switching(mp_obj_t self_in) {
+static mp_obj_t analog_sensor_set_switching(mp_obj_t self_in) {
     analog_sensor_obj_t *self = MP_OBJ_TO_PTR(self_in);
     opencube_analog_sensor_set_switching(self->port, true);
     return mp_const_none;
 }
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(analog_sensor_set_switching_obj, analog_sensor_set_switching);
+static MP_DEFINE_CONST_FUN_OBJ_1(analog_sensor_set_switching_obj, analog_sensor_set_switching);
 
 // Set sensor port to non-switching mode for continuous measurement.
-STATIC mp_obj_t analog_sensor_stop_switching(mp_obj_t self_in) {
+static mp_obj_t analog_sensor_stop_switching(mp_obj_t self_in) {
     analog_sensor_obj_t *self = MP_OBJ_TO_PTR(self_in);
     opencube_analog_sensor_set_switching(self->port, false);
     return mp_const_none;
 }
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(analog_sensor_stop_switching_obj, analog_sensor_stop_switching);
+static MP_DEFINE_CONST_FUN_OBJ_1(analog_sensor_stop_switching_obj, analog_sensor_stop_switching);
 
 // Set all analog sensors to continuous mode with given period (us)
 // Wait given time (us) after switching output pin state in switching mode 
-STATIC mp_obj_t analog_sensor_set_continuous(mp_obj_t self_in, mp_obj_t period_us, mp_obj_t wait_us) {
+static mp_obj_t analog_sensor_set_continuous(mp_obj_t self_in, mp_obj_t period_us, mp_obj_t wait_us) {
     uint32_t period = mp_obj_get_int(period_us);
     uint32_t wait = mp_obj_get_int(wait_us);
     opencube_analog_sensor_start_continuous(period, wait);
     return mp_const_none;
 }
-STATIC MP_DEFINE_CONST_FUN_OBJ_3(analog_sensor_set_continuous_obj, analog_sensor_set_continuous);
+static MP_DEFINE_CONST_FUN_OBJ_3(analog_sensor_set_continuous_obj, analog_sensor_set_continuous);
 
 // Stop continuous measurement of all analog sensors
-STATIC mp_obj_t analog_sensor_stop_continuous(mp_obj_t self_in) {
+static mp_obj_t analog_sensor_stop_continuous(mp_obj_t self_in) {
     opencube_analog_sensor_stop_continuous();
     return mp_const_none;
 }
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(analog_sensor_stop_continuous_obj, analog_sensor_stop_continuous);
+static MP_DEFINE_CONST_FUN_OBJ_1(analog_sensor_stop_continuous_obj, analog_sensor_stop_continuous);
 
 // Deinitialize analog sensor
-STATIC mp_obj_t analog_sensor_deinit(mp_obj_t self_in) {
+static mp_obj_t analog_sensor_deinit(mp_obj_t self_in) {
     analog_sensor_obj_t *self = MP_OBJ_TO_PTR(self_in);
     opencube_analog_sensor_deinit(self->port);
     return mp_const_none;
 }
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(analog_sensor_deinit_obj, analog_sensor_deinit);
+static MP_DEFINE_CONST_FUN_OBJ_1(analog_sensor_deinit_obj, analog_sensor_deinit);
 
 // This collects all methods and other static class attributes of the AnalogSensor.
-STATIC const mp_rom_map_elem_t analog_sensor_locals_dict[] = {
+static const mp_rom_map_elem_t analog_sensor_locals_dict[] = {
     { MP_ROM_QSTR(MP_QSTR_on), MP_ROM_PTR(&analog_sensor_on_obj) },
     { MP_ROM_QSTR(MP_QSTR_off), MP_ROM_PTR(&analog_sensor_off_obj) },
     { MP_ROM_QSTR(MP_QSTR_toggle), MP_ROM_PTR(&analog_sensor_toggle_obj) },
@@ -133,8 +135,9 @@ STATIC const mp_rom_map_elem_t analog_sensor_locals_dict[] = {
     { MP_ROM_QSTR(MP_QSTR_set_continuous), MP_ROM_PTR(&analog_sensor_set_continuous_obj) },
     { MP_ROM_QSTR(MP_QSTR_stop_continuous), MP_ROM_PTR(&analog_sensor_stop_continuous_obj)},
     { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&analog_sensor_deinit_obj) },
+    { MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&analog_sensor_deinit_obj) },
 };
-STATIC MP_DEFINE_CONST_DICT(analog_sensor_locals_dict_obj, analog_sensor_locals_dict);
+static MP_DEFINE_CONST_DICT(analog_sensor_locals_dict_obj, analog_sensor_locals_dict);
 
 // This defines the type(AnalogSensor) object.
 MP_DEFINE_CONST_OBJ_TYPE(
@@ -151,16 +154,16 @@ MP_DEFINE_CONST_OBJ_TYPE(
 // and the MicroPython object reference.
 // All identifiers and strings are written as MP_QSTR_xxx and will be
 // optimized to word-sized integers by the build system (interned strings).
-STATIC const mp_rom_map_elem_t analog_sensor_globals_dict[] = {
+static const mp_rom_map_elem_t analog_sensor_globals_dict[] = {
     { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_analog_sensor) },
     { MP_ROM_QSTR(MP_QSTR_AnalogSensor), MP_ROM_PTR(&opencube_analog_sensor) },
 };
-STATIC MP_DEFINE_CONST_DICT(analog_sensor_globals_dict_obj, analog_sensor_globals_dict);
+static MP_DEFINE_CONST_DICT(analog_sensor_globals_dict_obj, analog_sensor_globals_dict);
 
 // Define module object.
 const mp_obj_module_t analog_sensor = {
     .base = {.type = &mp_type_module },
-    .globals = (mp_obj_dict_t*)&analog_sensor_globals_dict_obj,
+    .globals = (mp_obj_dict_t *) &analog_sensor_globals_dict_obj,
 };
 
 // Register the module to make it available in Python.
diff --git a/micropython/modules/opencube_brick/ICM_api.c b/micropython/modules/opencube_brick/ICM_api.c
index 8e91e0ed2804a791d54b8fd73566e2bd07766048..121e7b1fadea62b562d86ecb8e6f7cecdc108266 100644
--- a/micropython/modules/opencube_brick/ICM_api.c
+++ b/micropython/modules/opencube_brick/ICM_api.c
@@ -9,19 +9,20 @@
 // This structure represents ICM instance objects.
 typedef struct _ICM_obj_t {
     mp_obj_base_t base;
-    ICM42688_t* icm;
+    ICM42688_t icm;
 } ICM_obj_t;
 
+const mp_obj_type_t opencube_ICM_type;
 
 static void ICM_print(const mp_print_t *print, mp_obj_t self_in);
 
 // Called on ICM init
-STATIC mp_obj_t ICM_make_new(const mp_obj_type_t* type, size_t n_args, size_t n_kw, const mp_obj_t* args) {
-    ICM_obj_t *self = m_new_obj(ICM_obj_t);	
+static mp_obj_t ICM_make_new(const mp_obj_type_t* type, size_t n_args, size_t n_kw, const mp_obj_t* args) {
+    ICM_obj_t *self = mp_obj_malloc_with_finaliser(ICM_obj_t, &opencube_ICM_type);
     self->base.type = type;
-    self->icm = (ICM42688_t*)malloc(sizeof(ICM42688_t));
+    //self->icm = (ICM42688_t*)malloc(sizeof(ICM42688_t));
     opencube_lock_i2c_or_raise();
-    ICM42688_init(self->icm);
+    ICM42688_init(&self->icm);
     opencube_unlock_i2c();
     return MP_OBJ_FROM_PTR(self);
 }
@@ -30,11 +31,11 @@ static void ICM_print(const mp_print_t *print, mp_obj_t self_in) {
     //ICM_obj_t *self = MP_OBJ_TO_PTR(self_in);
 }
 
-STATIC mp_obj_t ICM_read_value(mp_obj_t self_in) {
+static mp_obj_t ICM_read_value(mp_obj_t self_in) {
     ICM_obj_t *self = MP_OBJ_TO_PTR(self_in);	
     float accel_x, accel_y, accel_z, gyro_x, gyro_y, gyro_z;
     opencube_lock_i2c_or_raise();
-    ICM42688_read_data(self->icm, 
+    ICM42688_read_data(&self->icm, 
                        &accel_x, &accel_y, &accel_z, 
                        &gyro_x, &gyro_y, &gyro_z);
     opencube_unlock_i2c();
@@ -48,25 +49,25 @@ STATIC mp_obj_t ICM_read_value(mp_obj_t self_in) {
         };
     return mp_obj_new_tuple(6, tuple);
 }
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(ICM_read_value_obj, ICM_read_value);
+static MP_DEFINE_CONST_FUN_OBJ_1(ICM_read_value_obj, ICM_read_value);
 
 static mp_obj_t ICM_deinit(mp_obj_t self_in) {
     ICM_obj_t *self = MP_OBJ_FROM_PTR(self_in);
-    ICM42688_off(self->icm);
-    self->icm = NULL;
+    ICM42688_off(&self->icm);
+    //self->icm = NULL;
     return mp_const_none;
 }
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(ICM_deinit_obj, ICM_deinit);
+static MP_DEFINE_CONST_FUN_OBJ_1(ICM_deinit_obj, ICM_deinit);
 
 // This collects all methods and other static class attributes of the ICM.
 // The table structure is similar to the module table, as detailed below.
-STATIC const mp_rom_map_elem_t ICM_locals_dict[] = {
+static const mp_rom_map_elem_t ICM_locals_dict[] = {
     { MP_ROM_QSTR(MP_QSTR_read_value), MP_ROM_PTR(&ICM_read_value_obj) },
     { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&ICM_deinit_obj) },
     { MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&ICM_deinit_obj) },
     { MP_ROM_QSTR(MP_QSTR_close), MP_ROM_PTR(&ICM_deinit_obj) },
 };
-STATIC MP_DEFINE_CONST_DICT(ICM_locals_dict_obj, ICM_locals_dict);
+static MP_DEFINE_CONST_DICT(ICM_locals_dict_obj, ICM_locals_dict);
 
 // This defines the type(ICM) object.
 MP_DEFINE_CONST_OBJ_TYPE(
diff --git a/micropython/modules/opencube_brick/battery.c b/micropython/modules/opencube_brick/battery.c
index 246873c1c1dd20e36d7cbda3cd2bf7197de7b5b9..9e6dc54a17ecd36f61718f4cf1f26c12030e4671 100644
--- a/micropython/modules/opencube_brick/battery.c
+++ b/micropython/modules/opencube_brick/battery.c
@@ -15,6 +15,8 @@ typedef struct {
     repeating_timer_t timer;
 } battery_obj_t;
 
+const mp_obj_type_t opencube_battery_type;
+
 static void read_voltage(battery_obj_t *self);
 static bool read_voltage_handler(repeating_timer_t *timer);
 static void battery_print(const mp_print_t *print, mp_obj_t self_in);
@@ -34,36 +36,36 @@ static void battery_print(const mp_print_t *print, mp_obj_t self_in) {
     //battery_obj_t *self = MP_OBJ_TO_PTR(self_in);
 }
 
-STATIC mp_obj_t battery_read_voltage(mp_obj_t self_in) {
+static mp_obj_t battery_read_voltage(mp_obj_t self_in) {
     battery_obj_t *self = MP_OBJ_TO_PTR(self_in);
     read_voltage(self);
     return mp_obj_new_float(self->last_value);
 }
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(battery_read_voltage_obj, battery_read_voltage);
+static MP_DEFINE_CONST_FUN_OBJ_1(battery_read_voltage_obj, battery_read_voltage);
 
-STATIC mp_obj_t battery_voltage(mp_obj_t self_in) {
+static mp_obj_t battery_voltage(mp_obj_t self_in) {
     battery_obj_t *self = MP_OBJ_TO_PTR(self_in);
     return mp_obj_new_float(self->last_value);
 }
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(battery_voltage_obj, battery_voltage);
+static MP_DEFINE_CONST_FUN_OBJ_1(battery_voltage_obj, battery_voltage);
 
-STATIC mp_obj_t battery_set_multiplier(mp_obj_t self_in, mp_obj_t multiplier) {
+static mp_obj_t battery_set_multiplier(mp_obj_t self_in, mp_obj_t multiplier) {
     battery_obj_t *self = MP_OBJ_TO_PTR(self_in);
     self->multiplier = mp_obj_get_float(multiplier);
     return mp_const_none;
 }
-STATIC MP_DEFINE_CONST_FUN_OBJ_2(battery_set_multiplier_obj, battery_set_multiplier);
+static MP_DEFINE_CONST_FUN_OBJ_2(battery_set_multiplier_obj, battery_set_multiplier);
 
-STATIC mp_obj_t battery_deinit(mp_obj_t self_in) {
+static mp_obj_t battery_deinit(mp_obj_t self_in) {
     battery_obj_t *self = MP_OBJ_TO_PTR(self_in);
     alarm_pool_cancel_alarm(self->timer_pool, self->timer.alarm_id);
     return mp_const_none;
 }
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(battery_deinit_obj, battery_deinit);
+static MP_DEFINE_CONST_FUN_OBJ_1(battery_deinit_obj, battery_deinit);
 
 // Called on Battery init
-STATIC mp_obj_t battery_make_new(const mp_obj_type_t* type, size_t n_args, size_t n_kw, const mp_obj_t* args) {
-    battery_obj_t *self = m_new_obj_with_finaliser(battery_obj_t);
+static mp_obj_t battery_make_new(const mp_obj_type_t* type, size_t n_args, size_t n_kw, const mp_obj_t* args) {
+    battery_obj_t *self = mp_obj_malloc_with_finaliser(battery_obj_t, &opencube_battery_type);
     self->base.type = type;
     self->multiplier = 1.0;
     // Initialise the ADC peripheral if it's not already running.
@@ -90,14 +92,14 @@ STATIC mp_obj_t battery_make_new(const mp_obj_type_t* type, size_t n_args, size_
 
 // This collects all methods and other static class attributes of the Battery.
 // The table structure is similar to the module table, as detailed below.
-STATIC const mp_rom_map_elem_t battery_locals_dict[] = {
+static const mp_rom_map_elem_t battery_locals_dict[] = {
     { MP_ROM_QSTR(MP_QSTR_read_voltage), MP_ROM_PTR(&battery_read_voltage_obj) },
     { MP_ROM_QSTR(MP_QSTR_voltage), MP_ROM_PTR(&battery_voltage_obj) },
     { MP_ROM_QSTR(MP_QSTR_set_multiplier), MP_ROM_PTR(&battery_set_multiplier_obj) },
     { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&battery_deinit_obj) },
     { MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&battery_deinit_obj) },
 };
-STATIC MP_DEFINE_CONST_DICT(battery_locals_dict_obj, battery_locals_dict);
+static MP_DEFINE_CONST_DICT(battery_locals_dict_obj, battery_locals_dict);
 
 // This defines the type(Battery) object.
 MP_DEFINE_CONST_OBJ_TYPE(
diff --git a/micropython/modules/opencube_brick/brick_api.c b/micropython/modules/opencube_brick/brick_api.c
index d4996e4bbcbae368ca3b9986fabad371b4dd59ec..5483848a509914d7aa413efb8b45e51d98675c06 100644
--- a/micropython/modules/opencube_brick/brick_api.c
+++ b/micropython/modules/opencube_brick/brick_api.c
@@ -7,11 +7,11 @@
 #include "led.h"
 #include "opencube_fw_version.h"
 
-STATIC mp_obj_t i2c_lock_fun(void) {
+static mp_obj_t i2c_lock_fun(void) {
     opencube_lock_i2c_or_raise();
     return mp_const_none;
 }
-STATIC mp_obj_t i2c_unlock_fun(void) {
+static mp_obj_t i2c_unlock_fun(void) {
     opencube_unlock_i2c();
     return mp_const_none;
 }
diff --git a/micropython/modules/opencube_brick/buttons.c b/micropython/modules/opencube_brick/buttons.c
index 12e3b45a54deb58f678923311b0134fa1992ad5a..b6849f75fd35f3408f940ca5ff380eacdbaac2fb 100644
--- a/micropython/modules/opencube_brick/buttons.c
+++ b/micropython/modules/opencube_brick/buttons.c
@@ -21,7 +21,7 @@ typedef struct _buttons_obj_t {
 //static void pcf_irq_handler(void);
 
 // Called on buttons init
-STATIC mp_obj_t buttons_make_new(const mp_obj_type_t* type, size_t n_args, size_t n_kw, const mp_obj_t* args) {
+static mp_obj_t buttons_make_new(const mp_obj_type_t* type, size_t n_args, size_t n_kw, const mp_obj_t* args) {
     buttons_obj_t *self = m_new_obj(buttons_obj_t);
     self->base.type = type;
     opencube_lock_i2c_or_raise();
@@ -30,11 +30,11 @@ STATIC mp_obj_t buttons_make_new(const mp_obj_type_t* type, size_t n_args, size_
     return MP_OBJ_FROM_PTR(self);
 }
 
-STATIC void buttons_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
+static void buttons_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
   mp_printf(print, "Buttons");
 }
 
-STATIC mp_obj_t buttons_pressed(mp_obj_t self_in) {
+static mp_obj_t buttons_pressed(mp_obj_t self_in) {
     uint16_t pcf_last_read = PCF8575_read_value();
     uint16_t pcf_last_write = PCF8575_read_function();
     mp_obj_t tuple[6] = {
@@ -48,9 +48,9 @@ STATIC mp_obj_t buttons_pressed(mp_obj_t self_in) {
         };
     return mp_obj_new_tuple(6, tuple);
 }
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(buttons_pressed_obj, buttons_pressed);
+static MP_DEFINE_CONST_FUN_OBJ_1(buttons_pressed_obj, buttons_pressed);
 
-STATIC mp_obj_t buttons_pressed_since(mp_obj_t self_in) {
+static mp_obj_t buttons_pressed_since(mp_obj_t self_in) {
     uint16_t pcf_last_read = PCF8575_read_value_missed();
     mp_obj_t tuple[6] = {
             tuple[0] = mp_obj_new_bool(0),
@@ -62,9 +62,9 @@ STATIC mp_obj_t buttons_pressed_since(mp_obj_t self_in) {
         };
     return mp_obj_new_tuple(6, tuple);
 }
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(buttons_pressed_since_obj, buttons_pressed_since);
+static MP_DEFINE_CONST_FUN_OBJ_1(buttons_pressed_since_obj, buttons_pressed_since);
 
-STATIC mp_obj_t buttons_read_value(mp_obj_t self_in) {
+static mp_obj_t buttons_read_value(mp_obj_t self_in) {
     if (opencube_try_lock_i2c())
     {
         PCF8575_read();
@@ -72,9 +72,9 @@ STATIC mp_obj_t buttons_read_value(mp_obj_t self_in) {
     }
     return mp_const_none;
 }
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(buttons_read_value_obj, buttons_read_value);
+static MP_DEFINE_CONST_FUN_OBJ_1(buttons_read_value_obj, buttons_read_value);
 
-STATIC mp_obj_t buttons_set_pin(mp_obj_t self_in, mp_obj_t pin, mp_obj_t value) {
+static mp_obj_t buttons_set_pin(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);
     if (opencube_try_lock_i2c())
@@ -84,24 +84,24 @@ STATIC mp_obj_t buttons_set_pin(mp_obj_t self_in, mp_obj_t pin, mp_obj_t value)
     }
     return mp_const_none;
 }
-STATIC MP_DEFINE_CONST_FUN_OBJ_3(buttons_set_pin_obj, buttons_set_pin);
+static MP_DEFINE_CONST_FUN_OBJ_3(buttons_set_pin_obj, buttons_set_pin);
 
-STATIC mp_obj_t buttons_turn_off_cube(mp_obj_t self_in) {
+static mp_obj_t buttons_turn_off_cube(mp_obj_t self_in) {
     gpio_put(TURN_OFF_PIN, true);
     return mp_const_none;
 }
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(buttons_turn_off_cube_obj, buttons_turn_off_cube);
+static MP_DEFINE_CONST_FUN_OBJ_1(buttons_turn_off_cube_obj, buttons_turn_off_cube);
 
 
 // This collects all methods and other static class attributes of the buttons.
-STATIC const mp_rom_map_elem_t buttons_locals_dict[] = {
+static const mp_rom_map_elem_t buttons_locals_dict[] = {
     { MP_ROM_QSTR(MP_QSTR_pressed), MP_ROM_PTR(&buttons_pressed_obj) },
     { 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_turn_off_cube), MP_ROM_PTR(&buttons_turn_off_cube_obj) },
 };
-STATIC MP_DEFINE_CONST_DICT(buttons_locals_dict_obj, buttons_locals_dict);
+static MP_DEFINE_CONST_DICT(buttons_locals_dict_obj, buttons_locals_dict);
 
 // This defines the type(buttons) object.
 MP_DEFINE_CONST_OBJ_TYPE(
diff --git a/micropython/modules/opencube_brick/led.c b/micropython/modules/opencube_brick/led.c
index c0fe0b58ec8cc785dea8a2c6dc82d13c1985867f..078f5361bb0beb4045961a77191200c2cdd7d415 100644
--- a/micropython/modules/opencube_brick/led.c
+++ b/micropython/modules/opencube_brick/led.c
@@ -17,7 +17,7 @@ typedef struct _led_obj_t {
 //static void pcf_irq_handler(void);
 
 // Called on led init
-STATIC mp_obj_t led_make_new(const mp_obj_type_t* type, size_t n_args, size_t n_kw, const mp_obj_t* args) {
+static mp_obj_t led_make_new(const mp_obj_type_t* type, size_t n_args, size_t n_kw, const mp_obj_t* args) {
     led_obj_t *self = m_new_obj(led_obj_t);
     self->base.type = type;
     opencube_lock_i2c_or_raise();
@@ -26,44 +26,44 @@ STATIC mp_obj_t led_make_new(const mp_obj_type_t* type, size_t n_args, size_t n_
     return MP_OBJ_FROM_PTR(self);
 }
 
-STATIC void led_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
+static void led_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
   mp_printf(print, "Led");
 }
 
-STATIC mp_obj_t led_on(mp_obj_t self_in) {
+static mp_obj_t led_on(mp_obj_t self_in) {
     opencube_lock_i2c_or_raise();
     PCF8575_write_pin(USER_LED_RPIN, false);
     opencube_unlock_i2c();
     return mp_const_none;
 }
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(led_on_obj, led_on);
+static MP_DEFINE_CONST_FUN_OBJ_1(led_on_obj, led_on);
 
-STATIC mp_obj_t led_off(mp_obj_t self_in) {
+static mp_obj_t led_off(mp_obj_t self_in) {
     opencube_lock_i2c_or_raise();
     PCF8575_write_pin(USER_LED_RPIN, true);
     opencube_unlock_i2c();
     return mp_const_none;
 }
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(led_off_obj, led_off);
+static MP_DEFINE_CONST_FUN_OBJ_1(led_off_obj, led_off);
 
-STATIC mp_obj_t led_toggle(mp_obj_t self_in) {
+static mp_obj_t led_toggle(mp_obj_t self_in) {
     opencube_lock_i2c_or_raise();
     PCF8575_toggle_pin(USER_LED_RPIN);
     opencube_unlock_i2c();
     return mp_const_none;
 }
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(led_toggle_obj, led_toggle);
+static MP_DEFINE_CONST_FUN_OBJ_1(led_toggle_obj, led_toggle);
 
 
 // This collects all methods and other static class attributes of the led.
-STATIC const mp_rom_map_elem_t led_locals_dict[] = {
+static const mp_rom_map_elem_t led_locals_dict[] = {
     { MP_ROM_QSTR(MP_QSTR_on), MP_ROM_PTR(&led_on_obj) },
     { MP_ROM_QSTR(MP_QSTR_off), MP_ROM_PTR(&led_off_obj) },
     { MP_ROM_QSTR(MP_QSTR_toggle), MP_ROM_PTR(&led_toggle_obj) },
     { MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&led_off_obj) },
     { MP_ROM_QSTR(MP_QSTR_close), MP_ROM_PTR(&led_off_obj) },
 };
-STATIC MP_DEFINE_CONST_DICT(led_locals_dict_obj, led_locals_dict);
+static MP_DEFINE_CONST_DICT(led_locals_dict_obj, led_locals_dict);
 
 // This defines the type(led) object.
 MP_DEFINE_CONST_OBJ_TYPE(
diff --git a/micropython/modules/opencube_motors/encoder_api.c b/micropython/modules/opencube_motors/encoder_api.c
index fb73bac79a14455d574431a0f5dcc57f64639252..6ada393b255c72eb1afe66eb2e282e4658aa9740 100644
--- a/micropython/modules/opencube_motors/encoder_api.c
+++ b/micropython/modules/opencube_motors/encoder_api.c
@@ -9,6 +9,8 @@ typedef struct {
   bool reverse;
 } encoder_obj_t;
 
+const mp_obj_type_t opencube_encoder_type;
+
 static mp_obj_t encoder_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
   mp_arg_check_num(n_args, n_kw, 1, 2, false);
 
@@ -18,7 +20,7 @@ static mp_obj_t encoder_make_new(const mp_obj_type_t *type, size_t n_args, size_
   }
 
   opencube_encoders_init(port);
-  encoder_obj_t *self = m_new_obj_with_finaliser(encoder_obj_t);
+  encoder_obj_t *self = mp_obj_malloc_with_finaliser(encoder_obj_t, &opencube_encoder_type);
   self->base.type = type;
   self->port = port;
   self->ref_position = opencube_encoders_get_position(self->port);
diff --git a/micropython/modules/opencube_motors/motor_api.c b/micropython/modules/opencube_motors/motor_api.c
index 2be1e41f6254d10ef70819a6b437ba4b282ea4f1..dfc391de2fe871a702e010022899a80585ca9e0d 100644
--- a/micropython/modules/opencube_motors/motor_api.c
+++ b/micropython/modules/opencube_motors/motor_api.c
@@ -169,7 +169,7 @@ static mp_obj_t motor_finalizer(mp_obj_t self_in) {
     opencube_motor_deinit(self->port);
     return mp_const_none;
 }
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(motor_finalizer_obj, motor_finalizer);
+static MP_DEFINE_CONST_FUN_OBJ_1(motor_finalizer_obj, motor_finalizer);
 
 // This collects all methods and other static class attributes of the Motor.
 static const mp_rom_map_elem_t motor_locals_dict[] = {
diff --git a/micropython/modules/opencube_pindefs/opencube_hw.h b/micropython/modules/opencube_pindefs/opencube_hw.h
index 760a546b71cfeee4fee434936247305841f30d30..b407d3a19341665c409556a00bdb4e4c7680de58 100644
--- a/micropython/modules/opencube_pindefs/opencube_hw.h
+++ b/micropython/modules/opencube_pindefs/opencube_hw.h
@@ -19,8 +19,8 @@
 #define ADS1119_I2C_ADDR     0x40 // 1000000 (A0+A1=GND)
 
 // ==== I2C bus for external sensors ====
-#define UTZ_I2C_SDA_PIN = 16
-#define UTZ_I2C_SCK_PIN = 17
+#define UTZ_I2C_SDA_PIN 16
+#define UTZ_I2C_SCK_PIN 17
 #define UTZ_I2C_BUS i2c0
 #define UTZ_I2C_BAUD_RATE 30000
 #define MULTICUBE_I2C_BAUD_RATE 100000 
diff --git a/micropython/mpy b/micropython/mpy
index 41ed01f1394ea608bf9d055120d671e2765cd9b7..3823aeb0f14c04084eba6566164d9b7dbd9e7ced 160000
--- a/micropython/mpy
+++ b/micropython/mpy
@@ -1 +1 @@
-Subproject commit 41ed01f1394ea608bf9d055120d671e2765cd9b7
+Subproject commit 3823aeb0f14c04084eba6566164d9b7dbd9e7ced