-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathVibrationMotor.cpp
95 lines (77 loc) · 2.38 KB
/
VibrationMotor.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
#include <math.h>
#include <Arduino.h>
// Strategy values
const int averageStrat = 0;
const int minStrat = 1;
const int slidingWindowStrat = 2;
const int bufferSize = 10;
// Distance constants
const int minDistance = 300;
const int maxDistance = 3000;
class VibrationMotor {
private:
int distanceBuffer[bufferSize];
int currentIndex = 0;
int strategy = 0;
void processBuffer() {
float distance = 0;
if (this->strategy == averageStrat || this->strategy == slidingWindowStrat) {
distance = this->calcAverage();
} else if (this->strategy == minStrat) {
distance = this->calcMin();
}
this->setIntensity(this->calculateIntensity(distance));
if (this->currentIndex == bufferSize) {
this->currentIndex = 0;
}
}
int calculateIntensity(float distance) {
if (distance > maxDistance) return 0;
if (distance == maxDistance) return 255; // distance == maxDistance would lead to a zero division, therefor we return early
// Calculate the intensity based on the distance
int intensity = static_cast<int>((maxDistance - distance) / (maxDistance - minDistance) * 255.0);
intensity = constrain(intensity, 0, 255);
return intensity;
}
// Calculate min strategy
float calcMin() {
int minNum = 9999;
for (int i = 0; i < this->currentIndex; i++) {
if (this->distanceBuffer[i] < minDistance) continue;
minNum = min(minNum, this->distanceBuffer[i]);
}
return (float) minNum;
}
// Calculate average strategy, can be reused for sliding window strategy
float calcAverage() {
float sum = 0.0;
for (int i = 0; i < this->currentIndex; i++) {
sum += this->distanceBuffer[i];
}
float average = sum / this->currentIndex;
return average;
}
void setIntensity(int intensity) {
this->intensity = intensity;
Serial.print(this->pin);
Serial.print(" : ");
Serial.println(intensity);
}
public:
VibrationMotor(): pin(-1), intensity(999) {} // Default constructor
int pin;
int intensity;
VibrationMotor(int pin, int strategy) {
this->pin = pin;
this->intensity = -1;
this->strategy = strategy;
pinMode(this->pin, OUTPUT);
}
void add(float distance) {
this->distanceBuffer[this->currentIndex] = distance;
this->currentIndex++;
if (this->strategy == slidingWindowStrat || this->currentIndex == bufferSize) {
this->processBuffer();
}
}
};