implement motor driver
This commit is contained in:
+7
-3
@@ -16,8 +16,12 @@
|
||||
#define FORWARD 1
|
||||
#define BACKWARD 2
|
||||
|
||||
//PWM Configs
|
||||
#define PWM_FREQ 5000
|
||||
//MotorControl config
|
||||
#define PWM_FREQ 16000
|
||||
#define PWM_RES 8
|
||||
#define PWM_CHANNEL_M1 0
|
||||
#define PWM_CHANNEL_M2 1
|
||||
#define PWM_CHANNEL_M2 1
|
||||
#define UPDATE_TIME 25
|
||||
#define SPEED_STEPS 5 // A total of 20 levels ( 100 / SPEED_STEPS ) * UPDATE_TIME = 500ms
|
||||
#define PWM_MIN 40
|
||||
#define PWM_MAX 245 // Max 98% of 2^PWM_RES
|
||||
@@ -0,0 +1,30 @@
|
||||
#ifndef MOTOR_CONTROL_H
|
||||
#define MOTOR_CONTROL_H
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
class MotorControl {
|
||||
public:
|
||||
MotorControl(uint8_t pwm_pin, uint8_t pwm_channel, uint8_t direction_1, uint8_t direction_2);
|
||||
void runMotorControl();
|
||||
void setTargetSpeed(int16_t speed);
|
||||
void stop();
|
||||
void emergencyStop();
|
||||
|
||||
private:
|
||||
void setSpeed(int16_t speed);
|
||||
void accelerate(int8_t acc);
|
||||
|
||||
int16_t target_speed = 0;
|
||||
int16_t speed = 0;
|
||||
uint8_t direction = 0; // 0 = stop, 1 = forward, 2 = backward
|
||||
|
||||
uint64_t last_millis = 0;
|
||||
|
||||
uint8_t pwm_pin;
|
||||
uint8_t pwm_channel;
|
||||
uint8_t direction_pin_1;
|
||||
uint8_t direction_pin_2;
|
||||
};
|
||||
|
||||
#endif // MOTOR_CONTROL_H
|
||||
@@ -0,0 +1,135 @@
|
||||
#include "motorControl.h"
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
#include "config.h"
|
||||
|
||||
MotorControl::MotorControl(uint8_t pwm_pin, uint8_t pwm_channel, uint8_t direction_pin_1, uint8_t direction_pin_2) {
|
||||
this->pwm_pin = pwm_pin;
|
||||
this->pwm_channel = pwm_channel;
|
||||
this->direction_pin_1 = direction_pin_1;
|
||||
this->direction_pin_2 = direction_pin_2;
|
||||
|
||||
pinMode(this->direction_pin_1, OUTPUT);
|
||||
pinMode(this->direction_pin_2, OUTPUT);
|
||||
|
||||
digitalWrite(this->direction_pin_1, LOW);
|
||||
digitalWrite(this->direction_pin_2, LOW);
|
||||
|
||||
ledcSetup(this->pwm_channel, PWM_FREQ, PWM_RES);
|
||||
ledcAttachPin(this->pwm_pin, this->pwm_channel);
|
||||
ledcWrite(this->pwm_channel, 0);
|
||||
}
|
||||
|
||||
void MotorControl::runMotorControl() {
|
||||
uint64_t now_millis = millis();
|
||||
if (now_millis - this->last_millis > UPDATE_TIME) {
|
||||
|
||||
// Absolute difference between target_speed and speed
|
||||
uint8_t abs_difference = abs(this->target_speed - this->speed);
|
||||
|
||||
// Difference between target_speed and speed
|
||||
int16_t difference = this->target_speed - this->speed;
|
||||
|
||||
// Check that the target speed is close to 0 and that the abs_difference is lower than SPEED_STEPS
|
||||
if (abs(this->target_speed) < SPEED_STEPS && abs_difference < SPEED_STEPS) {
|
||||
this->setSpeed(0);
|
||||
return;
|
||||
}
|
||||
|
||||
// Correct speed
|
||||
if (abs_difference < SPEED_STEPS) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Positive or negative tagret speed
|
||||
if (this->target_speed >= 0) {
|
||||
|
||||
// Positive or negative speed
|
||||
if (this->speed >= 0) {
|
||||
if (difference > 0) {
|
||||
this->accelerate(SPEED_STEPS);
|
||||
} else {
|
||||
this->accelerate(-SPEED_STEPS);
|
||||
}
|
||||
} else {
|
||||
this->accelerate(SPEED_STEPS);
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
// Positive or negative speed
|
||||
if (this->speed >= 0) {
|
||||
this->accelerate(-SPEED_STEPS);
|
||||
} else {
|
||||
if (difference > 0) {
|
||||
this->accelerate(SPEED_STEPS);
|
||||
} else {
|
||||
this->accelerate(-SPEED_STEPS);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this->last_millis = millis();
|
||||
}
|
||||
|
||||
void MotorControl::setTargetSpeed(uint8_t speed) {
|
||||
//TODO: Exceptionhandling
|
||||
if (speed <= 100 || speed <= -100) {
|
||||
this->target_speed = speed;
|
||||
} else {
|
||||
Serial.println("Invalid Argument in MotorControl::setTargetSpeed");
|
||||
}
|
||||
}
|
||||
|
||||
void MotorControl::stop() {
|
||||
this->target_speed = 0;
|
||||
}
|
||||
|
||||
void MotorControl::emergencyStop() {
|
||||
setSpeed(0);
|
||||
}
|
||||
|
||||
void MotorControl::setSpeed(int16_t speed) {
|
||||
//TODO: Exceptionhandling
|
||||
if (speed <= 100 || speed <= -100) {
|
||||
this->target_speed = speed;
|
||||
} else {
|
||||
Serial.println("Invalid Argument in MotorControl::setSpeed");
|
||||
}
|
||||
|
||||
if (speed == 0) {
|
||||
this->direction = 0;
|
||||
digitalWrite(this->direction_pin_1, LOW);
|
||||
digitalWrite(this->direction_pin_2, LOW);
|
||||
ledcWrite(this->pwm_channel, 0);
|
||||
this->speed = speed;
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t pwm_val = map(abs(speed), 0, 100, PWM_MIN, PWM_MAX);
|
||||
|
||||
if (this->direction == 1 && speed < 0){ // new direction backward
|
||||
this->direction = 2;
|
||||
digitalWrite(this->direction_pin_1, LOW);
|
||||
digitalWrite(this->direction_pin_2, HIGH);
|
||||
} else if (this->direction == 2 && speed > 0){ // new direction forward
|
||||
this->direction = 1;
|
||||
digitalWrite(this->direction_pin_1, HIGH);
|
||||
digitalWrite(this->direction_pin_2, LOW);
|
||||
}
|
||||
|
||||
ledcWrite(this->pwm_channel, pwm_val);
|
||||
this->speed = speed;
|
||||
}
|
||||
|
||||
void MotorControl::accelerate(int8_t acc) {
|
||||
//TODO: Exceptionhandling
|
||||
if (abs(acc) > 2 * SPEED_STEPS) {
|
||||
Serial.println("Invalid Argument in MotorControl::accelerate");
|
||||
return;
|
||||
}
|
||||
|
||||
this->setSpeed(speed + acc);
|
||||
}
|
||||
Reference in New Issue
Block a user