-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmot.cpp
123 lines (110 loc) · 4 KB
/
mot.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
//Provides DC motor speed and direction control
#include "mot.h"
//Public methods
Mot::Mot(int type, float alpha, int gain, int pin1, int pin2): fil(alpha) {
//Constructor
_type = type;
_gain = gain;
_pin1 = pin1;
_pin2 = pin2;
pinMode(_pin1, OUTPUT);
pinMode(_pin2, OUTPUT);
}
void Mot::halt() {
drive(0.0);
}
void Mot::drive(float err) {
switch (_type) {
case PWMDIR:
_pwmdir(err);
break;
case FWDREV:
_fwdrev(err);
break;
case ACMOTR:
_acmotr(err);
break;
}
}
void Mot::_fwdrev(float err) {
//Drive the motors to reduce the antenna pointing errors to zero
//Calculate the motor speed: A linear ramp close to zero; constant full speed beyond that.
float spd = constrain(err * _gain, -255, 255);
//Low pass filter the speed to reduce abrubt changes in speed
spd = fil.lpf(spd);
//For L298N DC Motor H-Bridge Driver Boards
//Set the motor speed
if (abs(err) < 0.5) {
analogWrite(_pin1, 0);
analogWrite(_pin2, 0);
} else {
if (spd > 0) {
analogWrite(_pin1, (byte)(spd));
analogWrite(_pin2, 0);
} else {
analogWrite(_pin1, 0);
analogWrite(_pin2, (byte)(-spd));
}
}
}
void Mot::_pwmdir(float err) {
//Drive the motors to reduce the antenna pointing errors to zero
//Calculate the motor speed: A linear ramp close to zero; constant full speed beyond that.
float spd = constrain(err * _gain, -255, 255);
//Low pass filter the speed to reduce abrubt changes in speed
spd = fil.lpf(spd);
//For LMD18200T DC Motor H-Bridge Driver Boards
//Set the motor speed
if (abs(err) < 0.5) {
analogWrite(_pin1, 0); //Disengage motor drive when the error is small to reduce dither, noise and current consumption
} else {
analogWrite(_pin1, (byte)(abs(spd))); //Drive the motor
}
//Set the motor direction
digitalWrite(_pin2, (spd > 0) ? HIGH : LOW);
}
void Mot::_acmotr(float err) {
//AC Motor Driver
//Reduce the antenna pointing error in degrees (err) to the minimum error (minErr)
//by driving the motor at full speed until the maximum error (maxErr) point is reached.
//Then start PWM by pulsing the motor on and off for the on time (onTime)
//followed by the off time (offTime) until the maximum off time (maxOffTime) is reached.
//Stop driving the motor when the antenna pointing error is less than the minimum error.
//Constants
const int onTime = 20; //Set the on pulse time in milliseconds
const int minErr = 1; //Set the minimum error to start driving
const int maxOffTime = 100; //Set the maximum off time in milliseconds
const int maxErr = 20; //Set the maximum error to engage full speed
//Variables
unsigned long offTime;
//Low pass filter the error to reduce abrubt changes in speed
err = fil.lpf(err);
float absErr = abs(err); //Get the absolute magnitude of the error
if (absErr >= minErr) { //Check if the error is above the minimum
//If it is prepare to generate the PWM signals
if (absErr > maxErr) { //Check if the error is above the maximum
offTime = 0; //If it is prepare to drive the motor at full speed
} else {
offTime = float(maxOffTime) * (float(maxErr) - absErr) / float(maxErr); //Compute the off time in milliseconds
}
unsigned long thisTime = millis(); //Get the current time in milliseconds
if (thisTime > (lastTime + onTime)) {
//The drive pulse has completed, so set all the drive outputs low.
digitalWrite(_pin1, LOW);
digitalWrite(_pin2, LOW);
}
if (thisTime > (lastTime + onTime + offTime)) {
//The PWM cycle is now complete. Start another drive pulse.
if (err <= 0) {
digitalWrite(_pin2, HIGH); //If the error is negative drive the CW pin
} else {
digitalWrite(_pin1, HIGH); //If the error is positive drive the CCW pin
}
lastTime = thisTime; //Reset the stopwatch
}
} else {
//The minimum error has been reached so stop the drive
digitalWrite(_pin1, LOW);
digitalWrite(_pin2, LOW);
}
}