COSA
An Object-Oriented Platform for Arduino Programming
Rotary.hh
Go to the documentation of this file.
1 
21 #ifndef COSA_ROTARY_HH
22 #define COSA_ROTARY_HH
23 
24 #include "Cosa/Types.h"
26 #include "Cosa/RTT.hh"
27 
40 class Rotary {
41 public:
60  class Encoder : public Event::Handler {
61  public:
65  enum Direction {
66  NONE = 0x00,
67  CW = 0x10,
68  CCW = 0x20
69  } __attribute__((packed));
70 
74  enum Mode {
77  } __attribute__((packed));
78 
87  Mode mode = FULL_CYCLE) :
88  m_clk(clk, this),
89  m_dt(dt, this),
90  m_state(0),
91  m_mode(mode)
92  {
93  enable();
94  }
95 
100  Mode mode() const
101  {
102  return (m_mode);
103  }
104 
109  void mode(Mode mode)
110  {
111  m_mode = mode;
112  }
113 
117  void enable()
118  __attribute__((always_inline))
119  {
120  m_clk.enable();
121  m_dt.enable();
122  }
123 
127  void disable()
128  __attribute__((always_inline))
129  {
130  m_clk.disable();
131  m_dt.disable();
132  }
133 
134  protected:
139  class SignalPin : public PinChangeInterrupt {
140  public:
142  PinChangeInterrupt(pin),
143  m_encoder(encoder)
144  {}
145 
146  private:
147  Encoder* m_encoder;
148 
154  virtual void on_interrupt(uint16_t arg);
155  };
156 
158  static const uint8_t half_cycle_table[6][4] PROGMEM;
159 
161  static const uint8_t full_cycle_table[7][4] PROGMEM;
162 
166  uint8_t m_state;
168 
175  Direction detect();
176  };
177 
196  template<typename T>
197  class Dial : public Encoder {
198  public:
212  T initial, T min, T max, T step) :
213  Encoder(clk, dt, mode),
214  m_value(initial),
215  m_min(min),
216  m_max(max),
217  m_step(step)
218  {}
219 
224  T value() const
225  {
226  return (m_value);
227  }
228 
233  T step() const
234  {
235  return (m_step);
236  }
237 
242  void step(T step)
243  {
244  m_step = step;
245  }
246 
252  virtual void on_change(T value)
253  {
254  UNUSED(value);
255  }
256 
257  protected:
259  T m_min;
260  T m_max;
262 
270  virtual void on_event(uint8_t type, uint16_t value)
271  {
272  UNUSED(type);
273  if (value == CW) {
274  if (m_value == m_max) return;
275  m_value += m_step;
276  }
277  else {
278  if (m_value == m_min) return;
279  m_value -= m_step;
280  }
281  on_change(m_value);
282  }
283  };
284 
303  template<typename T, uint32_t THRESHOLD>
304  class AcceleratedDial : public Encoder {
305  public:
320  T initial, T min, T max, T step, T steps) :
321  Encoder(clk, dt, mode),
322  m_latest(0L),
323  m_value(initial),
324  m_min(min),
325  m_max(max),
326  m_step(step),
327  m_steps(steps)
328  {}
329 
334  T value() const
335  {
336  return (m_value);
337  }
338 
343  T step() const
344  {
345  return (m_step);
346  }
347 
352  void step(T step)
353  {
354  m_step = step;
355  }
356 
361  T steps() const
362  {
363  return (m_steps);
364  }
365 
370  void steps(T steps)
371  {
372  m_steps = steps;
373  }
374 
380  virtual void on_change(T value)
381  {
382  UNUSED(value);
383  }
384 
385  private:
386  uint32_t m_latest;
387  T m_value;
388  T m_min;
389  T m_max;
390  T m_step;
391  T m_steps;
392 
402  virtual void on_event(uint8_t type, uint16_t direction)
403  {
404  uint32_t now = RTT::micros();
405  int32_t diff = now - m_latest;
406  m_latest = now;
407  if (direction == CW) {
408  if (m_value == m_max) return;
409  if (diff > THRESHOLD)
410  m_value += m_step;
411  else
412  m_value += m_steps;
413  if (m_value > m_max) m_value = m_max;
414  }
415  else {
416  if (m_value == m_min) return;
417  if (diff > THRESHOLD)
418  m_value -= m_step;
419  else
420  m_value -= m_steps;
421  if (m_value < m_min) m_value = m_min;
422  }
423  on_change(m_value);
424  }
425  };
426 };
427 #endif
T value() const
Definition: Rotary.hh:224
Clock-wise direction.
Definition: Rotary.hh:67
uint8_t pin() const
Definition: Pin.hh:103
virtual void on_event(uint8_t type, uint16_t value)
Definition: Rotary.hh:270
virtual void on_change(T value)
Definition: Rotary.hh:380
static const uint8_t half_cycle_table[6][4]
Definition: Rotary.hh:158
Mode mode() const
Definition: IOPin.hh:71
static const uint8_t full_cycle_table[7][4]
Definition: Rotary.hh:161
void steps(T steps)
Definition: Rotary.hh:370
static uint32_t micros()
Definition: RTT.cpp:103
Dial(Board::InterruptPin clk, Board::InterruptPin dt, Mode mode, T initial, T min, T max, T step)
Definition: Rotary.hh:211
SignalPin(Board::InterruptPin pin, Encoder *encoder)
Definition: Rotary.hh:141
void disable()
Definition: Rotary.hh:127
#define UNUSED(x)
Definition: ATmega328P.hh:31
void step(T step)
Definition: Rotary.hh:242
void enable()
Definition: Rotary.hh:117
AcceleratedDial(Board::InterruptPin clk, Board::InterruptPin dt, Mode mode, T initial, T min, T max, T step, T steps)
Definition: Rotary.hh:319
Anti-clock-wise direction.
Definition: Rotary.hh:68
virtual void on_change(T value)
Definition: Rotary.hh:252
void mode(Mode mode)
Definition: Rotary.hh:109
SignalPin m_dt
Definition: Rotary.hh:165
T step() const
Definition: Rotary.hh:233
SignalPin m_clk
Definition: Rotary.hh:164
virtual void on_event(uint8_t type, uint16_t value)
Definition: Event.hh:107
uint8_t m_state
Definition: Rotary.hh:166
No direction change.
Definition: Rotary.hh:66
Mode mode() const
Definition: Rotary.hh:100
Direction detect()
Definition: Rotary.cpp:222
void step(T step)
Definition: Rotary.hh:352
Definition: Rotary.hh:40
Encoder(Board::InterruptPin clk, Board::InterruptPin dt, Mode mode=FULL_CYCLE)
Definition: Rotary.hh:86