Created
November 23, 2017 18:47
-
-
Save awkward-ninja/4fc9c4e14263bbea89dd61b1e4a1094e to your computer and use it in GitHub Desktop.
Rotary switch for Arduino Nano with Debouncing, Maximum Range, Value Lock, and Position Memory
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
struct signal { | |
byte curr; | |
byte prev; | |
}; | |
struct signalDb { | |
byte curr; | |
byte prev; | |
signal db; | |
}; | |
#define sigFetch(sig, pin) \ | |
(sig).curr = digitalRead (pin); | |
#define sigTick(sig) \ | |
(sig).prev = (sig).curr | |
#define sigInit(sig, pin) \ | |
sigFetch ((sig), (pin)); | |
#define sigPump(sig, pin) \ | |
sigTick (sig); \ | |
sigFetch ((sig), (pin)); | |
#define sigChanged(sig) ((sig).curr != (sig).prev) | |
#define sigRaised(sig) ((sig).curr == HIGH && (sig).prev == LOW) | |
#define sigDbFetch(sig, pin) \ | |
(sig).db.curr = ((sig).db.curr << 1) | digitalRead (pin); \ | |
if (!((sig).db.prev ^ (sig).db.curr)) { \ | |
(sig).curr = (sig).db.curr & 0x1; \ | |
} | |
#define sigDbInit(sig, pin) \ | |
sigFetch ((sig), (pin)); \ | |
(sig).db.curr = (sig).curr ? 0xFF : 0; | |
#define sigDbPump(sig, pin) \ | |
sigTick (sig); \ | |
sigTick ((sig).db); \ | |
sigDbFetch ((sig), (pin)); | |
struct rotary { | |
signal sw; | |
signal clk; | |
signalDb dt; | |
}; | |
#define rotInit(rot, SW, CLK, DT) \ | |
pinMode (SW, INPUT); | |
pinMode (CLK, INPUT); | |
pinMode (DT, INPUT); | |
sigInit ((rot).sw, SW); \ | |
sigInit ((rot).clk, CLK); \ | |
sigDbInit ((rot).dt, DT); | |
#define rotPump(rot, SW, CLK, DT) \ | |
sigPump ((rot).sw, SW); \ | |
sigPump ((rot).clk, CLK); \ | |
sigDbPump ((rot).dt, DT); | |
#define rotChanged(rot) (sigChanged (rot.dt) && (rot).clk.curr == HIGH) | |
#define rotCw(rot) ((rot).dt.curr != (rot).clk.curr) | |
#define SW0 2 | |
#define CLK0 3 | |
#define DT0 4 | |
#define SW1 5 | |
#define CLK1 6 | |
#define DT1 7 | |
rotary rCtrl; | |
rotary rVal; | |
byte ctrl; | |
int pos; | |
int bias[256]; | |
boolean ctrlLock; | |
boolean valLock; | |
void setup () | |
{ | |
rotInit (rCtrl, SW0, CLK0, DT0); | |
rotInit (rVal, SW1, CLK1, DT1); | |
Serial.begin (9600); | |
} | |
void loop () | |
{ | |
delayMicroseconds (500); | |
rotPump (rCtrl, SW0, CLK0, DT0); | |
rotPump (rVal, SW1, CLK1, DT1); | |
if (!ctrlLock && rotChanged (rCtrl)) { | |
bias[ctrl] = pos; | |
if (rotCw (rCtrl)) | |
ctrl++; | |
else | |
ctrl--; | |
pos = bias[ctrl]; | |
Serial.print ("Control "); | |
Serial.print (ctrl); | |
Serial.print (": "); | |
Serial.println (pos); | |
} | |
if (sigRaised (rCtrl.sw)) { | |
ctrlLock = !ctrlLock; | |
Serial.print ("LOCKED: Control: "); | |
Serial.println (ctrlLock); | |
} | |
if (!valLock && rotChanged (rVal)) { | |
if (rotCw (rVal)) | |
pos++; | |
else | |
pos--; | |
Serial.print ("Control"); | |
Serial.print (ctrl); | |
Serial.print (": "); | |
Serial.println (pos); | |
} | |
if (sigRaised (rVal.sw)) { | |
valLock = !valLock; | |
Serial.print ("LOCKED: Value: "); | |
Serial.println (valLock); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment