Skip to content

Commit bdef06b

Browse files
Added concentric rotary encoder emulation
New class to allow emulation of concentric rotary encoders using single shaft encoders with integrated push buttons. Retains methods and style from RotaryEncoderT. Example usage (A-10C): typedef DcsBios::EmulatedConcentricRotaryEncoderT<POLL_EVERY_TIME, DcsBios::FOUR_STEPS_PER_DETENT> EmulatedConcentricRotaryEncoder; EmulatedConcentricRotaryEncoder ilsRightKnob("ILS_KHZ", "DEC", "INC", "ILS_VOL", "-4500", "+4500", DATAPIN, CLKPIN, SWPIN);
1 parent 65843e1 commit bdef06b

File tree

1 file changed

+106
-0
lines changed

1 file changed

+106
-0
lines changed

src/internal/Encoders.h

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,112 @@ namespace DcsBios {
292292
};
293293
typedef MatRotaryEncoderT<> MatRotaryEncoder;
294294

295+
//To emulate dual concentric rotary encoders/resolvers/potentiometers using a rotary encoder with a push button.
296+
//Secondary message is used when push button or switch is enabled.
297+
298+
template <unsigned long pollIntervalMs = POLL_EVERY_TIME, StepsPerDetent stepsPerDetent = ONE_STEP_PER_DETENT>
299+
class EmulatedConcentricRotaryEncoderT : PollingInput, public ResettableInput {
300+
private:
301+
const char* msg1_; //Function 1 (default)
302+
const char* decArg1_;
303+
const char* incArg1_;
304+
const char* msg2_; //Function 2
305+
const char* decArg2_;
306+
const char* incArg2_;
307+
char pinA_;
308+
char pinB_;
309+
char pinC_; //Integrated button pin
310+
bool msg1Mode_;
311+
char prevMode_;
312+
char lastState_;
313+
signed char delta_;
314+
315+
char readState() {
316+
return (digitalRead(pinA_) << 1) | digitalRead(pinB_);
317+
}
318+
319+
void checkPress() {
320+
char currentMode;
321+
msg1Mode_ = ((currentMode = digitalRead(pinC_)) != prevMode_)?!msg1Mode_:msg1Mode_;
322+
prevMode_ = currentMode;
323+
}
324+
325+
void resetState() {
326+
lastState_ = (lastState_==0)?-1:0;
327+
}
328+
329+
void pollInput() {
330+
char state = readState();
331+
checkPress();
332+
switch(lastState_) {
333+
case 0:
334+
if (state == 2) delta_--;
335+
if (state == 1) delta_++;
336+
break;
337+
case 1:
338+
if (state == 0) delta_--;
339+
if (state == 3) delta_++;
340+
break;
341+
case 2:
342+
if (state == 3) delta_--;
343+
if (state == 0) delta_++;
344+
break;
345+
case 3:
346+
if (state == 1) delta_--;
347+
if (state == 2) delta_++;
348+
break;
349+
}
350+
lastState_ = state;
351+
352+
if ((delta_ >= stepsPerDetent) && (msg1Mode_)) {
353+
if (tryToSendDcsBiosMessage(msg1_, incArg1_))
354+
delta_ -= stepsPerDetent;
355+
}
356+
if ((delta_ <= -stepsPerDetent) && (msg1Mode_)) {
357+
if (tryToSendDcsBiosMessage(msg1_, decArg1_))
358+
delta_ += stepsPerDetent;
359+
}
360+
if ((delta_ >= stepsPerDetent) && (!msg1Mode_)) {
361+
if (tryToSendDcsBiosMessage(msg2_, incArg2_))
362+
delta_ -= stepsPerDetent;
363+
}
364+
if ((delta_ <= -stepsPerDetent) && (!msg1Mode_)) {
365+
if (tryToSendDcsBiosMessage(msg2_, decArg2_))
366+
delta_ += stepsPerDetent;
367+
}
368+
}
369+
public:
370+
EmulatedConcentricRotaryEncoderT(const char* msg1, const char* decArg1, const char* incArg1, const char* msg2, const char* decArg2, const char* incArg2, char pinA, char pinB, char pinC) :
371+
PollingInput(pollIntervalMs) {
372+
msg1_ = msg1;
373+
decArg1_ = decArg1;
374+
incArg1_ = incArg1;
375+
msg2_ = msg2;
376+
decArg2_ = decArg2;
377+
incArg2_ = incArg2;
378+
pinA_ = pinA;
379+
pinB_ = pinB;
380+
pinC_ = pinC;
381+
msg1Mode_ = true;
382+
prevMode_ = 1;
383+
pinMode(pinA_, INPUT_PULLUP);
384+
pinMode(pinB_, INPUT_PULLUP);
385+
pinMode(pinC_, INPUT_PULLUP);
386+
prevMode_ = digitalRead(pinC_); //Prevents defaulting to secondary action on initialization
387+
delta_ = 0;
388+
lastState_ = readState();
389+
}
390+
391+
void SetControl(const char* msg) {
392+
msg1_ = msg;
393+
}
394+
395+
396+
void resetThisState() {
397+
this->resetState();
398+
}
399+
};
400+
typedef EmulatedConcentricRotaryEncoderT<> EmulatedConcentricRotaryEncoder;
295401
}
296402

297403
#endif

0 commit comments

Comments
 (0)