#include "engine.hpp" #include #include using namespace std; using namespace std::chrono; engine::engine(gpio&& pin_forward, gpio&& pin_reverse) : speed(0), pin_forward(move(pin_forward)), pin_reverse(move(pin_reverse)), stop_thread(false), measurement(string("engine") + to_string(this->pin_forward.get_pin())) { this->pin_forward.set_value(false); this->pin_reverse.set_value(false); pwm_thread = thread(&engine::pwm_loop, this); } engine::~engine() { stop_thread = true; pwm_thread.join(); } void engine::set_speed(int speed) { this->speed.store(speed, memory_order_relaxed); } void engine::pwm_loop() { this_thread::sleep_for(milliseconds(100)); const int sleep_msec = 1; int counter = 0; high_resolution_clock::time_point next_sleep_target = high_resolution_clock::now(); while (!stop_thread) { measurement.start(); direction target_direction; int speed_val = speed.load(memory_order_relaxed); if (speed_val < 0) { target_direction = direction::REVERSE; speed_val *= -1; } else { target_direction = direction::FORWARD; } counter += sleep_msec; if (counter >= 100) counter = 0; if (counter < speed_val) { if (target_direction == direction::FORWARD) { pin_reverse.set_value(false); pin_forward.set_value(true); } else { pin_forward.set_value(false); pin_reverse.set_value(true); } } else { pin_forward.set_value(false); pin_reverse.set_value(false); } measurement.stop(); next_sleep_target += 500us; this_thread::sleep_until(next_sleep_target); } pin_forward.set_value(false); pin_reverse.set_value(false); }