-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathMServo.h
131 lines (116 loc) · 2.57 KB
/
MServo.h
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
124
125
126
127
128
129
130
131
class MServo {
public:
MServo();
void attach(int pot, int dir, int pwm);
int getPot();
int movingAverage();
void move(int val);
int getAngle();
int getTarget();
void resetTarget();
void setAngleConstrain(int min, int max);
void setPotConstrain(int min, int max);
void setTolerance(int tolerance);
void write(int target);
void update();
bool reverse = false;
private:
int _pot, _dir, _pwm;
// Moving Average
int _numRead = 10; // Default 10
int _readings[10]; // Default 10
int _total = 0;
int _readIndex = 0;
int _minPot = 0;
int _maxPot = 1023;
int _minAngle = 0;
int _maxAngle = 360;
int _target = 0;
int _tolerance = 6;
int _baseSpeed = 200;
};
// Constructor
MServo::MServo() {}
void MServo::attach(int pot, int dir, int pwm) {
_pot = pot;
_dir = dir;
_pwm = pwm;
pinMode(_pot, INPUT);
pinMode(_dir, OUTPUT);
pinMode(_pwm, OUTPUT);
// Ubah semua nilai awal menjadi 0
for (int thisReading = 0; thisReading < _numRead; thisReading++) {
_readings[thisReading] = 0;
}
}
int MServo::getPot() {
return analogRead(_pot);
}
int MServo::movingAverage() {
int result;
_total -= _readings[_readIndex];
_readings[_readIndex] = getPot();
_total += _readings[_readIndex];
_readIndex += 1;
if (_readIndex >= _numRead) {
_readIndex = 0;
}
result = _total / _numRead;
return result;
}
void MServo::move(int val) {
if(reverse){
val *=-1;
}
if (val >= 0) {
digitalWrite(_dir, 0);
analogWrite(_pwm, val);
} else if (val < 0) {
digitalWrite(_dir, 1);
analogWrite(_pwm, 255 + val);
}
}
int MServo::getAngle() {
int angle = map(movingAverage(), _minPot, _maxPot, _minAngle, _maxAngle);
return constrain(angle, _minAngle, _maxAngle);
}
int MServo::getTarget(){
return _target;
}
void MServo::resetTarget(){
_target = getAngle();
}
void MServo::setAngleConstrain(int min, int max) {
_minAngle = min;
_maxAngle = max;
}
void MServo::setPotConstrain(int min, int max) {
_minPot = min;
_maxPot = max;
}
void MServo::setTolerance(int tolerance) {
if (tolerance < 0) {
tolerance *= -1;
}
_tolerance = tolerance;
}
void MServo::write(int target) {
_target = target;
}
void MServo::update() {
int target = _target;
int feedback = getAngle();
int diff = feedback - target;
int tolerance = _tolerance / 2;
if ((diff < tolerance) && (diff > -tolerance)) {
move(0);
}
else {
if (diff > tolerance) {
move(_baseSpeed);
}
else if (diff < -tolerance) {
move(-1 * _baseSpeed);
}
}
}