AceSegment  0.4.0
An adjustable, configurable, and extensible framework for rendering seven segment LED displays.
Public Member Functions | Friends | List of all members
ace_segment::ScanningDisplay< HW, LM, DIGITS, SUBFIELDS > Class Template Reference

An implementation of LedDisplay for display modules which do not have hardware controller chips, so they require the microcontroller to perform the multiplexed scanning across the digits. More...

#include <ScanningDisplay.h>

Inheritance diagram for ace_segment::ScanningDisplay< HW, LM, DIGITS, SUBFIELDS >:
Inheritance graph
[legend]
Collaboration diagram for ace_segment::ScanningDisplay< HW, LM, DIGITS, SUBFIELDS >:
Collaboration graph
[legend]

Public Member Functions

 ScanningDisplay (const HW &hardware, const LM &ledMatrix, uint8_t framesPerSecond)
 Constructor. More...
 
void begin ()
 Configure the driver with the parameters given by in the constructor. More...
 
void end ()
 A no-op end() function for consistency with other classes.
 
uint8_t getNumDigits () const
 Get the number of digits.
 
uint16_t getFramesPerSecond () const
 Return the requested frames per second.
 
uint16_t getFieldsPerSecond () const
 Return the fields per second.
 
uint16_t getFieldsPerFrame () const
 Total fields per frame across all digits.
 
void writePatternAt (uint8_t pos, uint8_t pattern) override
 Write the pattern for a given pos. More...
 
void writePatternsAt (uint8_t pos, const uint8_t patterns[], uint8_t len) override
 Write the array of patterns of length len, starting at pos. More...
 
void writePatternsAt_P (uint8_t pos, const uint8_t patterns[], uint8_t len) override
 Write the array of patterns of length len, which are stored in flash memory through PROGMEM, starting at pos. More...
 
void setBrightnessAt (uint8_t pos, uint8_t brightness) override
 
void writeDecimalPointAt (uint8_t pos, bool state=true) override
 Write the decimal point for the pos. More...
 
void setGlobalBrightness (uint8_t brightness) override
 
void clear () override
 Clear all digits to blank pattern.
 
bool renderFieldWhenReady ()
 Display one field of a frame when the time is right. More...
 
void renderFieldNow ()
 Render the current field immediately. More...
 
void prepareToSleep ()
 Prepare to go to sleep by clearing the frame, and setting a flag so that it doesn't turn itself back on through an interrupt.
 
void wakeFromSleep ()
 Wake up from sleep.
 
- Public Member Functions inherited from ace_segment::LedDisplay
 LedDisplay (uint8_t numDigits)
 
uint8_t getNumDigits () const
 Return the number of digits supported by this display instance.
 

Friends

class ::ScanningDisplayTest_displayCurrentField
 

Detailed Description

template<typename HW, typename LM, uint8_t DIGITS, uint8_t SUBFIELDS = 1>
class ace_segment::ScanningDisplay< HW, LM, DIGITS, SUBFIELDS >

An implementation of LedDisplay for display modules which do not have hardware controller chips, so they require the microcontroller to perform the multiplexed scanning across the digits.

The matrix wiring of the segment and digit pins allow only a single digit to be turned on at any given time, so multiplexing across all the digits quickly (e.g. 60 Hz) gives the appearance of activating all the digits at the same time. For LED modules with a hardware controller (e.g. TM1637), the controller chip performs the multiplexing. Note that a 74HC595 Shift Register chip does not perform the multiplexing, it only provides a conversion from serial to parallel output.

This class depends on one of the implementations of the LedMatrixBase class to multiplex the LED segments on the digits, and potentially one of the of SwSpiAdapter or HwSpiAdapter classes if a 74HC595 shift register chip is used.

A frame is divided into fields. A field is a partial rendering of a frame. Normally, the one digit corresponds to one field. However if brightness control is enabled by setting SUBFIELDS > 1, then a single digit will be rendered for SUBFIELDS number of times so that the brightness of the digit will be controlled by PWM.

There are 2 ways to get the expected number of frames per second:

1) Call the renderFieldNow() in an ISR, or 2) Call renderFieldWhenReady() polling method repeatedly from the global loop(), and an internal timing parameter will trigger a renderFieldNow() at the appropriate time.

Template Parameters
HWclass that provides access to hardware pins and timing functions
LMLedMatrixBase class that provides access to LED segments (elements) organized by digit (group)
DIGITSnumber of LED digits
SUBFIELDSnumber of subfields for each digit to get brightness control using PWM. The default is 1, but can be set to greater than 1 to get brightness control.

Definition at line 75 of file ScanningDisplay.h.

Constructor & Destructor Documentation

◆ ScanningDisplay()

template<typename HW , typename LM , uint8_t DIGITS, uint8_t SUBFIELDS = 1>
ace_segment::ScanningDisplay< HW, LM, DIGITS, SUBFIELDS >::ScanningDisplay ( const HW &  hardware,
const LM &  ledMatrix,
uint8_t  framesPerSecond 
)
inlineexplicit

Constructor.

Parameters
hardwarepointer to an instance of Hardware. Required.
ledMatrixinstance of LedMatrixBase that understanding the wiring
framesPerSecondthe rate at which all digits of the LED display will be refreshed
numDigitsnumber of digits in the LED display
patternsarray of segment pattern per digit, not nullable
brightnessesarray of brightness for each digit (default: nullptr)

Definition at line 89 of file ScanningDisplay.h.

Member Function Documentation

◆ begin()

template<typename HW , typename LM , uint8_t DIGITS, uint8_t SUBFIELDS = 1>
void ace_segment::ScanningDisplay< HW, LM, DIGITS, SUBFIELDS >::begin ( )
inline

Configure the driver with the parameters given by in the constructor.

Normally, this should be called only once after construction. Unit tests will sometimes change a parameter of FakeDriver and call this a second time.

Definition at line 106 of file ScanningDisplay.h.

◆ renderFieldNow()

template<typename HW , typename LM , uint8_t DIGITS, uint8_t SUBFIELDS = 1>
void ace_segment::ScanningDisplay< HW, LM, DIGITS, SUBFIELDS >::renderFieldNow ( )
inline

Render the current field immediately.

If modulation is off (i.e. SUBFIELDS == 1), then the field corresponds to the single digit. If modulation is enabled (SUBFIELDS > 1), then each digit is PWM modulated over SUBFIELDS number of renderings.

This method is intended to be called directly from a timer interrupt handler.

Definition at line 253 of file ScanningDisplay.h.

◆ renderFieldWhenReady()

template<typename HW , typename LM , uint8_t DIGITS, uint8_t SUBFIELDS = 1>
bool ace_segment::ScanningDisplay< HW, LM, DIGITS, SUBFIELDS >::renderFieldWhenReady ( )
inline

Display one field of a frame when the time is right.

This is a polling method, so call this slightly more frequently than getFieldsPerSecond() per second.

Returns
Returns true if renderFieldNow() was called and the field was rendered.

Definition at line 232 of file ScanningDisplay.h.

◆ setBrightnessAt()

template<typename HW , typename LM , uint8_t DIGITS, uint8_t SUBFIELDS = 1>
void ace_segment::ScanningDisplay< HW, LM, DIGITS, SUBFIELDS >::setBrightnessAt ( uint8_t  pos,
uint8_t  brightness 
)
inlineoverridevirtual

The maximum brightness should is exactly SUBFIELDS which turns on the LED 100% of the time. The minimum brightness is 0, which turns OFF the digit. For example, if SUBFIELDS==16, the the maximum brightness is 16 which turns ON the digit 100% of the time. The relative brightness of each brightness level is in units of 1/SUBFIELDS.

The brightness scale is not normalized to [0,255]. A previous version of this class tried to do that, but I found that this introduced discretization errors which made it difficult to control the brightness at intermediate values. For example, suppose SUBFIELDS=16. If we changed the normalized brightness value from 32 to 40, it was impossible to determine without actually running the program if the 2 values actually differed in brightness. Instead, the calling program is expected to keep track of the value of SUBFIELDS, and create an array of brightness values in these raw units. The side benefit of using raw brightness values is that it makes displayCurrentFieldModulated() easier to implement.

Implements ace_segment::LedDisplay.

Definition at line 186 of file ScanningDisplay.h.

◆ setGlobalBrightness()

template<typename HW , typename LM , uint8_t DIGITS, uint8_t SUBFIELDS = 1>
void ace_segment::ScanningDisplay< HW, LM, DIGITS, SUBFIELDS >::setGlobalBrightness ( uint8_t  brightness)
inlineoverridevirtual

See the documentation for setBrightnessAt() for information about the range of values of brightness and how it is interpreted.

Implements ace_segment::LedDisplay.

Definition at line 210 of file ScanningDisplay.h.

◆ writeDecimalPointAt()

template<typename HW , typename LM , uint8_t DIGITS, uint8_t SUBFIELDS = 1>
void ace_segment::ScanningDisplay< HW, LM, DIGITS, SUBFIELDS >::writeDecimalPointAt ( uint8_t  pos,
bool  state = true 
)
inlineoverridevirtual

Write the decimal point for the pos.

Clock LED modules will attach the colon segment to one of the decimal points.

Implements ace_segment::LedDisplay.

Definition at line 193 of file ScanningDisplay.h.

◆ writePatternAt()

template<typename HW , typename LM , uint8_t DIGITS, uint8_t SUBFIELDS = 1>
void ace_segment::ScanningDisplay< HW, LM, DIGITS, SUBFIELDS >::writePatternAt ( uint8_t  pos,
uint8_t  pattern 
)
inlineoverridevirtual

Write the pattern for a given pos.

If the pos is out of bounds, the method does nothing.

Implements ace_segment::LedDisplay.

Definition at line 145 of file ScanningDisplay.h.

◆ writePatternsAt()

template<typename HW , typename LM , uint8_t DIGITS, uint8_t SUBFIELDS = 1>
void ace_segment::ScanningDisplay< HW, LM, DIGITS, SUBFIELDS >::writePatternsAt ( uint8_t  pos,
const uint8_t  patterns[],
uint8_t  len 
)
inlineoverridevirtual

Write the array of patterns of length len, starting at pos.

If an element of patterns attempts to write to a digit beyond the last digit of the LED module, nothing happens.

Implements ace_segment::LedDisplay.

Definition at line 150 of file ScanningDisplay.h.

◆ writePatternsAt_P()

template<typename HW , typename LM , uint8_t DIGITS, uint8_t SUBFIELDS = 1>
void ace_segment::ScanningDisplay< HW, LM, DIGITS, SUBFIELDS >::writePatternsAt_P ( uint8_t  pos,
const uint8_t  patterns[],
uint8_t  len 
)
inlineoverridevirtual

Write the array of patterns of length len, which are stored in flash memory through PROGMEM, starting at pos.

If an element of patterns attempts to write to a digit beyond the last digit of the LED module, nothing happens.

Implements ace_segment::LedDisplay.

Definition at line 158 of file ScanningDisplay.h.


The documentation for this class was generated from the following file: