IoAbstraction
JoystickSwitchInput.h
Go to the documentation of this file.
1 #ifndef _JOYSTICK_SWITCH_INPUT_H_
2 #define _JOYSTICK_SWITCH_INPUT_H_
3 
4 #include "SwitchInput.h"
6 
7 #ifndef MAX_JOYSTICK_ACCEL
8 #define MAX_JOYSTICK_ACCEL 10.1F
9 #endif // MAX_JOYSTICK_ACCEL
10 
28 class JoystickSwitchInput : public RotaryEncoder, public Executable {
29 private:
30  pinid_t analogPin;
31  AnalogDevice* analogDevice;
32  float tolerance = 0.03F;
33  float midPoint = 0.5F;
34  float accelerationFactor = 1000.0F;
35  float initialDelay = 750.0F;
36  float delayAcceleration = 3.0F;
37 public:
45  JoystickSwitchInput(AnalogDevice *analogDevice, pinid_t analogPin, EncoderCallbackFn callback) : RotaryEncoder(callback) {
46  this->analogPin = analogPin;
47  this->analogDevice = analogDevice;
48  analogDevice->initPin(analogPin, DIR_IN);
49  }
50 
58  JoystickSwitchInput(AnalogDevice *analogDevice, pinid_t analogPin, EncoderListener* listener) : RotaryEncoder(listener) {
59  this->analogPin = analogPin;
60  this->analogDevice = analogDevice;
61  analogDevice->initPin(analogPin, DIR_IN);
62  }
63 
70  void setAccelerationParameters(float initialDelayPeriod, float decreaseDivisor) {
71  this->initialDelay = initialDelayPeriod;
72  this->delayAcceleration = decreaseDivisor;
73  }
74 
82  void setTolerance(float midPoint_, float tolerance_) {
83  tolerance = tolerance_;
84  midPoint = midPoint_;
85  }
86 
87  int nextInterval(int forceApplied) {
88  switch(forceApplied) {
89  case 0:
90  case 1: return 250;
91  case 2: return 200;
92  case 3: return 150;
93  case 4: return 100;
94  default: return 50;
95  }
96  }
97 
101  void exec() override {
102  float readVal = analogDevice->getCurrentFloat(analogPin) - midPoint;
103 
104  bool scrolling = intent == SCROLL_THROUGH_ITEMS || intent == SCROLL_THROUGH_SIDEWAYS;
105 
106  if(readVal > tolerance) {
107  int dir = (scrolling) ? -1 : 1;
108  increment(dir);
109  }
110  else if(readVal < (-tolerance)) {
111  int dir = (scrolling) ? 1 : -1;
112  increment(dir);
113  }
114  else {
115  accelerationFactor = initialDelay;
116  taskManager.scheduleOnce(250, this);
117  return;
118  }
119 
120  auto delay = nextInterval(abs(readVal * MAX_JOYSTICK_ACCEL)) + accelerationFactor;
121  taskManager.scheduleOnce(delay, this);
122  if(accelerationFactor > 1.0F) {
123  accelerationFactor /= delayAcceleration;
124  }
125  }
126 };
127 
128 #define ANALOG_JOYSTICK_LOWER_PIN 0
129 #define ANALOG_JOYSTICK_HIGHER_PIN 1
130 
132 private:
133  enum CurrentJoystickDirection : uint8_t { LEFT = 0x01, RIGHT = 0x02, NONE = 0x00 };
134  AnalogDevice* analogDevice;
135  pinid_t joystickPin;
136  CurrentJoystickDirection currentDir = NONE;
137  bool errorOccurred = false;
138  bool initialisedYet = false;
139  bool inverted = false;
140  float centrePoint;
141 public:
142  AnalogJoystickToButtons(AnalogDevice* device, pinid_t pin, float centre) {
143  joystickPin = pin;
144  analogDevice = device;
145  centrePoint = centre;
146  }
147 
148  ~AnalogJoystickToButtons() override = default;
149 
150  uint8_t readValue(pinid_t pin) override {
151  bool ret = (pin == 0) ? currentDir == LEFT : currentDir == RIGHT;
152  if(inverted) ret = !ret;
153  return ret;
154  }
155 
156  uint8_t readPort(pinid_t pin) override {
157  return inverted ? ~currentDir : currentDir;
158  }
159 
160  bool runLoop() override {
161  auto value = analogDevice->getCurrentFloat(joystickPin);
162  auto offLowest = centrePoint - 0.15;
163  auto offHighest = centrePoint + 0.15;
164  if(value < offLowest) {
165  currentDir = LEFT;
166  }
167  else if(value > offHighest) {
168  currentDir = RIGHT;
169  }
170  else {
171  currentDir = NONE;
172  }
173  return true;
174  }
175 
176  void pinDirection(pinid_t pin, uint8_t mode) override {
177  if(!initialisedYet) {
178  initialisedYet = true;
179  analogDevice->initPin(joystickPin, DIR_IN);
180  }
181  if(mode == INPUT) {
182  inverted = false;
183  return;
184  }
185  if(mode == INPUT_PULLUP) {
186  inverted = true;
187  return;
188  }
189  // only input and input pull up are supported.
190  errorOccurred = true;
191  }
192 
193  bool hasErrorOccurred() const { return errorOccurred; }
194 
195  //
196  // The following functions are not supported, as this abstraction is only for local joystick input.
197  //
198 
199  void writeValue(pinid_t pin, uint8_t value) override { }
200 
201  void writePort(pinid_t pin, uint8_t portVal) override { }
202 
203  // we let the base class handle attach interrupt, if its supported it should work in change mode for analog in
204  //void attachInterrupt(pintype_t pin, RawIntHandler interruptHandler, uint8_t mode) override { }
205 };
206 
214 inline void setupAnalogJoystickEncoder(AnalogDevice* analogDevice, pinid_t analogPin, EncoderCallbackFn callback) {
215  auto joystickEncoder = new JoystickSwitchInput(analogDevice, analogPin, callback);
216  switches.setEncoder(joystickEncoder);
217  taskManager.scheduleOnce(250, joystickEncoder);
218 }
219 
220 inline IoAbstractionRef joystickTwoButtonExpander(AnalogDevice* analogDevice, pinid_t analogPin, float centrePoint) {
221  return new AnalogJoystickToButtons(analogDevice, analogPin, centrePoint);
222 }
223 
224 #endif // _JOYSTICK_SWITCH_INPUT_H_
Contains a series of helper classes for dealing with analog devices, these are compatible across a wi...
void setupAnalogJoystickEncoder(AnalogDevice *analogDevice, pinid_t analogPin, EncoderCallbackFn callback)
Definition: JoystickSwitchInput.h:214
Switch input provides the button and rotary encoder input capabilities provided by this library....
void(* EncoderCallbackFn)(int newValue)
Definition: SwitchInput.h:120
SwitchInput switches
Definition: SwitchInput.cpp:11
@ SCROLL_THROUGH_SIDEWAYS
Definition: SwitchInput.h:179
@ SCROLL_THROUGH_ITEMS
Definition: SwitchInput.h:177
Definition: AnalogDeviceAbstraction.h:31
virtual void initPin(pinid_t pin, AnalogDirection direction)=0
Definition: JoystickSwitchInput.h:131
uint8_t readValue(pinid_t pin) override
Definition: JoystickSwitchInput.h:150
void writeValue(pinid_t pin, uint8_t value) override
Definition: JoystickSwitchInput.h:199
uint8_t readPort(pinid_t pin) override
Definition: JoystickSwitchInput.h:156
void writePort(pinid_t pin, uint8_t portVal) override
Definition: JoystickSwitchInput.h:201
bool runLoop() override
Definition: JoystickSwitchInput.h:160
void pinDirection(pinid_t pin, uint8_t mode) override
Definition: JoystickSwitchInput.h:176
Definition: BasicIoAbstraction.h:38
Definition: SwitchInput.h:188
Definition: JoystickSwitchInput.h:28
void setAccelerationParameters(float initialDelayPeriod, float decreaseDivisor)
Definition: JoystickSwitchInput.h:70
void exec() override
Definition: JoystickSwitchInput.h:101
JoystickSwitchInput(AnalogDevice *analogDevice, pinid_t analogPin, EncoderListener *listener)
Definition: JoystickSwitchInput.h:58
JoystickSwitchInput(AnalogDevice *analogDevice, pinid_t analogPin, EncoderCallbackFn callback)
Definition: JoystickSwitchInput.h:45
void setTolerance(float midPoint_, float tolerance_)
Definition: JoystickSwitchInput.h:82
Definition: SwitchInput.h:203
void increment(int8_t incVal)
Definition: SwitchInput.cpp:316
void setEncoder(RotaryEncoder *encoder)
Definition: SwitchInput.h:626