diff --git a/stmhal/accel.c b/stmhal/accel.c
index cd513b3fe8dbe5d70dea994095c73d80cdf99a9c..b58b7c4db46545d00a232e7d5697b94baa8ab00c 100644
--- a/stmhal/accel.c
+++ b/stmhal/accel.c
@@ -3,6 +3,7 @@
 
 #include <stm32f4xx_hal.h>
 
+#include "nlr.h"
 #include "misc.h"
 #include "mpconfig.h"
 #include "qstr.h"
@@ -99,6 +100,19 @@ typedef struct _pyb_accel_obj_t {
 
 STATIC pyb_accel_obj_t pyb_accel_obj;
 
+STATIC mp_obj_t pyb_accel_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) {
+    // check arguments
+    if (!(n_args == 0 && n_kw == 0)) {
+        nlr_jump(mp_obj_new_exception_msg(&mp_type_ValueError, "Accel accepts no arguments"));
+    }
+
+    // init accel object
+    pyb_accel_obj.base.type = &pyb_accel_type;
+    accel_init_device();
+
+    return &pyb_accel_obj;
+}
+
 STATIC mp_obj_t read_axis(int axis) {
     uint8_t data[1];
     HAL_I2C_Mem_Read(&I2cHandle, MMA_ADDR, axis, I2C_MEMADD_SIZE_8BIT, data, 1, 200);
@@ -171,7 +185,7 @@ STATIC mp_obj_t pyb_accel_write_reg(mp_obj_t self_in, mp_obj_t reg, mp_obj_t val
 
 MP_DEFINE_CONST_FUN_OBJ_3(pyb_accel_write_reg_obj, pyb_accel_write_reg);
 
-STATIC const mp_method_t accel_methods[] = {
+STATIC const mp_method_t pyb_accel_methods[] = {
     { "x", &pyb_accel_x_obj },
     { "y", &pyb_accel_y_obj },
     { "z", &pyb_accel_z_obj },
@@ -182,16 +196,9 @@ STATIC const mp_method_t accel_methods[] = {
     { NULL, NULL },
 };
 
-STATIC const mp_obj_type_t accel_obj_type = {
+const mp_obj_type_t pyb_accel_type = {
     { &mp_type_type },
     .name = MP_QSTR_Accel,
-    .methods = accel_methods,
+    .make_new = pyb_accel_make_new,
+    .methods = pyb_accel_methods,
 };
-
-STATIC mp_obj_t pyb_Accel(void) {
-    pyb_accel_obj.base.type = &accel_obj_type;
-    accel_init_device();
-    return &pyb_accel_obj;
-}
-
-MP_DEFINE_CONST_FUN_OBJ_0(pyb_Accel_obj, pyb_Accel);
diff --git a/stmhal/accel.h b/stmhal/accel.h
index b2c0fd6b19c16bd982657330a777f94326943f1b..88fabfd543e6a6169f82e148be2cbc055d06421d 100644
--- a/stmhal/accel.h
+++ b/stmhal/accel.h
@@ -1,3 +1,3 @@
 void accel_init(void);
 
-MP_DECLARE_CONST_FUN_OBJ(pyb_Accel_obj);
+extern const mp_obj_type_t pyb_accel_type;
diff --git a/stmhal/led.c b/stmhal/led.c
index 102cbac5a7513aae25412c9c15328a61d393abf8..688daefc818b81b29cec76af672fdb5010f28995 100644
--- a/stmhal/led.c
+++ b/stmhal/led.c
@@ -3,6 +3,7 @@
 #include "usbd_cdc_msc.h"
 #include "usbd_cdc_interface.h"
 
+#include "nlr.h"
 #include "misc.h"
 #include "mpconfig.h"
 #include "qstr.h"
@@ -183,14 +184,45 @@ void led_debug(int n, int delay) {
 
 typedef struct _pyb_led_obj_t {
     mp_obj_base_t base;
-    uint led_id;
+    machine_uint_t led_id;
 } pyb_led_obj_t;
 
+STATIC const pyb_led_obj_t pyb_led_obj[NUM_LEDS] = {
+    {{&pyb_led_type}, 1},
+#if defined(PYB_LED2)
+    {{&pyb_led_type}, 2},
+#if defined(PYB_LED3)
+    {{&pyb_led_type}, 3},
+#if defined(PYB_LED4)
+    {{&pyb_led_type}, 4},
+#endif
+#endif
+#endif
+};
+
 void led_obj_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
     pyb_led_obj_t *self = self_in;
     print(env, "<LED %lu>", self->led_id);
 }
 
+STATIC mp_obj_t led_obj_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) {
+    // check arguments
+    if (!(n_args == 1 && n_kw == 0)) {
+        nlr_jump(mp_obj_new_exception_msg(&mp_type_ValueError, "Led accepts 1 argument"));
+    }
+
+    // get led number
+    machine_int_t led_id = mp_obj_get_int(args[0]) - 1;
+
+    // check led number
+    if (!(0 <= led_id && led_id < NUM_LEDS)) {
+        nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "Led %d does not exist", led_id));
+    }
+
+    // return static led object
+    return (mp_obj_t)&pyb_led_obj[led_id];
+}
+
 mp_obj_t led_obj_on(mp_obj_t self_in) {
     pyb_led_obj_t *self = self_in;
     led_state(self->led_id, 1);
@@ -232,18 +264,10 @@ STATIC const mp_method_t led_methods[] = {
     { NULL, NULL },
 };
 
-STATIC const mp_obj_type_t led_obj_type = {
+const mp_obj_type_t pyb_led_type = {
     { &mp_type_type },
     .name = MP_QSTR_Led,
     .print = led_obj_print,
+    .make_new = led_obj_make_new,
     .methods = led_methods,
 };
-
-STATIC mp_obj_t pyb_Led(mp_obj_t led_id) {
-    pyb_led_obj_t *o = m_new_obj(pyb_led_obj_t);
-    o->base.type = &led_obj_type;
-    o->led_id = mp_obj_get_int(led_id);
-    return o;
-}
-
-MP_DEFINE_CONST_FUN_OBJ_1(pyb_Led_obj, pyb_Led);
diff --git a/stmhal/led.h b/stmhal/led.h
index b3762271c1d39f43c4faae4d93dbb4928821627b..ab2b2ea14eff4298c58aa4f9147ea3e11302d72f 100644
--- a/stmhal/led.h
+++ b/stmhal/led.h
@@ -21,4 +21,4 @@ void led_state(pyb_led_t led, int state);
 void led_toggle(pyb_led_t led);
 void led_debug(int value, int delay);
 
-MP_DECLARE_CONST_FUN_OBJ(pyb_Led_obj);
+extern const mp_obj_type_t pyb_led_type;
diff --git a/stmhal/pybmodule.c b/stmhal/pybmodule.c
index 00a8c321db9212fa5f36b9902884625589813ed6..fda6b3d0b374e7a0e82ef2addd6cd3892c3ca23d 100644
--- a/stmhal/pybmodule.c
+++ b/stmhal/pybmodule.c
@@ -242,7 +242,7 @@ STATIC const mp_map_elem_t pyb_module_globals_table[] = {
 #if MICROPY_HW_ENABLE_SERVO
     { MP_OBJ_NEW_QSTR(MP_QSTR_pwm), (mp_obj_t)&pyb_pwm_set_obj },
     { MP_OBJ_NEW_QSTR(MP_QSTR_servo), (mp_obj_t)&pyb_servo_set_obj },
-    { MP_OBJ_NEW_QSTR(MP_QSTR_Servo), (mp_obj_t)&pyb_Servo_obj },
+    { MP_OBJ_NEW_QSTR(MP_QSTR_Servo), (mp_obj_t)&pyb_servo_type },
 #endif
 
 #if MICROPY_HW_HAS_SWITCH
@@ -254,13 +254,13 @@ STATIC const mp_map_elem_t pyb_module_globals_table[] = {
 #endif
 
 #if MICROPY_HW_HAS_MMA7660
-    { MP_OBJ_NEW_QSTR(MP_QSTR_Accel), (mp_obj_t)&pyb_Accel_obj },
+    { MP_OBJ_NEW_QSTR(MP_QSTR_Accel), (mp_obj_t)&pyb_accel_type },
 #endif
 
 #if 0
     { MP_OBJ_NEW_QSTR(MP_QSTR_hid), (mp_obj_t)&pyb_hid_send_report_obj },
 #endif
-    { MP_OBJ_NEW_QSTR(MP_QSTR_Led), (mp_obj_t)&pyb_Led_obj },
+    { MP_OBJ_NEW_QSTR(MP_QSTR_Led), (mp_obj_t)&pyb_led_type },
 #if 0
     { MP_OBJ_NEW_QSTR(MP_QSTR_I2C), (mp_obj_t)&pyb_I2C_obj },
 #endif
diff --git a/stmhal/servo.c b/stmhal/servo.c
index b0e0e8695d0c32605e06e0b1970eeec434281827..81b290bf5261cd032fe2d8eaeb6f5c1049d7901f 100644
--- a/stmhal/servo.c
+++ b/stmhal/servo.c
@@ -148,12 +148,35 @@ STATIC mp_obj_t pyb_pwm_set(mp_obj_t period, mp_obj_t pulse) {
 
 MP_DEFINE_CONST_FUN_OBJ_2(pyb_pwm_set_obj, pyb_pwm_set);
 
-STATIC void servo_obj_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
+STATIC void pyb_servo_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
     pyb_servo_obj_t *self = self_in;
     print(env, "<Servo %lu at %lu>", self->servo_id, self->pulse_cur);
 }
 
-STATIC mp_obj_t servo_obj_angle(uint n_args, const mp_obj_t *args) {
+STATIC mp_obj_t pyb_servo_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) {
+    // check arguments
+    if (!(n_args == 1 && n_kw == 0)) {
+        nlr_jump(mp_obj_new_exception_msg(&mp_type_ValueError, "Servo accepts 1 argument"));
+    }
+
+    // get servo number
+    machine_int_t servo_id = mp_obj_get_int(args[0]) - 1;
+
+    // check servo number
+    if (!(0 <= servo_id && servo_id < PYB_SERVO_NUM)) {
+        nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "Servo %d does not exist", servo_id));
+    }
+
+    // get and init servo object
+    pyb_servo_obj_t *s = &pyb_servo_obj[servo_id];
+    s->pulse_dest = s->pulse_cur;
+    s->time_left = 0;
+    servo_init_channel(s);
+
+    return s;
+}
+
+STATIC mp_obj_t pyb_servo_angle(uint n_args, const mp_obj_t *args) {
     pyb_servo_obj_t *self = args[0];
     if (n_args == 1) {
         // get angle
@@ -180,31 +203,17 @@ STATIC mp_obj_t servo_obj_angle(uint n_args, const mp_obj_t *args) {
     }
 }
 
-STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(servo_obj_angle_obj, 1, 3, servo_obj_angle);
+STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_servo_angle_obj, 1, 3, pyb_servo_angle);
 
-STATIC const mp_method_t servo_methods[] = {
-    { "angle", &servo_obj_angle_obj },
+STATIC const mp_method_t pyb_servo_methods[] = {
+    { "angle", &pyb_servo_angle_obj },
     { NULL, NULL },
 };
 
-STATIC const mp_obj_type_t servo_obj_type = {
+const mp_obj_type_t pyb_servo_type = {
     { &mp_type_type },
     .name = MP_QSTR_Servo,
-    .print = servo_obj_print,
-    .methods = servo_methods,
+    .print = pyb_servo_print,
+    .make_new = pyb_servo_make_new,
+    .methods = pyb_servo_methods,
 };
-
-STATIC mp_obj_t pyb_Servo(mp_obj_t servo_id_o) {
-    machine_int_t servo_id = mp_obj_get_int(servo_id_o) - 1;
-    if (0 <= servo_id && servo_id < PYB_SERVO_NUM) {
-        pyb_servo_obj_t *s = &pyb_servo_obj[servo_id];
-        s->pulse_dest = s->pulse_cur;
-        s->time_left = 0;
-        servo_init_channel(s);
-        return s;
-    } else {
-        nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "Servo %d does not exist", servo_id));
-    }
-}
-
-MP_DEFINE_CONST_FUN_OBJ_1(pyb_Servo_obj, pyb_Servo);
diff --git a/stmhal/servo.h b/stmhal/servo.h
index 753ca495981ea9215f1903a3be6147d8ef37f880..d5fb6a8505df7ff0cd813cb48d907b1ea6ea25aa 100644
--- a/stmhal/servo.h
+++ b/stmhal/servo.h
@@ -3,6 +3,7 @@ extern TIM_HandleTypeDef TIM2_Handle;
 void servo_init(void);
 void servo_timer_irq_callback(void);
 
+extern const mp_obj_type_t pyb_servo_type;
+
 MP_DECLARE_CONST_FUN_OBJ(pyb_servo_set_obj);
 MP_DECLARE_CONST_FUN_OBJ(pyb_pwm_set_obj);
-MP_DECLARE_CONST_FUN_OBJ(pyb_Servo_obj);