Encoder fyrir position í int32, stöðuvél án null-pointera, nefndir fastar, LED gegnum context

This commit is contained in:
2026-09-30 11:55:41 +00:00
parent c46539a57b
commit 1e02205344
8 changed files with 91 additions and 99 deletions
+17 -10
View File
@@ -4,6 +4,7 @@
#include "rotary_encoder_driver.h" #include "rotary_encoder_driver.h"
#include "motor_driver.h" #include "motor_driver.h"
#include "p_controller.h" #include "p_controller.h"
#include "digital_out.h"
class State; class State;
@@ -11,15 +12,21 @@ class State;
class MotorController class MotorController
{ {
private: private:
static constexpr double DEFAULT_REFERENCE_RPM = 40.0;
static constexpr double PWM_PER_PERCENT = 255.0 / 100.0;
static const uint8_t LED_PIN = 5; // PB5 = D13 = LED_BUILTIN
State* current_state; State* current_state;
State* initialization_state; State& initialization_state;
State* operational_state; State& operational_state;
RotaryEncoderDriver& encoder; RotaryEncoderDriver& encoder;
MotorDriver& motor; MotorDriver& motor;
P_controller& controller; P_controller& controller;
Digital_out led;
double reference_rpm; double reference_rpm;
@@ -27,13 +34,9 @@ public:
MotorController( MotorController(
RotaryEncoderDriver& encoder, RotaryEncoderDriver& encoder,
MotorDriver& motor, MotorDriver& motor,
P_controller& controller P_controller& controller,
); State& initialization,
State& operational
void set_states(
State* initialization,
State* operational
); );
@@ -43,7 +46,7 @@ public:
void command(char c); void command(char c);
void transition_to(State* new_state); void transition_to(State& new_state);
void to_initialization(); void to_initialization();
@@ -56,6 +59,10 @@ public:
void stop_motor(); void stop_motor();
void reset_speed_measurement(); void reset_speed_measurement();
void led_on();
void led_off();
}; };
#endif #endif
+10 -11
View File
@@ -4,37 +4,36 @@
#include <stdint.h> #include <stdint.h>
#include "digital_in.h" #include "digital_in.h"
//#include "digital_out.h"
#include "timer_usec.h" #include "timer_usec.h"
class RotaryEncoderDriver { class RotaryEncoderDriver {
static const uint8_t HIST_LEN = 4; // 4 x 4 ms = 16 ms gluggi fyrir rpm-utreikning public:
static constexpr uint16_t SAMPLE_PERIOD_US = 4000; // Ts = 4 ms
static constexpr float COUNTS_PER_REV = 1050.0f;
volatile uint8_t cycle; private:
volatile int16_t count; static const uint8_t HIST_LEN = 4; // 4 x Ts = 16 ms gluggi fyrir rpm-utreikning
volatile int16_t prev_count;
volatile int32_t count;
volatile int16_t delta;
volatile bool speed_ready; volatile bool speed_ready;
volatile int16_t history[HIST_LEN]; volatile int32_t history[HIST_LEN];
volatile uint8_t hist_idx; volatile uint8_t hist_idx;
//Digital_out led;
Digital_in eA; Digital_in eA;
Digital_in eB; Digital_in eB;
Timer_usec timer; Timer_usec timer;
public: public:
volatile int16_t delta;
RotaryEncoderDriver(); RotaryEncoderDriver();
void begin(); void begin();
void update(); void update();
int position(); int32_t position();
void update_delta(); void update_delta();
+1 -1
View File
@@ -6,7 +6,7 @@ class MotorController;
class State class State
{ {
protected: protected:
MotorController* context; MotorController* context = nullptr;
public: public:
virtual ~State() virtual ~State()
+1 -1
View File
@@ -9,7 +9,7 @@ void InitializationState::enter()
Serial.println(); Serial.println();
Serial.println("State: Initialization"); Serial.println("State: Initialization");
digitalWrite(LED_BUILTIN, LOW); context->led_off();
context->stop_motor(); context->stop_motor();
+12 -18
View File
@@ -15,14 +15,9 @@ RotaryEncoderDriver encoder;
MotorDriver motor; MotorDriver motor;
P_controller controller(12.5); const double KP = 12.5;
P_controller controller(KP);
MotorController motor_controller(
encoder,
motor,
controller
);
InitializationState initialization_state; InitializationState initialization_state;
@@ -30,6 +25,16 @@ InitializationState initialization_state;
OperationalState operational_state; OperationalState operational_state;
// Stöðurnar verða að vera skilgreindar á undan motor_controller
MotorController motor_controller(
encoder,
motor,
controller,
initialization_state,
operational_state
);
int main() int main()
{ {
init(); init();
@@ -37,11 +42,6 @@ int main()
Serial.begin(115200); Serial.begin(115200);
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, LOW);
cli(); cli();
encoder.begin(); encoder.begin();
@@ -51,12 +51,6 @@ int main()
sei(); sei();
motor_controller.set_states(
&initialization_state,
&operational_state
);
motor_controller.begin(); motor_controller.begin();
+27 -19
View File
@@ -7,45 +7,41 @@
MotorController::MotorController( MotorController::MotorController(
RotaryEncoderDriver& encoder, RotaryEncoderDriver& encoder,
MotorDriver& motor, MotorDriver& motor,
P_controller& controller P_controller& controller,
State& initialization,
State& operational
) )
: current_state(nullptr), : current_state(nullptr),
initialization_state(nullptr), initialization_state(initialization),
operational_state(nullptr), operational_state(operational),
encoder(encoder), encoder(encoder),
motor(motor), motor(motor),
controller(controller), controller(controller),
reference_rpm(40.0) led(LED_PIN),
reference_rpm(DEFAULT_REFERENCE_RPM)
{ {
} initialization_state.set_context(this);
operational_state.set_context(this);
void MotorController::set_states(
State* initialization,
State* operational
)
{
initialization_state = initialization;
operational_state = operational;
} }
void MotorController::begin() void MotorController::begin()
{ {
led.init();
led.set_lo();
transition_to(initialization_state); transition_to(initialization_state);
} }
void MotorController::transition_to(State* new_state) void MotorController::transition_to(State& new_state)
{ {
if (current_state != nullptr) if (current_state != nullptr)
{ {
current_state->exit(); current_state->exit();
} }
current_state = new_state; current_state = &new_state;
current_state->set_context(this);
current_state->enter(); current_state->enter();
} }
@@ -91,7 +87,7 @@ void MotorController::run_speed_controller()
controller.update(reference_rpm, actual); controller.update(reference_rpm, actual);
double pwm = double pwm =
pwm_percent * 2.55; pwm_percent * PWM_PER_PERCENT;
motor.set(pwm); motor.set(pwm);
} }
@@ -108,3 +104,15 @@ void MotorController::reset_speed_measurement()
{ {
encoder.reset_speed_measurement(); encoder.reset_speed_measurement();
} }
void MotorController::led_on()
{
led.set_hi();
}
void MotorController::led_off()
{
led.set_lo();
}
+2 -2
View File
@@ -8,7 +8,7 @@ void OperationalState::enter()
{ {
Serial.println("State: Operational"); Serial.println("State: Operational");
digitalWrite(LED_BUILTIN, HIGH); context->led_on();
} }
@@ -33,5 +33,5 @@ void OperationalState::exit()
{ {
context->stop_motor(); context->stop_motor();
digitalWrite(LED_BUILTIN, LOW); context->led_off();
} }
+9 -25
View File
@@ -1,17 +1,15 @@
#include "rotary_encoder_driver.h" #include "rotary_encoder_driver.h"
#include <avr/interrupt.h> #include <avr/interrupt.h>
RotaryEncoderDriver* driver = nullptr; static RotaryEncoderDriver* driver = nullptr;
RotaryEncoderDriver::RotaryEncoderDriver() RotaryEncoderDriver::RotaryEncoderDriver()
: cycle(0) : count(0)
, count(0) , delta(0)
, prev_count(0)
, speed_ready(false) , speed_ready(false)
, hist_idx(0) , hist_idx(0)
, eA(2) , eA(2)
, eB(5) , eB(5)
, delta(0)
{ {
for (uint8_t i = 0; i < HIST_LEN; i++) for (uint8_t i = 0; i < HIST_LEN; i++)
{ {
@@ -24,54 +22,46 @@ void RotaryEncoderDriver::begin()
{ {
driver = this; driver = this;
//led.init();
eA.init(); eA.init();
eB.init(); eB.init();
EICRA |= (1<<ISC01) | (1<<ISC00); EICRA |= (1<<ISC01) | (1<<ISC00);
EIMSK |= (1<<INT0); EIMSK |= (1<<INT0);
timer.init(4000); timer.init(SAMPLE_PERIOD_US);
} }
void RotaryEncoderDriver::update() void RotaryEncoderDriver::update()
{ {
count += eB.is_hi() ? 1 : -1; count += eB.is_hi() ? 1 : -1;
//led.set_hi();
} }
int RotaryEncoderDriver::position() int32_t RotaryEncoderDriver::position()
{ {
uint8_t oldSREG = SREG; uint8_t oldSREG = SREG;
cli(); cli();
int16_t local_count = count; int32_t local_count = count;
SREG = oldSREG; SREG = oldSREG;
//led.set_lo();
return local_count; return local_count;
} }
void RotaryEncoderDriver::update_delta() void RotaryEncoderDriver::update_delta()
{ {
int16_t oldest = history[hist_idx]; int32_t oldest = history[hist_idx];
history[hist_idx] = count; history[hist_idx] = count;
hist_idx = (hist_idx + 1) % HIST_LEN; hist_idx = (hist_idx + 1) % HIST_LEN;
delta = count - oldest; // breyting yfir HIST_LEN * Ts (16 ms) glugga delta = (int16_t)(count - oldest); // breyting yfir HIST_LEN * Ts (16 ms) glugga
prev_count = count;
speed_ready = true; speed_ready = true;
//led.set_lo();
} }
float RotaryEncoderDriver::count_per_sec() float RotaryEncoderDriver::count_per_sec()
@@ -85,14 +75,12 @@ float RotaryEncoderDriver::count_per_sec()
SREG = oldSREG; SREG = oldSREG;
return local_delta / (HIST_LEN * 0.004f); return local_delta / (HIST_LEN * SAMPLE_PERIOD_US * 1e-6f);
} }
float RotaryEncoderDriver::rpm() float RotaryEncoderDriver::rpm()
{ {
const float COUNTS_PER_REV = 1050.0f;
return count_per_sec() * 60.0f / COUNTS_PER_REV; return count_per_sec() * 60.0f / COUNTS_PER_REV;
} }
@@ -121,8 +109,6 @@ void RotaryEncoderDriver::reset_speed_measurement()
cli(); cli();
cycle = 0;
prev_count = count;
delta = 0; delta = 0;
speed_ready = false; speed_ready = false;
@@ -144,5 +130,3 @@ ISR(TIMER1_COMPA_vect)
{ {
driver->update_delta(); driver->update_delta();
} }