| Parola for Arduino 1.0 Text effects for Parola modular hardware

- Main Page
- Related Pages
- Classes
- Files

- File List

MD_Parola.h
1 /**
2 \mainpage Library for scrolling text effects using Parola hardware
3 The Parola Library
4 ------------------
5 The Parola library is implemented to work with the Parola hardware. It
6 depends on the MD_MAX72xx library for hardware control.
7
8 This software library implements functions to simplify the implementation
9 of text special effects on the Parola display.
10 - Left, right or center text justification in the display field.
11 - Text scrolling, text entering and exit effects.
12 - Control display parameters and animation speed.
13
14 The latest copy of the Parola Software and hardware files can be found
15 at the [Parola website] (http://code.google.com/p/parola-for-arduino).
16
17 ![The final product with 8 modules connected together] (Working_Display.jpg "Working System")
18
19 System Components
20 -----------------
21 - \subpage pageHardware
22 - \subpage pageSoftware
23 - \subpage pageConnection
24
25 Revision History
26 ----------------
27 June 2013 - version 1.0
28 - New library
29
30 Copyright
31 ---------
32 Copyright (C) 2013 Marco Colli. All rights reserved.
33
34 This library is free software; you can redistribute it and/or
35 modify it under the terms of the GNU Lesser General Public
36 License as published by the Free Software Foundation; either
37 version 2.1 of the License, or (at your option) any later version.
38
39 This library is distributed in the hope that it will be useful,
40 but WITHOUT ANY WARRANTY; without even the implied warranty of
41 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
42 Lesser General Public License for more details.
43
44 You should have received a copy of the GNU Lesser General Public
45 License along with this library; if not, write to the Free Software
46 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
47
48 \page pageSoftware Parola Software
49 The Parola Library
50 ------------------
51 The Parola library is implemented using the MD_MAX72xx library for hardware
52 control. The library implements functions to simplify the implementation
53 of text special effects on the LED matrix.
54 - Text left, right or center justification in the display
55 - Text scrolling, appearance and disappearance effects
56 - Control display parameters and animation speed
57
58 ### External Dependencies
59 - Parola uses the MD_MAX72xx library for hardware level control primitives.
60 The latest copy of this library can be found
61 [here] (http://code.google.com/p/arduino-code-repository).
62
63 Implementing New Text Effects
64 -----------------------------
65 Each of the selected text effects is implemented as a function. This makes it easy to add new
66 effects:
67 - Choose a name for the effect and add it to the textEffect_t enumerated type.
68 - Clone an existing method and modify it according to the guidelines below.
69 - Add the function prototype for the new effect to the class definition
70 (at the bottom of the MD_Parola.h file).
71 - Modify the displayAnimate() method in MD_Parola.cpp to invoke the new method.
72
73 ###New Text Effects
74 The effects functions are implemented as finite state machines that are called with the
75 frequency set by the setSpeed() method. The class variable _fsmState holds the state from
76 the last invocation of an effect method.
77
78 An effect method can work in one of 2 ways:
79 - *Additive*: where the animation frames are incrementally built up to the initial display.
80 With this method, the function will need to use the getFirstChar() and getNextChar() methods
81 to build up the displayed text, column by column.
82 - *Subtractive*: where the final displayed text is placed in the buffer using the commonPrint()
83 method and the elements that are not visible at that stage of the animation are removed.
84
85 Which algorithm is used depends on the type animation and what is convenient for the coder.
86 Examples of both are found in the supplied library text effects.
87
88 Each effect method is implemented in 2 parts. One part implements the text move IN to the display
89 (method parameter bIn is true) and the other when the text is moving OUT of the display (bIn false).
90 Because the IN and OUT effects can be different for a display cycle, the method must not assume
91 that the first part was ever called. The first phase should always end with the text in its
92 display position (depending on the alignment specified) and the second phase should assume the text
93 is in that position when called. Text position parameters are held in the class variable _limitLeft,
94 _limitRight,
95
96 The first phase starts with _fsmState set to INITIALISE and ends when the state is set to PAUSE
97 in the effect method. The second phase starts with a PAUSE state and ends when the state is set to
98 END by the method. Aside from the INITIALISE state (set by the displayReset() method), all other
99 state changes are under the control of the effect functions.
100
101 Coding Tips
102 -----------
103 + The MD_MAX72XX library sets the origin for the LED matrix at the top right of the display. This
104 makes the text leftmost column a higher column number that the far right column. Sometimes this
105 is not intuitive when coding and is worth remembering. Rows are numbered from top to bottom.
106
107 + Ensure that a new effect is tested in combination with other effects to make sure that transitions
108 are smooth and the IN and OUT effects combine weel. Common errors are misaligned entry compared to
109 exit, with causes a small jump in the text position when the effects are combined.
110
111 + Display update times grow with the number of modules there are in a display, so some timing
112 paramaters will need to adapt. In most cases the animations will simply slow down.
113 As an example, a 6 module chain updates in approximately 14ms, while a 12 module display
114 takes around 25ms.
115 Most of the time taken is to physically update the display, as animating frames takes about
116 1-2ms to update in the MD_MAX72XX display buffers.
117
118 \page pageHardware Parola Hardware
119 Design
120 ------
121 The aim was to create a 'lego-like' approach to LED matrix display, using standard 8x8 on
122 LED matrices. The software supports this flexibility through a scalable approach that
123 only requires the definition of the number of modules to adapt existing software to
124 a new configuration.
125
126 ![Completed Parola module with and without the LED matrix] (PCB_Actual.jpg "Parola Modules")
127
128 Circuit Schematic
129 -----------------
130 The schematic is the basic application circuit that is found on the MAX7219 datasheet,
131 adapted to the LED matrix. Each Parola Module consists of an 8x8 LED Common Anode matrix
132 controlled by a MAX7219 LED controller and a few passive components. These controllers
133 can be daisy chained, making them ideal for the purpose.
134
135 ![Parola Circuit Schematic] (Circuit_Schematic.jpg "Parola Schematic")
136
137 PCB Design
138 ----------
139 The PCD design was executed using the autorouting facility in Eagle CAD, and the PCB was
140 manufactured by SeedStudio. The Eagle CAD files for the layout and the Gerber files
141 suitable for SeedStudio are found on the [Parola website] (http://code.google.com/p/parola-for-arduino).
142 The final design includes edge connections that allow many modules to be connected
143 together into an extended display one LED module high.
144
145 ![PCB layout ready for manufacture] (PCB_Layout.jpg "PCB Design")
146
147 \page pageConnection System Connections
148 Connecting Parola to the Arduino
149 --------------------------------
150 The modules are connected through a 4-wire serial interface (SPI), and devices are cascaded,
151 with communications passed through the first device in the chain to all others. The Arduino
152 should be connected to the IN side (shown in the figure below) of the first module in the chain.
153
154 ![Module Input Header] (Connector.jpg "Connection In")
155
156 The Arduino interface is implemented with 3 digital outputs that are passed through to
157 the class constructor. The digital outputs define the SPI interface as follows:
158 - DIN - the Data IN signal shifts data into the display module. Data is loaded into
159 the device's internal 16-bit shift register on CLK's rising edge.
160 - CLK - the CLocK signal that is used to time the data for the device.
161 - LD - the interface is active when LoaD signal is LOW. Serial data are loaded into the
162 device shift register while LOAD is LOW and latched in on the riding edge.
163
164 Note that the LD signal is used to select the entire device chain. This allows separate LD
165 outputs to control multiple Parola displays sharing the same DIN and CLK signals. The
166 software needs to instantiate a separate object for each display.
167
168 The remaining interface pins are for +5V and GND. The power supply must be able to supply
169 enough current for the number of connected Parola modules. The central position of the GND
170 connector provides some protection for accidentally reversing the connector.
171
172 Connecting Parola Modules
173 -------------------------
174 Separate Parola modules are connected by the plugging them together edge to edge, with the
175 OUT side of one module plugged to the IN side of the next, as shown in the figure below.
176
177 ![Connecting Parola modules] (Modules_conn.jpg "Modules connected")
178 */
179 #ifndef _MD_PAROLA_H
180 #define _MD_PAROLA_H
181
182 #include <Arduino.h>
183 #include <MD_MAX72xx.h>
184
185 // Miscellaneous defines
186 #define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
187
188 /**
189 * Core object for the Parola library
190 */
191 class MD_Parola
192 {
193 public:
194 /**
195 * Text alignment specification.
196 *
197 * Used to define the display text aligmnent and to specify direction for
198 * scrolling and animations. In the situation where LEFT AND RIGHT are the onty sensible
199 * options (eg, text scrolling direction), CENTER will behave the same as LEFT.
200 */
201 enum textPosition_t
202 {
203 LEFT, ///< The leftmost column for the first character will be on the left side of the display
204 CENTER, ///< The text will be placed with equal number of blank display columns either side
205 RIGHT ///< The rightmost column of the last character will be on the right side of the display
206 };
207
208 /**
209 * Special effect specification.
210 *
211 * Used to define the effects to be used for the entry and exit of text in the display area.
212 */
213 enum textEffect_t
214 {
215 NO_EFFECT, ///< Used as a place filler, executes no operation
216 PRINT, ///< Text just appears (printed)
217 SLICE, ///< Text enters and exits a slice (column) at a time
218 WIPE, ///< Text appears/disappears one column at a time, looks like it is wiped on and off
219 WIPE_CURSOR, ///< WIPE with a light bar ahead of the change
220 OPENING, ///< Appear and disappear from the center of the display, towards the ends
221 OPENING_CURSOR, ///< OPENING with light bars ahead of the change
222 CLOSING, ///< Appear and disappear from the ends of the display, tords the middle
223 CLOSING_CURSOR, ///< CLOSING with light bars ahead of the change
224 BLINDS, ///< Text is replaced behind vertical blinds
225 DISSOLVE, ///< Text dissolves from one display to another
226 SCROLL_UP, ///< Text scrolls up through the display
227 SCROLL_DOWN, ///< Text scrolls down through the display
228 SCROLL_LEFT, ///< Text scrolls right to left on the display
229 SCROLL_RIGHT, ///< Text scrolls left to right on the display
230 };
231
232 /**
233 * Class Constructor.
234 *
235 * Instantiate a new instance of the class. The parameters passed are used to
236 * connect the software to the hardware using the MD_MAX72XX class.
237 *
238 * See documentation for the MD_MAX72XX library for detailed explanation of parameters.
239 *
240 * \param dataPin output on the Arduino where data gets shifted out.
241 * \param clkPin output for the clock signal.
242 * \param csPin output for selecting the device.
243 * \param numDevices number of devices connected. Default is 1 if not supplied.
244 */
245 MD_Parola(uint8_t dataPin, uint8_t clkPin, uint8_t csPin, uint8_t numDevices=1);
246
247 /**
248 * Class Destructor.
249 *
250 * Release allocated memory and does the necessary to clean up once the object is
251 * no longer required.
252 */
253 ~MD_Parola(void);
254
255 //--------------------------------------------------------------
256 /** \name Methods for core object control.
257 * @{
258 */
259 /**
260 * Animate the display.
261 *
262 * Animate the display using the currently specifed text and animation parameters.
263 * This method needs to be invoked as often as possible to ensure smooth animation.
264 * The animation is goiverened by a time tick that is set by the setSpeed() method
265 * and it will pause between entry and exit using the time set by the setPause() method.
266 *
267 * The calling program should monitor the return value for a true in order to either
268 * reset the animation or supply another string for display.
269 *
270 * \return bool true if the current animation has competed, false otherwise.
271 */
272 bool displayAnimate(void);
273
274 /**
275 * Clear the display.
276 *
277 * Clear all the data from the current display.
278 *
279 * \return No return value.
280 */
281 inline void displayClear() { _D.clear(); };
282
283 /**
284 * Reset the current animation to restart.
285 *
286 * This method is used to reset an animation back to the start of the current cycle.
287 * It is normally invoked after all the parameters for a display are set and the
288 * animation needs to be started (or restarted).
289 *
290 * \return No return value.
291 */
292 void displayReset(void);
293
294 /**
295 * Easy start for a scrolling text display.
296 *
297 * This method is a convenient way to set up a scrolling display. All the data
298 * necessary for setup is passed through as parameters and the display animation
299 * is started.
300 *
301 * \param pText parameter suitable for the setTextBuffer() method.
302 * \param align parameter suitable for the the setTextAlignment() method.
303 * \param effect parameter suitable for the the setTextEffect() method.
304 * \param speed parameter suitable for the setSpeed() method.
305 * \return No return value.
306 */
307 void displayScroll(char *pText, textPosition_t align, textEffect_t effect, uint16_t speed);
308
309 /**
310 * Suspend or resume display updates.
311 *
312 * Stopthe current animation at the point it is at. When pausing it leaves the
313 * display showing the current text. Resuming will restart the animation where
314 * it left off. To reset the animation back to the beginning, use the
315 * displayReset() method.
316 *
317 * \param b boolean value to suspend(true) or resume (false).
318 * \return No return value.
319 */
320 inline void displaySuspend(bool b) { _suspend = b; };
321
322 /**
323 * Easy start for a non-scrolling text display.
324 *
325 * This method is a convenient way to set up a static text display. All the data
326 * necessary for setup is passed through as parameters and the display animation
327 * is started.
328 *
329 * \param pText parameter suitable for the setTextBuffer() method.
330 * \param align parameter suitable for the the setTextAlignment() method.
331 * \param speed parameter suitable for the setSpeed() method.
332 * \param pause parameter suitable for the setPause() method.
333 * \param effectIn parameter suitable for the setTextEffect() method.
334 * \param effectOut parameter suitable for the setTextEffect() method.
335 * \return No return value.
336 */
337 void displayText(char *pText, textPosition_t align, uint16_t speed, uint16_t pause, textEffect_t effectIn, textEffect_t effectOut = NO_EFFECT);
338
339 /** @} */
340 //--------------------------------------------------------------
341 /** \name Support methods for visually adjusting the display.
342 * @{
343 */
344
345 /**
346 * Get the inter-character spacing in columns.
347 *
348 * \return the current setting for the space between characters in columns.
349 */
350 inline uint8_t getCharSpacing(void) { return _charSpacing; };
351
352 /**
353 * Get the current pause time.
354 *
355 * See the setPause() method.
356 *
357 * \return the pause value in milliseconds.
358 */
359 inline uint16_t getPause(void) { return _pauseTime; };
360
361 /**
362 * Get the current animation speed.
363 *
364 * See the setSpeed() method
365 *
366 * \return the speed value.
367 */
368 inline uint16_t getSpeed(void) { return _tickTime; };
369
370 /**
371 * Get the current text alignment specification.
372 *
373 * \return the current text alignment setting.
374 */
375 inline textPosition_t getTextAlignment(void) { return _textAlignment; };
376
377 /**
378 * Set the inter-character spacing in columns.
379 *
380 * Set the number of blank columns between characters when they are displayed.
381 *
382 * \param cs space between characters in columns.
383 * \return No return value.
384 */
385 inline void setCharSpacing(uint8_t cs) { _charSpacing = cs; };
386
387 /**
388 * Set the display brightness.
389 *
390 * Set the intensity (brightness) of the display.
391 *
392 * \param intensity The intensity to set the display (0-15).
393 * \return No return value.
394 */
395 inline void setIntensity(uint8_t intensity) { _D.control(MD_MAX72XX::INTENSITY, intensity); };
396
397 /**
398 * Set the pause between ENTER and EXIT animations.
399 *
400 * Between each entry and exit, the libray will pause by the number of milliseconds
401 * specified to allow the viewer to read the message. For continuous scrolling displays
402 * this should be set to the same value as the display speed.
403 *
404 * \param pause the time, in milliseconds, between animations.
405 * \return No return value.
406 */
407 inline void setPause(uint16_t pause) { _pauseTime = pause; /*(pause > _tickTime ? pause : _tickTime);*/ };
408
409 /**
410 * Set the animation frame speed.
411 *
412 * The speed of the display is the 'tick' time between animation frames. The lower this time
413 * the faster the animation; set it to zero to run as fast as possible.
414 *
415 * \param speed the time, in milliseconds, between animation frames.
416 * \return No return value.
417 */
418 inline void setSpeed(uint16_t speed) { _tickTime = speed; /*_pauseTime = (_pauseTime > _tickTime ? _pauseTime : _tickTime); */ };
419
420 /**
421 * Set the text alignment.
422 *
423 * Text alignment is specified as one of the values in textPosition_t.
424 *
425 * \param ta the required text alignment.
426 * \return No return value.
427 */
428 inline void setTextAlignment(textPosition_t ta) { _textAlignment = ta; };
429
430 /**
431 * Set the pointer to the text buffer.
432 *
433 * Sets the text buffer to be a pointer to user data. The library does not allocate
434 * any memory for the text message, rather it is the calling program that supplies
435 * a pointer to a buffer. This reduces memory requirements and offers the flexibility
436 * to keep a single buffer or rotate buffers with different messages, all under calling
437 * program control, with no livbrary limit to the size or numbers of buffers. The text
438 * placed in the buffer must be properly terminated by the NUL ('\0') character or
439 * processing will overrun the end of the message.
440 *
441 * \param pb pointer to the text buffer to be used.
442 * \return No return value.
443 */
444 inline void setTextBuffer(char *pb) { _pText = pb; };
445
446 /**
447 * Set the entry and exit text effects.
448 *
449 * The 'in' and 'out' text effects are specified using the textEffect_t enumerated
450 * type. If no effect is required, NO_EFFECT should be specified. NO_EFFECT
451 * is most useful when no exit effect is required (e.g., when DISSOLVE is used) and
452 * the entry effect is sufficient.
453 *
454 * \param effectIn the entry effect, one of the textEffect_t enumerated values.
455 * \param effectOut the exit effect, one of the textEffect_t enumerated values.
456 * \return No return value.
457 */
458 inline void setTextEffect(textEffect_t effectIn, textEffect_t effectOut) { _effectIn = effectIn, _effectOut = effectOut; };
459
460 /** @} */
461
462 private:
463 /***
464 * Finite State machine states enumerated type.
465 */
466 enum fsmState_t
467 {
468 INITIALISE, ///< Initialise all variables
469 GET_FIRST_CHAR, ///< Get the first character
470 GET_NEXT_CHAR, ///< Get the next character
471 PUT_CHAR, ///< Placing a character
472 PUT_FILLER, ///< Placing filler (blank) columns
473 PAUSE, ///< Pausing between anmations
474 END ///< Display cycle has completed
475 };
476
477 // The display hardware controlled by this library
478 MD_MAX72XX _D;
479
480 // Time and speed controlling data and methods
481 bool _suspend; // don't do anything
482 uint32_t _lastRunTime; // the millis() value for when the animation was last run
483 uint16_t _tickTime; // the time between animations in milliseconds
484 uint16_t _pauseTime; // time to pause the animation between 'in' and 'out'
485
486 // Display control data and methods
487 fsmState_t _fsmState; // fsm state for all FSMs used to display text
488 uint16_t _textLen; // length of current text in columns
489 int16_t _limitLeft; // leftmost limit for the current display effect
490 int16_t _limitRight; // rightmost limit for the current display effect
491 bool _limitOverflow; // true if the text will overflow the display
492 textPosition_t _textAlignment; // current text alignment
493 textEffect_t _effectIn; // the effect for text entering the display
494 textEffect_t _effectOut; // the effect for text exiting the display
495 bool _moveIn; // animation is movein IN when true, OUT when false
496 void setInitialConditions(void); // set up initial conditions for an effect
497 uint16_t getTextWidth(char *p); // width of text in columns
498 bool calcTextLimits(char *p); // calculate the right and left limits for the text
499
500 // Character buffer handling data and methods
501 char *_pText; // pointer to text buffer from user call
502 char *_pCurChar; // the current character being processed in the text
503 bool _endOfText; // true when the end of the text string has been reached.
504 void moveTextPointer(void); // move the text pointer depending on direction of buffer scan
505 uint8_t getFirstChar(void); // put the first Text char into the char buffer
506 uint8_t getNextChar(void); // put the next Text char into the char buffer
507
508 // Font character handling data and methods
509 uint8_t _cBuf[15]; // buffer for loading character font
510 uint8_t _charSpacing; // spacing in columns between characters
511 uint8_t _charCols; // number of columns for this character
512 int16_t _countCols; // count of number of columns already shown
513 uint8_t makeChar(char c); // load a character bitmap and add in trailing _charSpacing blanks
514 uint8_t reverseBuf(uint8_t *p, uint8_t size); // reverse the elements of the buffer
515
516 // Effect functions
517 void commonPrint(void);
518 void effectPrint(bool bIn);
519 void effectSlice(bool bIn);
520 void effectWipe(bool bLightBar, bool bIn);
521 void effectOpen(bool bLightBar, bool bIn);
522 void effectClose(bool bLightBar, bool bIn);
523 void effectBlinds(bool bIn);
524 void effectDissolve(bool bIn);
525 void effectVScroll(textEffect_t effectSelect, bool bIn);
526 void effectHScroll(textEffect_t effectSelect, bool bIn);
527 };
528
529 #endif