Skip to content

Commit 71bd61d

Browse files
committed
pybricks.nxtdevices: Add EnergyMeter.
1 parent aae6462 commit 71bd61d

File tree

4 files changed

+49
-38
lines changed

4 files changed

+49
-38
lines changed

lib/pbio/src/port_dcm_ev3.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ typedef enum {
9191
*/
9292
DCM_CATEGORY_NXT_I2C = PIN_STATE_ADC1_4800_to_5000 | PIN_STATE_P5_HIGH | PIN_STATE_MASK_P6,
9393
/**
94-
* Device is NXT Temperature sensor (special case of I2C).
94+
* Device is NXT Temperature sensor or Energy Meter (special case of I2C).
9595
*/
9696
DCM_CATEGORY_NXT_TEMPERATURE = DCM_CATEGORY_NXT_I2C | PIN_STATE_P2_HIGH,
9797
/**

pybricks/nxtdevices/nxtdevices.h

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,8 @@ extern const mp_obj_type_t pb_type_nxtdevices_ColorSensor;
1616
extern const mp_obj_type_t pb_type_nxtdevices_UltrasonicSensor;
1717
extern const mp_obj_type_t pb_type_nxtdevices_TemperatureSensor;
1818
extern const mp_obj_type_t pb_type_nxtdevices_SoundSensor;
19-
20-
#if PYBRICKS_PY_EV3DEVDEVICES
21-
2219
extern const mp_obj_type_t pb_type_nxtdevices_EnergyMeter;
2320

24-
int32_t analog_scale(int32_t mvolts, int32_t mvolts_min, int32_t mvolts_max, bool invert);
25-
26-
#endif // PYBRICKS_PY_EV3DEVDEVICES
27-
2821
#endif // PYBRICKS_PY_NXTDEVICES
2922

3023
#endif // PYBRICKS_INCLUDED_PYBRICKS_NXTDEVICES_H

pybricks/nxtdevices/pb_module_nxtdevices.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,7 @@ static const mp_rom_map_elem_t nxtdevices_globals_table[] = {
1919
{ MP_ROM_QSTR(MP_QSTR_UltrasonicSensor), MP_ROM_PTR(&pb_type_nxtdevices_UltrasonicSensor) },
2020
{ MP_ROM_QSTR(MP_QSTR_TemperatureSensor), MP_ROM_PTR(&pb_type_nxtdevices_TemperatureSensor)},
2121
{ MP_ROM_QSTR(MP_QSTR_SoundSensor), MP_ROM_PTR(&pb_type_nxtdevices_SoundSensor) },
22-
#if PYBRICKS_PY_EV3DEVDEVICES
2322
{ MP_ROM_QSTR(MP_QSTR_EnergyMeter), MP_ROM_PTR(&pb_type_nxtdevices_EnergyMeter) },
24-
#endif
2523
};
2624
static MP_DEFINE_CONST_DICT(pb_module_nxtdevices_globals, nxtdevices_globals_table);
2725

Lines changed: 48 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,28 @@
11
// SPDX-License-Identifier: MIT
2-
// Copyright (c) 2018-2023 The Pybricks Authors
2+
// Copyright (c) 2018-2025 The Pybricks Authors
33

44
#include "py/mpconfig.h"
55

6-
#if PYBRICKS_PY_NXTDEVICES && PYBRICKS_PY_EV3DEVDEVICES
6+
#if PYBRICKS_PY_NXTDEVICES
7+
8+
#include "py/mphal.h"
9+
10+
#include <pbdrv/i2c.h>
11+
#include <pbio/port_interface.h>
12+
#include <pbio/util.h>
713

814
#include <pybricks/common.h>
9-
#include <pybricks/nxtdevices.h>
15+
#include <pybricks/iodevices/iodevices.h>
1016
#include <pybricks/parameters.h>
1117

1218
#include <pybricks/util_mp/pb_kwarg_helper.h>
1319
#include <pybricks/util_mp/pb_obj_helper.h>
14-
#include <pybricks/common/pb_type_device.h>
20+
#include <pybricks/util_pb/pb_error.h>
21+
1522
// pybricks.nxtdevices.EnergyMeter class object
1623
typedef struct _nxtdevices_EnergyMeter_obj_t {
17-
pb_type_device_obj_base_t device_base;
24+
mp_obj_base_t base;
25+
mp_obj_t i2c_device_obj;
1826
} nxtdevices_EnergyMeter_obj_t;
1927

2028
// pybricks.nxtdevices.EnergyMeter.__init__
@@ -23,44 +31,56 @@ static mp_obj_t nxtdevices_EnergyMeter_make_new(const mp_obj_type_t *type, size_
2331
PB_ARG_REQUIRED(port));
2432

2533
nxtdevices_EnergyMeter_obj_t *self = mp_obj_malloc(nxtdevices_EnergyMeter_obj_t, type);
26-
pb_type_device_init_class(&self->device_base, port_in, LEGO_DEVICE_TYPE_ID_NXT_ENERGY_METER);
27-
28-
// Read once so we are in the mode we'll be using for all methods, to avoid mode switch delays later
29-
pb_type_device_get_data_blocking(MP_OBJ_FROM_PTR(self), LEGO_DEVICE_MODE_NXT_ENERGY_METER_ALL);
34+
self->i2c_device_obj = pb_type_i2c_device_make_new(MP_OBJ_FROM_PTR(self), port_in, 0x02, true, false, false);
3035

3136
return MP_OBJ_FROM_PTR(self);
3237
}
3338

34-
// pybricks.nxtdevices.EnergyMeter.storage
35-
static mp_obj_t nxtdevices_EnergyMeter_storage(mp_obj_t self_in) {
36-
int32_t *all = pb_type_device_get_data_blocking(self_in, LEGO_DEVICE_MODE_NXT_ENERGY_METER_ALL);
37-
return mp_obj_new_int(all[4]);
39+
static mp_obj_t nxtdevices_EnergyMeter_read_all(mp_obj_t self_in, pb_type_i2c_device_return_map_t return_map) {
40+
nxtdevices_EnergyMeter_obj_t *self = MP_OBJ_TO_PTR(self_in);
41+
const uint8_t reg_data[] = { 0x0A };
42+
return pb_type_i2c_device_start_operation(self->i2c_device_obj, reg_data, MP_ARRAY_SIZE(reg_data), 14, return_map);
3843
}
39-
static MP_DEFINE_CONST_FUN_OBJ_1(nxtdevices_EnergyMeter_storage_obj, nxtdevices_EnergyMeter_storage);
4044

4145
// pybricks.nxtdevices.EnergyMeter.input
42-
static mp_obj_t nxtdevices_EnergyMeter_input(mp_obj_t self_in) {
43-
int32_t *all = pb_type_device_get_data_blocking(self_in, LEGO_DEVICE_MODE_NXT_ENERGY_METER_ALL);
46+
static mp_obj_t map_input(mp_obj_t self_in, const uint8_t *all, size_t len) {
4447
mp_obj_t dat[3];
45-
dat[0] = mp_obj_new_int(all[0]);
46-
dat[1] = mp_obj_new_int(all[1]);
47-
dat[2] = mp_obj_new_int(all[5]);
48-
return mp_obj_new_tuple(3, dat);
48+
dat[0] = mp_obj_new_int((int16_t)pbio_get_uint16_le(&all[0]));
49+
dat[1] = mp_obj_new_int((int16_t)pbio_get_uint16_le(&all[2]));
50+
dat[2] = mp_obj_new_int((int16_t)pbio_get_uint16_le(&all[10]));
51+
return mp_obj_new_tuple(MP_ARRAY_SIZE(dat), dat);
52+
}
53+
54+
static mp_obj_t nxtdevices_EnergyMeter_input(mp_obj_t self_in) {
55+
return nxtdevices_EnergyMeter_read_all(self_in, map_input);
4956
}
5057
static MP_DEFINE_CONST_FUN_OBJ_1(nxtdevices_EnergyMeter_input_obj, nxtdevices_EnergyMeter_input);
5158

59+
// pybricks.nxtdevices.EnergyMeter.storage
60+
static mp_obj_t map_storage(mp_obj_t self_in, const uint8_t *all, size_t len) {
61+
return mp_obj_new_int((int16_t)pbio_get_uint16_le(&all[8]));
62+
}
63+
64+
static mp_obj_t nxtdevices_EnergyMeter_storage(mp_obj_t self_in) {
65+
return nxtdevices_EnergyMeter_read_all(self_in, map_storage);
66+
}
67+
static MP_DEFINE_CONST_FUN_OBJ_1(nxtdevices_EnergyMeter_storage_obj, nxtdevices_EnergyMeter_storage);
68+
5269
// pybricks.nxtdevices.EnergyMeter.output
53-
static mp_obj_t nxtdevices_EnergyMeter_output(mp_obj_t self_in) {
54-
int32_t *all = pb_type_device_get_data_blocking(self_in, LEGO_DEVICE_MODE_NXT_ENERGY_METER_ALL);
70+
static mp_obj_t map_output(mp_obj_t self_in, const uint8_t *all, size_t len) {
5571
mp_obj_t dat[3];
56-
dat[0] = mp_obj_new_int(all[2]);
57-
dat[1] = mp_obj_new_int(all[3]);
58-
dat[2] = mp_obj_new_int(all[6]);
59-
return mp_obj_new_tuple(3, dat);
72+
dat[0] = mp_obj_new_int((int16_t)pbio_get_uint16_le(&all[4]));
73+
dat[1] = mp_obj_new_int((int16_t)pbio_get_uint16_le(&all[6]));
74+
dat[2] = mp_obj_new_int((int16_t)pbio_get_uint16_le(&all[12]));
75+
return mp_obj_new_tuple(MP_ARRAY_SIZE(dat), dat);
76+
}
77+
78+
static mp_obj_t nxtdevices_EnergyMeter_output(mp_obj_t self_in) {
79+
return nxtdevices_EnergyMeter_read_all(self_in, map_output);
6080
}
6181
static MP_DEFINE_CONST_FUN_OBJ_1(nxtdevices_EnergyMeter_output_obj, nxtdevices_EnergyMeter_output);
6282

63-
// dir(pybricks.ev3devices.EnergyMeter)
83+
// dir(pybricks.nxtdevices.EnergyMeter)
6484
static const mp_rom_map_elem_t nxtdevices_EnergyMeter_locals_dict_table[] = {
6585
{ MP_ROM_QSTR(MP_QSTR_input), MP_ROM_PTR(&nxtdevices_EnergyMeter_input_obj) },
6686
{ MP_ROM_QSTR(MP_QSTR_output), MP_ROM_PTR(&nxtdevices_EnergyMeter_output_obj) },
@@ -76,4 +96,4 @@ MP_DEFINE_CONST_OBJ_TYPE(pb_type_nxtdevices_EnergyMeter,
7696
locals_dict, &nxtdevices_EnergyMeter_locals_dict);
7797

7898

79-
#endif // PYBRICKS_PY_NXTDEVICES && PYBRICKS_PY_EV3DEVDEVICES
99+
#endif // PYBRICKS_PY_NXTDEVICES

0 commit comments

Comments
 (0)