2018-12-22 20:57:28 -08:00
|
|
|
/**
|
2018-12-23 18:10:30 -08:00
|
|
|
* @file DcMotor.cpp
|
|
|
|
* @brief DC motor controller
|
|
|
|
*
|
|
|
|
* @date Dec 22, 2018
|
|
|
|
* @author Matthew Kennedy
|
2018-12-22 20:57:28 -08:00
|
|
|
*/
|
2018-12-23 18:10:30 -08:00
|
|
|
|
2019-03-29 06:11:13 -07:00
|
|
|
#include "dc_motor.h"
|
2020-04-10 14:27:13 -07:00
|
|
|
#include "efi_gpio.h"
|
2019-11-22 13:30:44 -08:00
|
|
|
#include "pwm_generator_logic.h"
|
2018-12-22 20:57:28 -08:00
|
|
|
|
2021-06-26 18:42:40 -07:00
|
|
|
TwoPinDcMotor::TwoPinDcMotor(OutputPin& disablePin)
|
|
|
|
: m_disable(&disablePin)
|
2018-12-22 20:57:28 -08:00
|
|
|
{
|
2020-04-10 14:27:13 -07:00
|
|
|
disable();
|
|
|
|
}
|
|
|
|
|
2021-06-26 18:42:40 -07:00
|
|
|
void TwoPinDcMotor::configure(IPwm& enable, IPwm& dir1, IPwm& dir2) {
|
|
|
|
m_enable = &enable;
|
|
|
|
m_dir1 = &dir1;
|
|
|
|
m_dir2 = &dir2;
|
|
|
|
}
|
|
|
|
|
2020-04-10 14:27:13 -07:00
|
|
|
void TwoPinDcMotor::enable() {
|
|
|
|
if (m_disable) {
|
|
|
|
m_disable->setValue(false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void TwoPinDcMotor::disable() {
|
|
|
|
if (m_disable) {
|
|
|
|
m_disable->setValue(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Also set the duty to zero
|
|
|
|
set(0);
|
2018-12-22 20:57:28 -08:00
|
|
|
}
|
|
|
|
|
2019-06-08 06:51:36 -07:00
|
|
|
bool TwoPinDcMotor::isOpenDirection() const {
|
2019-05-04 21:42:50 -07:00
|
|
|
return m_value >= 0;
|
2019-03-01 20:09:33 -08:00
|
|
|
}
|
|
|
|
|
2019-11-22 13:30:44 -08:00
|
|
|
float TwoPinDcMotor::get() const {
|
2019-05-04 21:42:50 -07:00
|
|
|
return m_value;
|
2019-03-09 20:31:47 -08:00
|
|
|
}
|
|
|
|
|
2019-02-10 16:13:04 -08:00
|
|
|
/**
|
|
|
|
* @param duty value between -1.0 and 1.0
|
|
|
|
*/
|
2019-11-22 13:30:44 -08:00
|
|
|
bool TwoPinDcMotor::set(float duty)
|
2018-12-22 20:57:28 -08:00
|
|
|
{
|
2019-05-04 21:42:50 -07:00
|
|
|
m_value = duty;
|
|
|
|
|
2021-06-26 18:42:40 -07:00
|
|
|
// If not init, don't try to set
|
|
|
|
if (!m_dir1 || !m_dir2 || !m_enable) {
|
|
|
|
if (m_disable) {
|
|
|
|
m_disable->setValue(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool isPositive = duty > 0;
|
2018-12-22 20:57:28 -08:00
|
|
|
|
2021-06-26 18:42:40 -07:00
|
|
|
if (!isPositive) {
|
|
|
|
duty = -duty;
|
|
|
|
}
|
2019-05-04 21:42:50 -07:00
|
|
|
|
2021-06-26 18:42:40 -07:00
|
|
|
// below here 'duty' is a not negative
|
2018-12-22 20:57:28 -08:00
|
|
|
|
2021-06-26 18:42:40 -07:00
|
|
|
// Clamp to 100%
|
|
|
|
if (duty > 1.0f) {
|
|
|
|
duty = 1.0f;
|
|
|
|
}
|
|
|
|
// Disable for very small duty
|
|
|
|
else if (duty < 0.01f)
|
|
|
|
{
|
|
|
|
duty = 0.0f;
|
|
|
|
}
|
2018-12-22 20:57:28 -08:00
|
|
|
|
2021-06-26 18:42:40 -07:00
|
|
|
// If we're in two pin mode, force 100%, else use this pin to PWM
|
|
|
|
float enableDuty = m_type == ControlType::PwmEnablePin ? duty : 1;
|
2019-04-12 22:03:12 -07:00
|
|
|
|
2021-06-26 18:42:40 -07:00
|
|
|
// Direction pins get 100% duty unless we're in PwmDirectionPins mode
|
|
|
|
float dirDuty = m_type == ControlType::PwmDirectionPins ? duty : 1;
|
2018-12-22 20:57:28 -08:00
|
|
|
|
2021-06-26 18:42:40 -07:00
|
|
|
m_enable->setSimplePwmDutyCycle(enableDuty);
|
|
|
|
m_dir1->setSimplePwmDutyCycle(isPositive ? dirDuty : 0);
|
|
|
|
m_dir2->setSimplePwmDutyCycle(isPositive ? 0 : dirDuty);
|
2018-12-23 18:10:30 -08:00
|
|
|
|
2021-06-26 18:42:40 -07:00
|
|
|
// This motor has no fault detection, so always return false (indicate success).
|
|
|
|
return false;
|
2018-12-22 20:57:28 -08:00
|
|
|
}
|