Fix for hard lock when taking many snapshots

This commit is contained in:
ZodiusInfuser 2022-04-19 15:44:31 +01:00
parent 0bbd07164d
commit 9472a1f109
4 changed files with 45 additions and 32 deletions

View File

@ -19,16 +19,28 @@ uint Encoder::pio_program_offset[] = { 0, 0 };
Encoder::Snapshot::Snapshot()
: count(0), delta(0), frequency(0.0f), counts_per_rev(INT32_MAX) {
: captured_count(0), captured_delta(0), captured_frequency(0.0f), counts_per_rev(INT32_MAX) {
}
Encoder::Snapshot::Snapshot(int32_t count, int32_t delta, float frequency, float counts_per_rev)
: count(count), delta(delta), frequency(frequency)
: captured_count(count), captured_delta(delta), captured_frequency(frequency)
, counts_per_rev(MAX(counts_per_rev, FLT_EPSILON)) { //Clamp counts_per_rev to avoid potential NaN
}
int32_t Encoder::Snapshot::count() const {
return captured_count;
}
int32_t Encoder::Snapshot::delta() const {
return captured_delta;
}
float Encoder::Snapshot::frequency() const {
return captured_frequency;
}
float Encoder::Snapshot::revolutions() const {
return (float)count / counts_per_rev;
return (float)captured_count / counts_per_rev;
}
float Encoder::Snapshot::degrees() const {
@ -40,7 +52,7 @@ float Encoder::Snapshot::radians() const {
}
float Encoder::Snapshot::revolutions_delta() const {
return (float)delta / counts_per_rev;
return (float)captured_delta / counts_per_rev;
}
float Encoder::Snapshot::degrees_delta() const {
@ -52,7 +64,7 @@ float Encoder::Snapshot::radians_delta() const {
}
float Encoder::Snapshot::revolutions_per_second() const {
return frequency / counts_per_rev;
return captured_frequency / counts_per_rev;
}
float Encoder::Snapshot::revolutions_per_minute() const {

View File

@ -71,11 +71,10 @@ namespace pimoroni {
//--------------------------------------------------
// Variables
//--------------------------------------------------
public:
const int32_t count;
const int32_t delta;
const float frequency;
private:
int32_t captured_count;
int32_t captured_delta;
float captured_frequency;
float counts_per_rev;
@ -91,6 +90,10 @@ namespace pimoroni {
// Methods
//--------------------------------------------------
public:
int32_t count() const;
int32_t delta() const;
float frequency() const;
float revolutions() const;
float degrees() const;
float radians() const;

View File

@ -316,14 +316,14 @@ int main() {
{
std::stringstream sstream;
sstream << snapshot.count;
sstream << snapshot.count();
pico_explorer.set_pen(255, 255, 255); pico_explorer.text("Count:", Point(10, 150), 200, 3);
pico_explorer.set_pen(255, 128, 255); pico_explorer.text(sstream.str(), Point(110, 150), 200, 3);
}
{
std::stringstream sstream;
sstream << std::fixed << std::setprecision(1) << snapshot.frequency << "hz";
sstream << std::fixed << std::setprecision(1) << snapshot.frequency() << "hz";
pico_explorer.set_pen(255, 255, 255); pico_explorer.text("Freq: ", Point(10, 180), 220, 3);
pico_explorer.set_pen(128, 255, 255); pico_explorer.text(sstream.str(), Point(90, 180), 220, 3);
}

View File

@ -17,7 +17,7 @@ extern "C" {
/***** Variables Struct *****/
typedef struct _Snapshot_obj_t {
mp_obj_base_t base;
Encoder::Snapshot *snapshot;
Encoder::Snapshot snapshot;
} _Snapshot_obj_t;
@ -25,13 +25,13 @@ typedef struct _Snapshot_obj_t {
void Snapshot_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
(void)kind; //Unused input parameter
_Snapshot_obj_t *self = MP_OBJ_TO_PTR2(self_in, _Snapshot_obj_t);
Encoder::Snapshot* snap = self->snapshot;
Encoder::Snapshot& snap = self->snapshot;
mp_print_str(print, "Snapshot(count = ");
mp_obj_print_helper(print, mp_obj_new_int(snap->count), PRINT_REPR);
mp_obj_print_helper(print, mp_obj_new_int(snap.count()), PRINT_REPR);
mp_print_str(print, ", delta = ");
mp_obj_print_helper(print, mp_obj_new_int(snap->delta), PRINT_REPR);
mp_obj_print_helper(print, mp_obj_new_int(snap.delta()), PRINT_REPR);
mp_print_str(print, ", freq = ");
mp_obj_print_helper(print, mp_obj_new_float(snap->frequency), PRINT_REPR);
mp_obj_print_helper(print, mp_obj_new_float(snap.frequency()), PRINT_REPR);
mp_print_str(print, ")");
}
@ -45,8 +45,6 @@ mp_obj_t Snapshot_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw
/***** Destructor ******/
mp_obj_t Snapshot___del__(mp_obj_t self_in) {
_Snapshot_obj_t *self = MP_OBJ_TO_PTR2(self_in, _Snapshot_obj_t);
delete self->snapshot;
return mp_const_none;
}
@ -54,67 +52,67 @@ mp_obj_t Snapshot___del__(mp_obj_t self_in) {
/***** Methods *****/
mp_obj_t Snapshot_count(mp_obj_t self_in) {
_Snapshot_obj_t *self = MP_OBJ_TO_PTR2(self_in, _Snapshot_obj_t);
return mp_obj_new_int(self->snapshot->count);
return mp_obj_new_int(self->snapshot.count());
}
mp_obj_t Snapshot_delta(mp_obj_t self_in) {
_Snapshot_obj_t *self = MP_OBJ_TO_PTR2(self_in, _Snapshot_obj_t);
return mp_obj_new_int(self->snapshot->delta);
return mp_obj_new_int(self->snapshot.delta());
}
mp_obj_t Snapshot_frequency(mp_obj_t self_in) {
_Snapshot_obj_t *self = MP_OBJ_TO_PTR2(self_in, _Snapshot_obj_t);
return mp_obj_new_float(self->snapshot->frequency);
return mp_obj_new_float(self->snapshot.frequency());
}
mp_obj_t Snapshot_revolutions(mp_obj_t self_in) {
_Snapshot_obj_t *self = MP_OBJ_TO_PTR2(self_in, _Snapshot_obj_t);
return mp_obj_new_int(self->snapshot->revolutions());
return mp_obj_new_int(self->snapshot.revolutions());
}
mp_obj_t Snapshot_degrees(mp_obj_t self_in) {
_Snapshot_obj_t *self = MP_OBJ_TO_PTR2(self_in, _Snapshot_obj_t);
return mp_obj_new_int(self->snapshot->degrees());
return mp_obj_new_int(self->snapshot.degrees());
}
mp_obj_t Snapshot_radians(mp_obj_t self_in) {
_Snapshot_obj_t *self = MP_OBJ_TO_PTR2(self_in, _Snapshot_obj_t);
return mp_obj_new_int(self->snapshot->radians());
return mp_obj_new_int(self->snapshot.radians());
}
mp_obj_t Snapshot_revolutions_delta(mp_obj_t self_in) {
_Snapshot_obj_t *self = MP_OBJ_TO_PTR2(self_in, _Snapshot_obj_t);
return mp_obj_new_int(self->snapshot->revolutions_delta());
return mp_obj_new_int(self->snapshot.revolutions_delta());
}
mp_obj_t Snapshot_degrees_delta(mp_obj_t self_in) {
_Snapshot_obj_t *self = MP_OBJ_TO_PTR2(self_in, _Snapshot_obj_t);
return mp_obj_new_int(self->snapshot->degrees_delta());
return mp_obj_new_int(self->snapshot.degrees_delta());
}
mp_obj_t Snapshot_radians_delta(mp_obj_t self_in) {
_Snapshot_obj_t *self = MP_OBJ_TO_PTR2(self_in, _Snapshot_obj_t);
return mp_obj_new_int(self->snapshot->radians_delta());
return mp_obj_new_int(self->snapshot.radians_delta());
}
mp_obj_t Snapshot_revolutions_per_second(mp_obj_t self_in) {
_Snapshot_obj_t *self = MP_OBJ_TO_PTR2(self_in, _Snapshot_obj_t);
return mp_obj_new_float(self->snapshot->revolutions_per_second());
return mp_obj_new_float(self->snapshot.revolutions_per_second());
}
mp_obj_t Snapshot_revolutions_per_minute(mp_obj_t self_in) {
_Snapshot_obj_t *self = MP_OBJ_TO_PTR2(self_in, _Snapshot_obj_t);
return mp_obj_new_float(self->snapshot->revolutions_per_minute());
return mp_obj_new_float(self->snapshot.revolutions_per_minute());
}
mp_obj_t Snapshot_degrees_per_second(mp_obj_t self_in) {
_Snapshot_obj_t *self = MP_OBJ_TO_PTR2(self_in, _Snapshot_obj_t);
return mp_obj_new_float(self->snapshot->degrees_per_second());
return mp_obj_new_float(self->snapshot.degrees_per_second());
}
mp_obj_t Snapshot_radians_per_second(mp_obj_t self_in) {
_Snapshot_obj_t *self = MP_OBJ_TO_PTR2(self_in, _Snapshot_obj_t);
return mp_obj_new_float(self->snapshot->radians_per_second());
return mp_obj_new_float(self->snapshot.radians_per_second());
}
@ -388,7 +386,7 @@ extern mp_obj_t Encoder_take_snapshot(mp_obj_t self_in) {
_Snapshot_obj_t *snap = m_new_obj_with_finaliser(_Snapshot_obj_t);
snap->base.type = &Snapshot_type;
snap->snapshot = new Encoder::Snapshot(self->encoder->take_snapshot());
snap->snapshot = self->encoder->take_snapshot();
return MP_OBJ_FROM_PTR(snap);
}
}