AceSegment  0.2.0
An adjustable, configurable, and extensible framework for rendering seven segment LED displays.
Renderer.h
1 /*
2 MIT License
3 
4 Copyright (c) 2018 Brian T. Park
5 
6 Permission is hereby granted, free of charge, to any person obtaining a copy
7 of this software and associated documentation files (the "Software"), to deal
8 in the Software without restriction, including without limitation the rights
9 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 copies of the Software, and to permit persons to whom the Software is
11 furnished to do so, subject to the following conditions:
12 
13 The above copyright notice and this permission notice shall be included in all
14 copies or substantial portions of the Software.
15 
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 SOFTWARE.
23 */
24 
25 #ifndef ACE_SEGMENT_RENDERER_H
26 #define ACE_SEGMENT_RENDERER_H
27 
28 #include <stdint.h>
29 #include "Driver.h"
30 #include "TimingStats.h"
31 
32 namespace ace_segment {
33 
34 class StyledDigit;
35 class Hardware;
36 
47 class Renderer {
48  public:
49  // VisibleForTesting.
50  static const uint8_t kBlinkStateOff = 0;
51  static const uint8_t kBlinkStateOn = 1;
52 
54  explicit Renderer(Hardware* hardware, Driver* driver,
55  StyledDigit* styledDigits, uint8_t numDigits,
56  uint8_t framesPerSecond,
57  uint16_t statsResetInterval,
58  uint16_t blinkSlowDurationMillis,
59  uint16_t blinkFastDurationMillis,
60  uint16_t pulseSlowDurationMillis,
61  uint16_t pulseFastDurationMillis):
62  mHardware(hardware),
63  mDriver(driver),
64  mStyledDigits(styledDigits),
65  mNumDigits(numDigits),
66  mFramesPerSecond(framesPerSecond),
67  mStatsResetInterval(statsResetInterval),
68  mBlinkSlowDurationMillis(blinkSlowDurationMillis),
69  mBlinkFastDurationMillis(blinkFastDurationMillis),
70  mPulseSlowDurationMillis(pulseSlowDurationMillis),
71  mPulseFastDurationMillis(pulseFastDurationMillis),
72  mBrightness(255),
73  mIsPulseEnabled(false),
74  mBlinkSlowState(kBlinkStateOn),
75  mBlinkFastState(kBlinkStateOn)
76  {}
77 
79  virtual ~Renderer() {}
80 
85  virtual void configure();
86 
88  uint8_t getNumDigits() { return mNumDigits; }
89 
91  uint16_t getFramesPerSecond() { return mFramesPerSecond; }
92 
94  uint16_t getFieldsPerSecond() {
95  return mFramesPerSecond * mDriver->getFieldsPerFrame();
96  }
97 
105  void writeBrightness(uint8_t brightness) {
106  mBrightness = brightness;
107  }
108 
110  void writePatternAt(uint8_t digit, uint8_t pattern, uint8_t style);
111 
113  void writePatternAt(uint8_t digit, uint8_t pattern);
114 
116  void writeStyleAt(uint8_t digit, uint8_t style);
117 
119  void writeDecimalPointAt(uint8_t digit, bool state = true);
120 
125  void renderFieldWhenReady();
126 
151  void renderField();
152 
157  // TODO: make this a pointer and make stats gathering optional
159 
162  return mStyledDigits[i];
163  }
164 
166  static void calcBlinkStateForFrame(uint16_t framesPerBlink,
167  uint16_t& currentFrame, uint8_t& blinkState);
168 
170  static void calcPulseFractionForFrame(uint16_t framesPerPulse,
171  uint16_t& currentFrame, uint8_t& pulseFraction);
172 
179  uint16_t framesPerPulseInverse, uint16_t framesPerPulse,
180  uint16_t& currentFrame, uint8_t& pulseFraction);
181 
197  static uint8_t calcBrightness(uint8_t style, uint8_t brightness,
198  uint8_t blinkSlowState, uint8_t blinkFastState, bool isPulseEnabled,
199  uint8_t pulseSlowFraction, uint8_t pulseFastFraction);
200 
201  protected:
202  // disable copy-constructor and assignment operator
203  Renderer(const Renderer&) = delete;
204  Renderer& operator=(const Renderer&) = delete;
205 
207  void updateFrame();
208 
211 
213  void renderStyledDigits();
214 
215  Hardware* const mHardware;
216  Driver* const mDriver;
217  StyledDigit* const mStyledDigits;
218  const uint8_t mNumDigits;
219  const uint8_t mFramesPerSecond;
220 
221  // statistics
222  const uint16_t mStatsResetInterval;
223  TimingStats mStats;
224 
225  // digit style attributes
226  const uint16_t mBlinkSlowDurationMillis;
227  const uint16_t mBlinkFastDurationMillis;
228  const uint16_t mPulseSlowDurationMillis;
229  const uint16_t mPulseFastDurationMillis;
230 
231  // global brightness, can be changed during runtime
232  uint8_t mBrightness;
233 
234  // depends on the Driver
235  bool mIsPulseEnabled;
236 
237  // variables to support renderFieldWhenReady()
238  uint16_t mMicrosPerField;
239  uint16_t mLastRenderFieldMicros;
240 
241  // each call to renderField() increment current field counter modulo the
242  // fieldsPerFrame, so certain calculations can be performed once per frame
243  uint16_t mFieldsPerFrame;
244  uint16_t mCurrentField;
245 
246  // TODO: Maybe generalize the following into an array of styles, because the
247  // calculations seem so similar.
248 
249  uint16_t mFramesPerBlinkSlow;
250  uint16_t mCurrentBlinkSlowFrame;
251  uint8_t mBlinkSlowState;
252 
253  uint16_t mFramesPerBlinkFast;
254  uint16_t mCurrentBlinkFastFrame;
255  uint8_t mBlinkFastState;
256 
257  uint16_t mFramesPerPulseSlow;
258  uint16_t mFramesPerPulseSlowInverse; // 65536/mFramesPerPulseSlow
259  uint16_t mCurrentPulseSlowFrame;
260  uint8_t mPulseSlowFraction;
261 
262  uint16_t mFramesPerPulseFast;
263  uint16_t mFramesPerPulseFastInverse; // 65536/mFramesPerPulseFast
264  uint16_t mCurrentPulseFastFrame;
265  uint8_t mPulseFastFraction;
266 };
267 
268 }
269 
270 #endif
uint16_t getFramesPerSecond()
Return the frames per second.
Definition: Renderer.h:91
void renderFieldWhenReady()
Display one field of a frame when the time is right.
Definition: Renderer.cpp:108
TimingStats getTimingStats()
Return stats.
Definition: Renderer.cpp:138
Data structure that keeps track of the state of each digit (its segment bit pattern and its style)...
Definition: StyledDigit.h:36
void writePatternAt(uint8_t digit, uint8_t pattern, uint8_t style)
Write the pattern and style for a given digit.
Definition: Renderer.cpp:79
void renderField()
Render the current field immediately.
Definition: Renderer.cpp:117
static void calcPulseFractionForFrameUsingInverse(uint16_t framesPerPulseInverse, uint16_t framesPerPulse, uint16_t &currentFrame, uint8_t &pulseFraction)
Calculate the pulse fraction using the reciprocal of the framesPerPulse, which avoid a long division...
Definition: Renderer.cpp:235
void writeStyleAt(uint8_t digit, uint8_t style)
Write the style for a given digit, leaving pattern unchanged.
Definition: Renderer.cpp:92
virtual void configure()
Configure the driver with the parameters given by the various setXxx() methods.
Definition: Renderer.cpp:37
void writeBrightness(uint8_t brightness)
Set brightness expressed as a fraction of 256.
Definition: Renderer.h:105
StyledDigit & getStyledDigit(uint8_t i)
Return a reference the styled digit.
Definition: Renderer.h:161
A class that knows how to translate an array of led segement bit patterns with style attributes to a ...
Definition: Renderer.h:47
void updateFrame()
Perform things that need to be done each frame.
Definition: Renderer.cpp:129
void calcBlinkAndPulseForFrame()
Calculate the blink and pulse states for current frame.
Definition: Renderer.cpp:184
void renderStyledDigits()
Translate the StyledDigits to DimmingDigits for the Driver.
Definition: Renderer.cpp:145
static void calcPulseFractionForFrame(uint16_t framesPerPulse, uint16_t &currentFrame, uint8_t &pulseFraction)
Calculate the pulse fraction.
Definition: Renderer.cpp:216
uint16_t getFieldsPerSecond()
Return the fields per second.
Definition: Renderer.h:94
void writeDecimalPointAt(uint8_t digit, bool state=true)
Write the decimal point for the digit.
Definition: Renderer.cpp:98
static uint8_t calcBrightness(uint8_t style, uint8_t brightness, uint8_t blinkSlowState, uint8_t blinkFastState, bool isPulseEnabled, uint8_t pulseSlowFraction, uint8_t pulseFastFraction)
Calculate the effective brightness of a digit with the given style.
Definition: Renderer.cpp:156
Base class of drivers which knows how to transfer the bit patterns stored in the array of DimmingDigi...
Definition: Driver.h:44
virtual ~Renderer()
Destructor.
Definition: Renderer.h:79
uint8_t getNumDigits()
Get the number of digits.
Definition: Renderer.h:88
static void calcBlinkStateForFrame(uint16_t framesPerBlink, uint16_t &currentFrame, uint8_t &blinkState)
Calculate the blink state.
Definition: Renderer.cpp:205
Renderer(Hardware *hardware, Driver *driver, StyledDigit *styledDigits, uint8_t numDigits, uint8_t framesPerSecond, uint16_t statsResetInterval, uint16_t blinkSlowDurationMillis, uint16_t blinkFastDurationMillis, uint16_t pulseSlowDurationMillis, uint16_t pulseFastDurationMillis)
Constructor.
Definition: Renderer.h:54
virtual uint16_t getFieldsPerFrame()=0
Return number of fields per frame.