-
Notifications
You must be signed in to change notification settings - Fork 2
/
button_abs.h
160 lines (133 loc) · 4.86 KB
/
button_abs.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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
// Button abstraction IO wrapper
// @uses IoAbstraction
#ifndef buttons_abs_h
#define buttons_abs_h
#include <taskmanager.h> // davetcc/TaskManagerIO
#include <IoAbstraction.h> // davetcc/ioabstraction
#include <IoAbstractionWire.h>
const int interruptPin = 3; // if motor.h stalldetect, Real interrupt for io expander USES SERIAL RX!!!
const int encoderSWPin = 0;
const int encoderAPin = 1;
const int encoderBPin = 2;
int _maximumEncoderValue = 0; // 128; 0 for non counting mode
int encoderStale = 0; // prev stale value
int encoderLast = -1; // prev value
bool encoderHasChange = false; // flag enc change
bool useInt = false; // use interrupts, via interruptPin
long int encoderLastChange = 0; // timestamp of last encoder change
int encoderThrottleDuration = 500; // how long to defer loop for encoder waits
bool encoderHasPress = false;
bool encoderHasHold = false;
bool debug_enc = true;
volatile bool PCFInterruptFlag = false;
void encoderClear(){
encoderHasPress = false;
encoderHasHold = false;
encoderHasChange = false;
encoderLastChange = millis();
}
void IRAM_ATTR onEncoderChange(int newValue) {
// @todo always a false trigger on start
// if(encoderLast < 0){
// Serial.println("[ENC] init fired");
// encoderLast = newValue;
// encoderClear();
// return; // init
// }
if(_maximumEncoderValue > 0){
if(debug_enc){
Serial.print("[ENCODER] change to ");
Serial.print(newValue);
Serial.print(" from ");
Serial.print(encoderLast);
if(encoderLast == newValue){
Serial.println("\n");
return;
}
}
bool dir = (encoderLast > newValue);
if(debug_enc) Serial.println(" dir: " + String(dir ? "CC" : "CW"));
encoderStale = encoderLast;
encoderLast = newValue;
encoderHasChange = true;
}
else{
if(newValue == 0){
if(debug_enc) Serial.print("[ENCODER] no change");
return;
}
if(debug_enc){
Serial.print("[ENCODER] change by ");
Serial.print(newValue);
}
bool dir = (newValue == 1);
if(debug_enc) Serial.println(" dir: " + String(dir ? "CW" : "CC")); // for plotting use 10,20 etc
encoderStale = encoderLast;
encoderLast = newValue;
encoderHasChange = true;
}
}
void ICACHE_RAM_ATTR onEncoderSWPressed(uint8_t pin, bool heldDown) {
Serial.print("[ENCODER] Button ");
Serial.println(heldDown ? "Held" : "Pressed");
encoderHasPress = true;
encoderHasHold = heldDown;
}
// adjust the encoder acceleraton
// HWACCEL_FAST
// HWACCEL_SLOWER
// HWACCEL_NONE
void setEncoderAccel(HWAccelerationMode accel){
HardwareRotaryEncoder* hwEncoder = reinterpret_cast<HardwareRotaryEncoder*>(switches.getEncoder());
hwEncoder->setAccelerationMode(accel);
}
void init_encoder(int encoderAPin, int encoderBPin, int encoderSWPin,uint8_t addr=0){
if(addr){
// First we set up the switches library, giving it the task manager and tell it where the pins are located
// We could also of chosen IO through an i2c device that supports interrupts.
// the second parameter is a flag to use pull up switching, (true is pull up).
if(useInt)switches.initialiseInterrupt(ioFrom8574(0x20, interruptPin), true);
else switches.initialiseInterrupt(ioFrom8574(0x20), true);
}
else{
switches.initialise(ioUsingArduino(), true);
}
// encoder sw
#ifndef ENC_SW_ANALOG
switches.addSwitch(encoderSWPin, onEncoderSWPressed); // encoder button press
#endif
// encoder
setupRotaryEncoderWithInterrupt(encoderAPin, encoderBPin, onEncoderChange);
if(_maximumEncoderValue > 0) switches.changeEncoderPrecision(_maximumEncoderValue, 0);
// switches.setEncoder(0, myEncoder);
// alt encocder setup
// HardwareRotaryEncoder* firstEncoder = new HardwareRotaryEncoder(encoderAPin, encoderBPin, onEncoderChange);
// switches.setEncoder(0, firstEncoder);
// firstEncoder->setAccelerationMode(HWACCEL_SLOWER); // acceleration mode
// interrupt for any
// taskManager.setInterruptCallback(onInterrupt);
// now we add the switches, we dont want the spinwheel button to repeat, so leave off the last parameter
// which is the repeat interval (millis / 20 basically) Repeat button does repeat as we can see.
}
void setEncoderMax(int maximumEncoderValue){
if(maximumEncoderValue > 0) switches.changeEncoderPrecision(maximumEncoderValue, 0);
_maximumEncoderValue = maximumEncoderValue;
}
void checkAnalogSW(uint8_t pin, uint16_t value,uint32_t hold){
// adc range / value 1024/500 = 2 states+ etc
if(analogRead(pin) < value){
encoderHasPress = true;
delay(hold);
if(analogRead(pin) < value) encoderHasHold = true;
}
}
// IoAbstractionRef iodev = switches.getIoAbstraction();
// iodev->pinDirection(7,OUTPUT);
// bool res = iodev->runLoop();
// if(res!=1) Serial.println("devsync: " + (String)res);
// taskManager.runLoop();
// if(!res){
// Serial.println("error");
// delay(500);
// }
#endif