-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathESP32_Touch_Tacho.cpp
103 lines (90 loc) · 2.51 KB
/
ESP32_Touch_Tacho.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
/* Routines to add Tacho capability to TouchDRO Interface
Mates with ESP32Encoder as adapted by romeo
Prepared June 2020
*/
#include "ESP32_Touch_Tacho.h"
const int minRPM = 20; //RPM below which tacho will decide shaft is stopped
extern ESP32Tacho Tacho;
portMUX_TYPE TachoMux = portMUX_INITIALIZER_UNLOCKED; //despite vs squiggly line, compiles ok
const int32_t microsPerMinute = 60000000;
ESP32Tacho::ESP32Tacho() {
pulsesPerRev = 0;
}
ESP32Tacho::ESP32Tacho(int aP, int bP, float ppr, pullupType uip) {
tachoPinA = (gpio_num_t)aP;
tachoPinB = (gpio_num_t)bP;
pulsesPerRev = ppr;
puType = uip;
pulsesPerMinute = 0;
maxPulseInterval = microsPerMinute / (minRPM * pulsesPerRev);
directionEnabled = false;
}
void ESP32Tacho::attachTacho() {
setupPin(tachoPinA);
if (tachoPinB != 0 && tachoPinB != tachoPinA) {
setupPin(tachoPinB);
directionEnabled = true;
running = false;
}
attachInterrupt(tachoPinA, tacho_isr, RISING);
}
void ESP32Tacho::setupPin(gpio_num_t a) {
gpio_pad_select_gpio(a);
gpio_set_direction(a, GPIO_MODE_INPUT);
if (puType == down) {
gpio_pulldown_en(a);
}
else {
if (puType == up) {
gpio_pullup_en(a);
}
}
}
void IRAM_ATTR tacho_isr() {
unsigned long isr_micros = micros();
if (!Tacho.running) {
portENTER_CRITICAL_ISR(&TachoMux);
Tacho.running = true;
Tacho.pulseCount = 0;
Tacho.direction = digitalRead(Tacho.tachoPinB);
Tacho.timeOfLastPulse = isr_micros;
Tacho.aggregateMicros = 0;
portEXIT_CRITICAL_ISR(&TachoMux);
}
else {
portENTER_CRITICAL_ISR(&TachoMux);
Tacho.pulseCount++;
Tacho.aggregateMicros += (isr_micros - Tacho.timeOfLastPulse);
Tacho.direction = digitalRead(Tacho.tachoPinB);
Tacho.timeOfLastPulse = isr_micros;
portEXIT_CRITICAL_ISR(&TachoMux);
}
}
float ESP32Tacho::get_ppm() {
int temp_pulseCount;
unsigned long temp_aggregateMicros;
unsigned long temp_timeOfLastPulse;
if (!Tacho.running) {
return 0;
}
portENTER_CRITICAL(&TachoMux);
temp_pulseCount = pulseCount;
pulseCount = 0;
temp_aggregateMicros = aggregateMicros;
aggregateMicros = 0;
temp_timeOfLastPulse = timeOfLastPulse;
portEXIT_CRITICAL(&TachoMux);
if (temp_pulseCount == 0) { //if no actual pulses received, display an apparent slowdown in accordance with the report interval
pulseInterval = micros() - temp_timeOfLastPulse;
if (pulseInterval > maxPulseInterval) {
running = false;
direction = 0;
return 0;
}
temp_pulseCount = 1;
}
else {
pulseInterval = temp_aggregateMicros / temp_pulseCount;
}
return (microsPerMinute / pulseInterval);
}