Skip to content

Instantly share code, notes, and snippets.

@awkward-ninja
Created November 23, 2017 18:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save awkward-ninja/4fc9c4e14263bbea89dd61b1e4a1094e to your computer and use it in GitHub Desktop.
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
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