Skip to content

Commit b7b4668

Browse files
committed
extmod/modpupdevices: Add InfraredSensor
Using the raw data, we can get much more information than the 10 distance increments that this sensor normally gives. We provide two convenience methods based on this data: - distance() nonlinearly scales the raw data to provide an approximately linear distance value. It corresponds to the original sensor value, but with higher resolution and a scale from 0-100 to match similar relative distance methods on the other sensors. Resolution is somewhat course above 50%. - reflection() linearly scales the data to provide reflection data close to the sensor. This can be used for line following or precise distance sensing up close. There is also a count() method, which does the same as the original sensor. In this class, the count is reset to 0 upon instantiation. Using the other methods does not reset this count.
1 parent 0665a27 commit b7b4668

File tree

2 files changed

+83
-0
lines changed

2 files changed

+83
-0
lines changed

extmod/modpupdevices.c

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -526,6 +526,81 @@ STATIC const mp_obj_type_t pupdevices_ForceSensor_type = {
526526
.locals_dict = (mp_obj_dict_t *)&pupdevices_ForceSensor_locals_dict,
527527
};
528528

529+
// Class structure for InfraredSensor
530+
typedef struct _pupdevices_InfraredSensor_obj_t {
531+
mp_obj_base_t base;
532+
pbdevice_t *pbdev;
533+
int32_t count_offset;
534+
} pupdevices_InfraredSensor_obj_t;
535+
536+
// pybricks.pupdevices.InfraredSensor._raw
537+
STATIC int32_t pupdevices_InfraredSensor__raw(pbdevice_t *pbdev) {
538+
int32_t raw[3];
539+
pbdevice_get_values(pbdev, PBIO_IODEV_MODE_PUP_WEDO2_MOTION_SENSOR__CAL, raw);
540+
return raw[0];
541+
}
542+
543+
// pybricks.pupdevices.InfraredSensor.__init__
544+
STATIC mp_obj_t pupdevices_InfraredSensor_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
545+
PB_PARSE_ARGS_CLASS(n_args, n_kw, args,
546+
PB_ARG_REQUIRED(port));
547+
548+
pupdevices_InfraredSensor_obj_t *self = m_new_obj(pupdevices_InfraredSensor_obj_t);
549+
self->base.type = (mp_obj_type_t *)type;
550+
551+
mp_int_t port_num = pb_type_enum_get_value(port, &pb_enum_type_Port);
552+
553+
// Get iodevice
554+
self->pbdev = pbdevice_get_device(port_num, PBIO_IODEV_TYPE_ID_WEDO2_MOTION_SENSOR);
555+
556+
// Reset sensor counter and get sensor back in sensing mode
557+
pbdevice_get_values(self->pbdev, PBIO_IODEV_MODE_PUP_WEDO2_MOTION_SENSOR__COUNT, &self->count_offset);
558+
pupdevices_InfraredSensor__raw(self->pbdev);
559+
560+
return MP_OBJ_FROM_PTR(self);
561+
}
562+
563+
// pybricks.pupdevices.InfraredSensor.count
564+
STATIC mp_obj_t pupdevices_InfraredSensor_count(mp_obj_t self_in) {
565+
pupdevices_InfraredSensor_obj_t *self = MP_OBJ_TO_PTR(self_in);
566+
int32_t count;
567+
pbdevice_get_values(self->pbdev, PBIO_IODEV_MODE_PUP_WEDO2_MOTION_SENSOR__COUNT, &count);
568+
return mp_obj_new_int(count - self->count_offset);
569+
}
570+
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pupdevices_InfraredSensor_count_obj, pupdevices_InfraredSensor_count);
571+
572+
// pybricks.pupdevices.InfraredSensor.reflection
573+
STATIC mp_obj_t pupdevices_InfraredSensor_reflection(mp_obj_t self_in) {
574+
pupdevices_InfraredSensor_obj_t *self = MP_OBJ_TO_PTR(self_in);
575+
int32_t raw = pupdevices_InfraredSensor__raw(self->pbdev);
576+
return mp_obj_new_int(raw / 5);
577+
}
578+
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pupdevices_InfraredSensor_reflection_obj, pupdevices_InfraredSensor_reflection);
579+
580+
// pybricks.pupdevices.InfraredSensor.distance
581+
STATIC mp_obj_t pupdevices_InfraredSensor_distance(mp_obj_t self_in) {
582+
pupdevices_InfraredSensor_obj_t *self = MP_OBJ_TO_PTR(self_in);
583+
int32_t raw = pupdevices_InfraredSensor__raw(self->pbdev);
584+
return mp_obj_new_int(1100 / (10 + raw));
585+
}
586+
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pupdevices_InfraredSensor_distance_obj, pupdevices_InfraredSensor_distance);
587+
588+
// dir(pybricks.pupdevices.InfraredSensor)
589+
STATIC const mp_rom_map_elem_t pupdevices_InfraredSensor_locals_dict_table[] = {
590+
{ MP_ROM_QSTR(MP_QSTR_count), MP_ROM_PTR(&pupdevices_InfraredSensor_count_obj) },
591+
{ MP_ROM_QSTR(MP_QSTR_reflection), MP_ROM_PTR(&pupdevices_InfraredSensor_reflection_obj) },
592+
{ MP_ROM_QSTR(MP_QSTR_distance), MP_ROM_PTR(&pupdevices_InfraredSensor_distance_obj) },
593+
};
594+
STATIC MP_DEFINE_CONST_DICT(pupdevices_InfraredSensor_locals_dict, pupdevices_InfraredSensor_locals_dict_table);
595+
596+
// type(pybricks.pupdevices.InfraredSensor)
597+
STATIC const mp_obj_type_t pupdevices_InfraredSensor_type = {
598+
{ &mp_type_type },
599+
.name = MP_QSTR_InfraredSensor,
600+
.make_new = pupdevices_InfraredSensor_make_new,
601+
.locals_dict = (mp_obj_dict_t *)&pupdevices_InfraredSensor_locals_dict,
602+
};
603+
529604
// Class structure for Light
530605
typedef struct _pupdevices_Light_obj_t {
531606
mp_obj_base_t base;
@@ -593,6 +668,7 @@ STATIC const mp_rom_map_elem_t pupdevices_globals_table[] = {
593668
{ MP_ROM_QSTR(MP_QSTR_ColorSensor), MP_ROM_PTR(&pupdevices_ColorSensor_type) },
594669
{ MP_ROM_QSTR(MP_QSTR_UltrasonicSensor), MP_ROM_PTR(&pupdevices_UltrasonicSensor_type) },
595670
{ MP_ROM_QSTR(MP_QSTR_ForceSensor), MP_ROM_PTR(&pupdevices_ForceSensor_type) },
671+
{ MP_ROM_QSTR(MP_QSTR_InfraredSensor), MP_ROM_PTR(&pupdevices_InfraredSensor_type) },
596672
{ MP_ROM_QSTR(MP_QSTR_Light), MP_ROM_PTR(&pupdevices_Light_type) },
597673
};
598674

extmod/pbdevice.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,13 @@ enum {
118118
PBIO_IODEV_MODE_NXT_ENERGY_METER_ALL = 7,
119119
};
120120

121+
// LEGO POWERED UP WEDO 2.0 Infrared "Motion" sensor
122+
enum {
123+
PBIO_IODEV_MODE_PUP_WEDO2_MOTION_SENSOR__DETECT = 0, // read 1x int8_t
124+
PBIO_IODEV_MODE_PUP_WEDO2_MOTION_SENSOR__COUNT = 1, // read 1x int32_t
125+
PBIO_IODEV_MODE_PUP_WEDO2_MOTION_SENSOR__CAL = 2, // read 3x int16_t
126+
};
127+
121128
// LEGO POWERED UP Color and Distance Sensor
122129
enum {
123130
PBIO_IODEV_MODE_PUP_COLOR_DISTANCE_SENSOR__COLOR = 0, // read 1x int8_t

0 commit comments

Comments
 (0)