55
66namespace daisy
77{
8+
9+ enum PotTrackingMode
10+ {
11+ // Always post changes immediately
12+ Immediate,
13+ // Wait until value gets close to explicitly set
14+ // "internal value" to begin tracking again
15+ Pickup
16+ };
17+
818/* * @brief A potentiometer monitor that generates events in a UiEventQueue
919 * @author jelliesen
1020 * @ingroup ui
@@ -73,11 +83,28 @@ class PotMonitor
7383 initialized_[i] = false ;
7484 lastValue_[i] = 0.0 ;
7585 timeoutCounterMs_[i] = 0 ;
86+ pickupTarget_[i] = 0 .0f ;
87+ tracking_[i] = true ;
7688 }
7789
7890 lastCallSysTime_ = System::GetNow ();
7991 }
8092
93+ void SetTrackingMode (PotTrackingMode mode)
94+ {
95+ if (mode != tracking_mode_)
96+ {
97+ tracking_mode_ = mode;
98+ if (mode == PotTrackingMode::Immediate)
99+ {
100+ for (uint32_t i = 0 ; i < numPots; i++)
101+ {
102+ tracking_[i] = true ;
103+ }
104+ }
105+ }
106+ }
107+
81108 /* * Checks the value of each pot and generates messages for the UIEventQueue.
82109 * Call this at regular intervals, ideally from your main() idle loop.
83110 */
@@ -102,6 +129,14 @@ class PotMonitor
102129 return timeoutCounterMs_[potId] < timeout_;
103130 }
104131
132+ bool IsTracking (bool potId) const
133+ {
134+ if (potId >= numPots)
135+ return false ;
136+ else
137+ return tracking_[potId];
138+ }
139+
105140 /* * For a given potentiometer, this will return the last value that was
106141 * posted to the UiEventQueue.
107142 * @param potId The unique ID of the potentiometer (< numPots)
@@ -114,6 +149,24 @@ class PotMonitor
114149 return lastValue_[potId];
115150 }
116151
152+ void SetPickupTarget (uint16_t pot_id, float value)
153+ {
154+ if (pot_id < numPots && tracking_mode_ == PotTrackingMode::Pickup)
155+ {
156+ float diff = fabsf (lastValue_[pot_id] - value);
157+ pickupTarget_[pot_id] = value;
158+ tracking_[pot_id] = diff <= deadBand_;
159+
160+ // if the pot is not tracking but it is currently moving,
161+ // force it to stop and send message
162+ if (!tracking_[pot_id] && IsMoving (pot_id))
163+ {
164+ timeoutCounterMs_[pot_id] = timeout_;
165+ queue_->AddPotActivityChanged (pot_id, false );
166+ }
167+ }
168+ }
169+
117170 /* * Returns the BackendType that is used by the monitor. */
118171 BackendType& GetBackend () { return backend_; }
119172
@@ -130,14 +183,17 @@ class PotMonitor
130183 */
131184 void ProcessPot (uint16_t id, float value, uint32_t timeDiffMs)
132185 {
186+ bool tracking
187+ = tracking_[id] || tracking_mode_ == PotTrackingMode::Immediate;
188+
133189 // currently moving?
134190 if (!initialized_[id])
135191 {
136192 initialized_[id] = true ;
137193 lastValue_[id] = value;
138194 queue_->AddPotMoved (id, value);
139195 }
140- else if (timeoutCounterMs_[id] < timeout_)
196+ else if (tracking && timeoutCounterMs_[id] < timeout_)
141197 {
142198 // check if pot has left the deadband. If so, add a new message
143199 // to the queue.
@@ -159,8 +215,8 @@ class PotMonitor
159215 }
160216 }
161217 }
162- // not moving right now
163- else
218+ // tracking but not moving right now
219+ else if (tracking)
164220 {
165221 // check if pot has left the idle deadband. If so, add a new message
166222 // to the queue and restart the timeout
@@ -173,20 +229,41 @@ class PotMonitor
173229 timeoutCounterMs_[id] = 0 ;
174230 }
175231 }
232+ // not tracking
233+ else
234+ {
235+ // Update tracking state
236+ bool passthrough = (lastValue_[id] < pickupTarget_[id]
237+ && value > pickupTarget_[id])
238+ || (lastValue_[id] > pickupTarget_[id]
239+ && value < pickupTarget_[id]);
240+ tracking_[id]
241+ = passthrough || fabsf (value - pickupTarget_[id]) <= deadBand_;
242+ if (tracking_[id])
243+ {
244+ lastValue_[id] = value;
245+ queue_->AddPotActivityChanged (id, true );
246+ queue_->AddPotMoved (id, value);
247+ timeoutCounterMs_[id] = 0 ;
248+ }
249+ }
176250 }
177251
178252 PotMonitor (const PotMonitor&) = delete;
179253 PotMonitor& operator =(const PotMonitor&) = delete ;
180254
181- UiEventQueue* queue_;
182- BackendType* backend_;
183- float deadBand_;
184- float deadBandIdle_;
185- uint16_t timeout_;
186- bool initialized_[numPots];
187- float lastValue_[numPots];
188- uint16_t timeoutCounterMs_[numPots];
189- uint32_t lastCallSysTime_;
255+ UiEventQueue* queue_;
256+ BackendType* backend_;
257+ PotTrackingMode tracking_mode_;
258+ float deadBand_;
259+ float deadBandIdle_;
260+ uint16_t timeout_;
261+ bool initialized_[numPots];
262+ float lastValue_[numPots];
263+ float pickupTarget_[numPots];
264+ bool tracking_[numPots];
265+ uint16_t timeoutCounterMs_[numPots];
266+ uint32_t lastCallSysTime_;
190267};
191268
192269} // namespace daisy
0 commit comments