RSeries astromech firmware
ServoSequencer.h
Go to the documentation of this file.
1 #ifndef ServoSequencer_h
2 #define ServoSequencer_h
3 
4 #include "ReelTwo.h"
5 #include "core/AnimatedEvent.h"
6 #include "ServoDispatch.h"
7 
8 // Offset value specified in per-mille (per thousand)
9 #define SEQUENCE_RANGE_LIMIT(offsetFromMin, offsetFromMax) \
10 { uint16_t(~0), (((offsetFromMin)>>8)&0xFF), (((offsetFromMin)>>0)&0xFF), (((offsetFromMax)>>8)&0xFF), (((offsetFromMax)>>0)&0xFF) },
11 
17 struct ServoStep
18 {
19  uint16_t cs; /* centiseconds: 1/100th of a second*/
20  uint8_t servo1_8;
21  uint8_t servo9_16;
22  uint8_t servo17_24;
23  uint8_t servo25_32;
24 };
25 
26 typedef struct ServoStep ServoSequence[];
27 
28 static const ServoSequence SeqPanelAllOpen PROGMEM =
29 {
30  { 20, B11111111, B11111111, B11111111, B11111111 },
31 };
32 
33 static const ServoSequence SeqPanelAllClose PROGMEM =
34 {
35  { 20, B00000000, B00000000, B00000000, B00000000 },
36 };
37 
38 static const ServoSequence SeqPanelAllOpenClose PROGMEM =
39 {
40  { 300, B11111111, B11111111, B11111111, B11111111 },
41  { 150, B00000000, B00000000, B00000000, B00000000 },
42 };
43 
44 static const ServoSequence SeqPanelAllOpenCloseLong PROGMEM =
45 {
46  { 1000, B11111111, B11111111, B11111111, B11111111 },
47  { 150, B00000000, B00000000, B00000000, B00000000 },
48 };
49 
50 static const ServoSequence SeqPanelAllFlutter PROGMEM =
51 {
52  // Twenty permille (per thousand) offset from start/end positions
53  SEQUENCE_RANGE_LIMIT(200, 200)
54  { 10, B11111111, B11111111, B11111111, B11111111 },
55  { 10, B00000000, B00000000, B00000000, B00000000 },
56  { 10, B11111111, B11111111, B11111111, B11111111 },
57  { 10, B00000000, B00000000, B00000000, B00000000 },
58  { 10, B11111111, B11111111, B11111111, B11111111 },
59  { 10, B00000000, B00000000, B00000000, B00000000 },
60  { 10, B11111111, B11111111, B11111111, B11111111 },
61  { 10, B00000000, B00000000, B00000000, B00000000 },
62  { 10, B11111111, B11111111, B11111111, B11111111 },
64  { 10, B00000000, B00000000, B00000000, B00000000 },
65 };
66 
67 static const ServoSequence SeqPanelAllFOpenCloseRepeat PROGMEM =
68 {
69  // Twenty permille (per thousand) offset from start/end positions
70  { 10, B11111111, B11111111, B11111111, B11111111 },
71  { 10, B00000000, B00000000, B00000000, B00000000 },
72  { 10, B11111111, B11111111, B11111111, B11111111 },
73  { 10, B00000000, B00000000, B00000000, B00000000 },
74  { 10, B11111111, B11111111, B11111111, B11111111 },
75  { 10, B00000000, B00000000, B00000000, B00000000 },
76  { 10, B11111111, B11111111, B11111111, B11111111 },
77  { 10, B00000000, B00000000, B00000000, B00000000 },
78  { 10, B11111111, B11111111, B11111111, B11111111 },
79  { 10, B00000000, B00000000, B00000000, B00000000 },
80 };
81 
82 static const ServoSequence SeqPanelWave PROGMEM =
83 {
84  { 30, B00000000, B00000000, B00000000, B00000000 },
85  { 30, B10000000, B00000000, B00000000, B00000000 },
86  { 30, B01000000, B00000000, B00000000, B00000000 },
87  { 30, B00100000, B00000000, B00000000, B00000000 },
88  { 30, B00010000, B00000000, B00000000, B00000000 },
89  { 30, B00001000, B00000000, B00000000, B00000000 },
90  { 30, B00000100, B00000000, B00000000, B00000000 },
91  { 30, B00000010, B00000000, B00000000, B00000000 },
92  { 30, B00000001, B00000000, B00000000, B00000000 },
93  { 30, B00000000, B10000000, B00000000, B00000000 },
94  { 30, B00000000, B01000000, B00000000, B00000000 },
95  { 30, B00000000, B00100000, B00000000, B00000000 },
96  { 30, B00000000, B00010000, B00000000, B00000000 },
97  { 30, B00000000, B00000000, B00000000, B00000000 },
98 };
99 
100 static const ServoSequence SeqPanelWaveFast PROGMEM =
101 {
102  { 15, B00000000, B00000000, B00000000, B00000000 },
103  { 15, B10000000, B00000000, B00000000, B00000000 },
104  { 15, B01000000, B00000000, B00000000, B00000000 },
105  { 15, B00100000, B00000000, B00000000, B00000000 },
106  { 15, B00010000, B00000000, B00000000, B00000000 },
107  { 15, B00001000, B00000000, B00000000, B00000000 },
108  { 15, B00000100, B00000000, B00000000, B00000000 },
109  { 15, B00000010, B00000000, B00000000, B00000000 },
110  { 15, B00000001, B00000000, B00000000, B00000000 },
111  { 15, B00000000, B10000000, B00000000, B00000000 },
112  { 15, B00000000, B01000000, B00000000, B00000000 },
113  { 30, B00000000, B00100000, B00000000, B00000000 },
114  { 30, B00000000, B00010000, B00000000, B00000000 },
115  { 15, B00000000, B00000000, B00000000, B00000000 },
116  { 30, B00000000, B00010000, B00000000, B00000000 },
117  { 30, B00000000, B00100000, B00000000, B00000000 },
118  { 15, B00000000, B01000000, B00000000, B00000000 },
119  { 15, B00000000, B10000000, B00000000, B00000000 },
120  { 15, B00000001, B00000000, B00000000, B00000000 },
121  { 15, B00000010, B00000000, B00000000, B00000000 },
122  { 15, B00000100, B00000000, B00000000, B00000000 },
123  { 15, B00001000, B00000000, B00000000, B00000000 },
124  { 15, B00010000, B00000000, B00000000, B00000000 },
125  { 15, B00100000, B00000000, B00000000, B00000000 },
126  { 15, B01000000, B00000000, B00000000, B00000000 },
127  { 15, B10000000, B00000000, B00000000, B00000000 },
128  { 15, B00000000, B00000000, B00000000, B00000000 },
129 };
130 
131 static const ServoSequence SeqPanelOpenCloseWave PROGMEM =
132 {
133  { 20, B00000000, B00000000, B00000000, B00000000 },
134  { 20, B10000000, B00000000, B00000000, B00000000 },
135  { 20, B11000000, B00000000, B00000000, B00000000 },
136  { 20, B11100000, B00000000, B00000000, B00000000 },
137  { 20, B11110000, B00000000, B00000000, B00000000 },
138  { 20, B11111000, B00000000, B00000000, B00000000 },
139  { 20, B11111100, B00000000, B00000000, B00000000 },
140  { 20, B11111110, B00000000, B00000000, B00000000 },
141  { 20, B11111111, B00000000, B00000000, B00000000 },
142  { 20, B11111111, B10000000, B00000000, B00000000 },
143  { 20, B11111111, B11000000, B00000000, B00000000 },
144  { 20, B11111111, B11100000, B00000000, B00000000 },
145  { 80, B11111111, B11110000, B00000000, B00000000 },
146  { 20, B01111111, B11110000, B00000000, B00000000 },
147  { 20, B00111111, B11110000, B00000000, B00000000 },
148  { 20, B00011111, B11110000, B00000000, B00000000 },
149  { 20, B00001111, B11110000, B00000000, B00000000 },
150  { 20, B00000111, B11110000, B00000000, B00000000 },
151  { 20, B00000011, B11110000, B00000000, B00000000 },
152  { 20, B00000001, B11110000, B00000000, B00000000 },
153  { 20, B00000000, B11110000, B00000000, B00000000 },
154  { 20, B00000000, B01110000, B00000000, B00000000 },
155  { 20, B00000000, B00110000, B00000000, B00000000 },
156  { 20, B00000000, B00010000, B00000000, B00000000 },
157  { 40, B00000000, B00000000, B00000000, B00000000 },
158 };
159 
160 static const ServoSequence SeqPanelMarchingAnts PROGMEM =
161 {
162  // Alternating pattern of on/off
163  { 20, B00000000, B00000000, B00000000, B00000000 },
164  { 50, B10101010, B10101010, B10101010, B10101010 },
165  { 50, B01010101, B01010101, B01010101, B01010101 },
166  { 50, B10101010, B10101010, B10101010, B10101010 },
167  { 50, B01010101, B01010101, B01010101, B01010101 },
168  { 50, B10101010, B10101010, B10101010, B10101010 },
169  { 50, B01010101, B01010101, B01010101, B01010101 },
170  { 50, B10101010, B10101010, B10101010, B10101010 },
171  { 50, B01010101, B01010101, B01010101, B01010101 },
172  { 50, B10101010, B10101010, B10101010, B10101010 },
173  { 50, B01010101, B01010101, B01010101, B01010101 },
174  { 50, B10101010, B10101010, B10101010, B10101010 },
175  { 50, B01010101, B01010101, B01010101, B01010101 },
176  { 50, B10101010, B10101010, B10101010, B10101010 },
177  { 50, B01010101, B01010101, B01010101, B01010101 },
178  { 50, B10101010, B10101010, B10101010, B10101010 },
179  { 50, B01010101, B01010101, B01010101, B01010101 },
180  { 50, B10101010, B10101010, B10101010, B10101010 },
181  { 50, B01010101, B01010101, B01010101, B01010101 },
182  { 50, B10101010, B10101010, B10101010, B10101010 },
183  { 50, B01010101, B01010101, B01010101, B01010101 },
184  { 50, B10101010, B10101010, B10101010, B10101010 },
185  { 50, B01010101, B01010101, B01010101, B01010101 },
186  { 50, B10101010, B10101010, B10101010, B10101010 },
187  { 50, B01010101, B01010101, B01010101, B01010101 },
188  { 50, B10101010, B10101010, B10101010, B10101010 },
189  { 50, B01010101, B01010101, B01010101, B01010101 },
190  { 50, B10101010, B10101010, B10101010, B10101010 },
191  { 50, B01010101, B01010101, B01010101, B01010101 },
192  { 50, B10101010, B10101010, B10101010, B10101010 },
193  { 50, B01010101, B01010101, B01010101, B01010101 },
194  { 100, B00000000, B00000000, B00000000, B00000000 },
195 };
196 
197 static const ServoSequence SeqPanelAlternate PROGMEM =
198 {
199  // Alternating pattern of on/off
200  { 20, B00000000, B00000000, B00000000, B00000000 },
201  { 50, B10101010, B10101010, B10101010, B10101010 },
202  { 50, B01010101, B01010101, B01010101, B01010101 },
203  { 100, B00000000, B00000000, B00000000, B00000000 },
204 };
205 
206 // 1-4 panels
207 // 5-6 large panels
208 // 7-10 pie panels
209 // 11-12 mini doors
210 // 13 pie door
211 static const ServoSequence SeqPanelDance PROGMEM =
212 {
213  { 10, B00000000, B00000000, B00000000, B00000000 }, // 4 pie, 1 by one
214  { 45, B00000010, B00000000, B00000000, B00000000 },
215  { 45, B00000011, B00000000, B00000000, B00000000 },
216  { 45, B00000011, B10000000, B00000000, B00000000 },
217  { 45, B00000011, B11000000, B00000000, B00000000 },
218  { 45, B00000011, B10000000, B00000000, B00000000 },
219  { 45, B00000011, B00000000, B00000000, B00000000 },
220  { 45, B00000010, B00000000, B00000000, B00000000 },
221 
222  { 45, B00000000, B00000000, B00000000, B00000000 }, // 4 side, 1 by one
223  { 45, B10000000, B00000000, B00000000, B00000000 },
224  { 45, B11000000, B00000000, B00000000, B00000000 },
225  { 45, B11100000, B00000000, B00000000, B00000000 },
226  { 45, B11110000, B00000000, B00000000, B00000000 },
227  { 45, B01110000, B00000000, B00000000, B00000000 },
228  { 45, B00110000, B00000000, B00000000, B00000000 },
229  { 45, B00010000, B00000000, B00000000, B00000000 },
230 
231  { 45, B00000000, B00000000, B00000000, B00000000 }, // 4 pies. 2 by 2
232  { 45, B00000010, B10000000, B00000000, B00000000 },
233  { 45, B00000000, B00000000, B00000000, B00000000 },
234  { 45, B00000001, B01000000, B00000000, B00000000 },
235  { 45, B00000000, B00000000, B00000000, B00000000 },
236  { 45, B00000011, B11000000, B00000000, B00000000 },
237  { 45, B00000001, B01000000, B00000000, B00000000 },
238  { 45, B00000010, B10000000, B00000000, B00000000 },
239 
240  { 45, B00000000, B00000000, B00000000, B00000000 }, // 2 large sides
241  { 45, B00001000, B00000000, B00000000, B00000000 },
242  { 45, B00000000, B00000000, B00000000, B00000000 },
243  { 45, B00000100, B00000000, B00000000, B00000000 },
244  { 45, B00000000, B00000000, B00000000, B00000000 },
245  { 45, B11111100, B00000000, B00000000, B00000000 },
246  { 45, B01111100, B00000000, B00000000, B00000000 },
247  { 45, B00011100, B00000000, B00000000, B00000000 },
248 
249  { 45, B00000000, B00000000, B00000000, B00000000 }, // interleaved
250  { 45, B01010000, B00000000, B00000000, B00000000 },
251  { 45, B00000000, B00000000, B00000000, B00000000 },
252  { 45, B10100000, B00000000, B00000000, B00000000 },
253  { 45, B00000000, B00000000, B00000000, B00000000 },
254  { 45, B00000001, B01000000, B00000000, B00000000 },
255  { 45, B00000010, B10000000, B00000000, B00000000 },
256  { 45, B00000001, B01000000, B00000000, B00000000 },
257 
258  { 45, B00000000, B00000000, B00000000, B00000000 }, // 2nd interleaved
259  { 45, B00000011, B11000000, B00000000, B00000000 },
260  { 45, B00000001, B01000000, B00000000, B00000000 },
261  { 45, B00000010, B10000000, B00000000, B00000000 },
262  { 45, B00000001, B01000000, B00000000, B00000000 },
263  { 45, B00000010, B10000000, B00000000, B00000000 },
264  { 45, B00000001, B01000000, B00000000, B00000000 },
265  { 45, B10101010, B10000000, B00000000, B00000000 },
266 
267  { 45, B00000000, B00000000, B00000000, B00000000 }, //
268  { 45, B00000010, B10000000, B00000000, B00000000 },
269  { 45, B00000001, B01000000, B00000000, B00000000 },
270  { 45, B00000010, B10000000, B00000000, B00000000 },
271  { 45, B00000001, B01000000, B00000000, B00000000 },
272  { 45, B10101010, B10000000, B00000000, B00000000 },
273  { 45, B01010101, B01000000, B00000000, B00000000 },
274  { 45, B10101010, B10000000, B00000000, B00000000 },
275 
276  { 45, B00000000, B00000000, B00000000, B00000000 }, //
277  { 45, B11000000, B00000000, B00000000, B00000000 },
278  { 45, B00110000, B00000000, B00000000, B00000000 },
279  { 45, B00001100, B00000000, B00000000, B00000000 },
280  { 45, B00000000, B00000000, B00000000, B00000000 },
281  { 45, B11001100, B11000000, B00000000, B00000000 },
282  { 45, B00110011, B00000000, B00000000, B00000000 },
283  { 45, B11001100, B11000000, B00000000, B00000000 },
284 
285  { 45, B00000000, B00000000, B00000000, B00000000 }, // transition
286  { 45, B10000000, B00000000, B00000000, B00000000 },
287  { 45, B00000000, B00000000, B00000000, B00000000 },
288  { 45, B01000000, B00000000, B00000000, B00000000 },
289  { 45, B00000000, B00000000, B00000000, B00000000 },
290  { 45, B11100000, B00000000, B00000000, B00000000 },
291  { 45, B01100000, B00000000, B00000000, B00000000 },
292  { 45, B00100000, B00000000, B00000000, B00000000 },
293  { 45, B00000000, B00000000, B00000000, B00000000 },
294 
295  { 45, B00000010, B10000000, B00000000, B00000000 }, // good
296  { 45, B00000000, B00000000, B00000000, B00000000 },
297  { 45, B00000001, B01000000, B00000000, B00000000 },
298  { 45, B00000000, B00000000, B00000000, B00000000 },
299  { 45, B00000010, B10000000, B00000000, B00000000 },
300  { 45, B00000001, B01000000, B00000000, B00000000 },
301  { 45, B00000010, B10000000, B00000000, B00000000 },
302  { 45, B00000000, B00000000, B00000000, B00000000 },
303  { 45, B10101010, B10000000, B00000000, B00000000 },
304  { 45, B01010101, B01000000, B00000000, B00000000 },
305  { 45, B00000000, B00000000, B00000000, B00000000 },
306  { 45, B11111111, B11000000, B00000000, B00000000 },
307  { 45, B00000011, B11000000, B00000000, B00000000 },
308  { 45, B11111100, B00000000, B00000000, B00000000 },
309  { 45, B00000000, B00000000, B00000000, B00000000 },
310  { 45, B00000000, B00001000, B00000000, B00000000 }, // tip of the hat
311  { 500, B00000000, B00000000, B00000000, B00000000 },
312 };
313 
314 static const ServoSequence SeqPanelLongDisco PROGMEM =
315 {
316  { 15, B00000000, B00000000, B00000000, B00000000 },
317  { 15, B10000000, B00000000, B00000000, B00000000 },
318  { 15, B01000000, B00000000, B00000000, B00000000 },
319  { 15, B00100000, B00000000, B00000000, B00000000 },
320  { 15, B00010000, B00000000, B00000000, B00000000 },
321  { 15, B00001000, B00000000, B00000000, B00000000 },
322  { 15, B00000100, B00000000, B00000000, B00000000 },
323  { 15, B00000010, B00000000, B00000000, B00000000 },
324  { 15, B00000001, B00000000, B00000000, B00000000 },
325  { 15, B00000000, B10000000, B00000000, B00000000 },
326  { 15, B00000000, B01000000, B00000000, B00000000 },
327  { 15, B00000000, B00000000, B00000000, B00000000 },
328  { 15, B00000000, B01000000, B00000000, B00000000 },
329  { 15, B00000000, B10000000, B00000000, B00000000 },
330  { 15, B00000001, B00000000, B00000000, B00000000 },
331  { 15, B00000010, B00000000, B00000000, B00000000 },
332  { 15, B00000100, B00000000, B00000000, B00000000 },
333  { 15, B00001000, B00000000, B00000000, B00000000 },
334  { 15, B00010000, B00000000, B00000000, B00000000 },
335  { 15, B00100000, B00000000, B00000000, B00000000 },
336  { 15, B01000000, B00000000, B00000000, B00000000 },
337  { 15, B10000000, B00000000, B00000000, B00000000 },
338  { 15, B00000000, B00000000, B00000000, B00000000 }, // 3.45 seconds
339  { 36000, B00000000, B00000000, B00000000, B00000000 }, // 6 minutes
340  { 2200, B00000000, B00000000, B00000000, B00000000 }, // 22 seconds
341 };
342 
343 static const ServoSequence SeqPanelLongHarlemShake PROGMEM =
344 {
345  { 45, B00000000, B00000000, B00000000, B00000000 },
346  { 45, B10000000, B00000000, B00000000, B00000000 },
347  { 45, B01000000, B00000000, B00000000, B00000000 },
348  { 45, B00100000, B00000000, B00000000, B00000000 },
349  { 45, B00010000, B00000000, B00000000, B00000000 },
350  { 45, B00001000, B00000000, B00000000, B00000000 },
351  { 45, B00000100, B00000000, B00000000, B00000000 },
352  { 45, B00000010, B00000000, B00000000, B00000000 },
353  { 45, B00000001, B00000000, B00000000, B00000000 },
354  { 45, B00000000, B10000000, B00000000, B00000000 },
355  { 45, B00000000, B01000000, B00000000, B00000000 },
356  { 45, B00000000, B00000000, B00000000, B00000000 },
357  { 45, B00000000, B01000000, B00000000, B00000000 },
358  { 45, B00000000, B10000000, B00000000, B00000000 },
359  { 45, B00000001, B00000000, B00000000, B00000000 },
360  { 45, B00000010, B00000000, B00000000, B00000000 },
361  { 45, B00000100, B00000000, B00000000, B00000000 },
362  { 45, B00001000, B00000000, B00000000, B00000000 },
363  { 45, B00010000, B00000000, B00000000, B00000000 },
364  { 45, B00100000, B00000000, B00000000, B00000000 },
365  { 45, B01000000, B00000000, B00000000, B00000000 },
366  { 45, B10000000, B00000000, B00000000, B00000000 },
367  { 45, B00000000, B00000000, B00000000, B00000000 },
368 };
369 
370 #define SEQUENCE_PLAY_ONCE(sequencer, sequence, groupMask) \
371  (sequencer).play(sequence, SizeOfArray(sequence), groupMask)
372 #define SEQUENCE_PLAY_ONCE_SPEED(sequencer, sequence, groupMask, speed) \
373  (sequencer).play(sequence, SizeOfArray(sequence), groupMask, speed)
374 #define SEQUENCE_PLAY_ONCE_VARSPEED(sequencer, sequence, groupMask, minspeed, maxspeed) \
375  (sequencer).playVariableSpeed(sequence, SizeOfArray(sequence), groupMask, minspeed, maxspeed)
376 #define SEQUENCE_PLAY_RANDOM_STEP(sequencer, sequence, groupMask) \
377  (sequencer).play(&sequence[random(SizeOfArray(sequence))], 1, groupMask)
378 #define SEQUENCE_PLAY_ONCE_VARSPEED_EASING(sequencer, sequence, groupMask, minspeed, maxspeed, onEasing, offEasing) \
379  (sequencer).playVariableSpeed(sequence, SizeOfArray(sequence), groupMask, minspeed, maxspeed, 0.0, 1.0, onEasing, offEasing)
380 
381 
390 {
391 public:
393  fDispatch(dispatch)
394  {
395  stop();
396  }
397 
398  void playVariableSpeed(const ServoStep* sequence, uint16_t length, uint32_t servoGroupMask,
399  uint16_t speedMinMS, uint16_t speedMaxMS, float startPos = 0.0, float endPos = 1.0,
400  float (*onEasingMethod)(float) = NULL, float (*offEasingMethod)(float) = NULL)
401  {
402  stop();
403  fSequence = (ServoStep*)sequence;
404  fServoGroupMask = servoGroupMask;
405  fLength = length;
406  fStartPos = startPos;
407  fEndPos = endPos;
408  fSpeedMinMS = speedMinMS;
409  fSpeedMaxMS = speedMaxMS;
410  fNextStepMS = millis();
411  fOffsetFromStart = 0;
412  fOffsetFromEnd = 0;
413  fIndex = 0;
414  fOnEasingMethod = onEasingMethod;
415  fOffEasingMethod = offEasingMethod;
416  }
417 
418  void play(const ServoStep* sequence, uint16_t length, uint32_t servoGroupMask,
419  uint16_t speedMS = 0, float startPos = 0.0, float endPos = 1.0)
420  {
421  playVariableSpeed(sequence, length, servoGroupMask, speedMS, speedMS, startPos, endPos);
422  }
423 
424  void stop()
425  {
426  fSequence = NULL;
427  fLength = 0;
428  fNextStepMS = 0;
429  }
430 
431  inline bool isFinished() const
432  {
433  return (fSequence == nullptr);
434  }
435 
436  virtual void animate() override
437  {
438  unsigned long currentTime;
439  if (fSequence == NULL || (currentTime = millis()) < fNextStepMS)
440  return;
441  if (fIndex >= fLength)
442  {
443  stop();
444  return;
445  }
446  uint32_t servoSetMask = 0;
447  const ServoStep* step = &fSequence[fIndex];
448  while (pgm_read_word(&step->cs) == uint16_t(~0))
449  {
450  // Check for an initial range limiting step
451  uint16_t offsetFromStart = 0;
452  uint16_t offsetFromEnd = 0;
453  offsetFromStart |= (uint32_t)pgm_read_byte(&step->servo1_8) << 8;
454  offsetFromStart |= (uint32_t)pgm_read_byte(&step->servo9_16);
455  offsetFromEnd |= (uint32_t)pgm_read_byte(&step->servo17_24) << 8;
456  offsetFromEnd |= (uint32_t)pgm_read_byte(&step->servo25_32);
457  fOffsetFromStart = (offsetFromStart / 1000.0);
458  fOffsetFromEnd = (offsetFromEnd / 1000.0);
459  fIndex++;
460  if (fIndex >= fLength)
461  {
462  stop();
463  return;
464  }
465  step = &fSequence[fIndex];
466  }
467  servoSetMask |= (uint32_t)pgm_read_byte(&step->servo1_8) << 24;
468  servoSetMask |= (uint32_t)pgm_read_byte(&step->servo9_16) << 16;
469  servoSetMask |= (uint32_t)pgm_read_byte(&step->servo17_24) << 8;
470  servoSetMask |= (uint32_t)pgm_read_byte(&step->servo25_32) << 0;
471  uint32_t ms = pgm_read_word(&fSequence[fIndex].cs) * 10L;
472  fNextStepMS = currentTime + fSpeedMinMS + ms;
473  fDispatch.moveServoSetTo(fServoGroupMask, servoSetMask, 0,
474  fSpeedMinMS, fSpeedMaxMS, fEndPos-fOffsetFromEnd, fStartPos+fOffsetFromStart, fOnEasingMethod, fOffEasingMethod);
475  fIndex++;
476  }
477 
479  {
480  return fDispatch;
481  }
482 
483 private:
484  ServoDispatch& fDispatch;
485  ServoStep* fSequence;
486  uint16_t fLength = 0;
487  uint16_t fIndex = 0;
488  float fOffsetFromStart;
489  float fOffsetFromEnd;
490  float fStartPos;
491  float fEndPos;
492  uint16_t fSpeedMinMS;
493  uint16_t fSpeedMaxMS;
494  uint32_t fServoGroupMask;
495  uint32_t fNextStepMS;
496  float (*fOnEasingMethod)(float);
497  float (*fOffEasingMethod)(float);
498 };
499 
500 #endif
ServoDispatch.h
ServoStep::servo1_8
uint8_t servo1_8
Definition: ServoSequencer.h:20
ServoStep::servo17_24
uint8_t servo17_24
Definition: ServoSequencer.h:22
ReelTwo.h
AnimatedEvent
Base class for all animated devices. AnimatedEvent::animate() is called for each device once through ...
Definition: AnimatedEvent.h:18
SEQUENCE_RANGE_LIMIT
#define SEQUENCE_RANGE_LIMIT(offsetFromMin, offsetFromMax)
Definition: ServoSequencer.h:9
ServoSequencer::stop
void stop()
Definition: ServoSequencer.h:424
AnimatedEvent.h
ServoSequencer::playVariableSpeed
void playVariableSpeed(const ServoStep *sequence, uint16_t length, uint32_t servoGroupMask, uint16_t speedMinMS, uint16_t speedMaxMS, float startPos=0.0, float endPos=1.0, float(*onEasingMethod)(float)=NULL, float(*offEasingMethod)(float)=NULL)
Definition: ServoSequencer.h:398
ServoStep::servo25_32
uint8_t servo25_32
Definition: ServoSequencer.h:23
ServoSequencer
Plays a sequence of servo commands using a servo group mask.
Definition: ServoSequencer.h:389
ServoSequencer::ServoSequencer
ServoSequencer(ServoDispatch &dispatch)
Definition: ServoSequencer.h:392
ServoSequencer::play
void play(const ServoStep *sequence, uint16_t length, uint32_t servoGroupMask, uint16_t speedMS=0, float startPos=0.0, float endPos=1.0)
Definition: ServoSequencer.h:418
ServoDispatch::moveServoSetTo
void moveServoSetTo(uint32_t servoGroupMask, uint32_t servoSetMask, float onPos, float offPos, float(*onEasingMethod)(float)=NULL, float(*offEasingMethod)(float)=NULL)
Definition: ServoDispatch.h:172
ServoStep::servo9_16
uint8_t servo9_16
Definition: ServoSequencer.h:21
ServoDispatch
Servo interace implemented eitehr by ServoDispatchPCA9685 or ServoDispatchDirect.
Definition: ServoDispatch.h:83
ServoSequence
struct ServoStep ServoSequence[]
Definition: ServoSequencer.h:26
ServoStep::cs
uint16_t cs
Definition: ServoSequencer.h:19
ServoStep
Single frame of servo animation. Time is specified in centi seconds (1/100th of a second)
Definition: ServoSequencer.h:17
ServoSequencer::isFinished
bool isFinished() const
Definition: ServoSequencer.h:431
ServoSequencer::animate
virtual void animate() override
Subclasses must implement this function to run through a single frame of animation/activity.
Definition: ServoSequencer.h:436
ServoSequencer::dispatch
ServoDispatch & dispatch()
Definition: ServoSequencer.h:478