Notifications
Clear all

Object Oriented techniques - Example 2 - Display Manager

49 Posts
8 Users
83 Reactions
5,342 Views
 Biny
(@binaryrhyme)
Member
Joined: 3 years ago
Posts: 269
Topic starter  

 

Folks - here's the next installment on OO techniques - a simple DisplayManager class that supervises the "redraw" of your displays. The way it works is conceptually simple - you set a frame rate up - say 30 Hz, and add a bunch of DisplayElements (LEDs, screens, buzzers, etc) to the DisplayManager, whch keeps track of the DisplayElements and calls the Refresh() method on them whenever a "redraw" is triggered.

The example has the Built-in LED, a Red LED and a Green LED make use of a specific type (subclass) of DisplayElement - a DigitalLED - which can be set up for various blink cycles - cycle length and duty cycle in this case. The example starts to show the payoff off OO techniques, as getting various LEDs blinking at different speeds and duty cycles can be tricky.

Pictured below is the main arduino BR_DisplayManager-v02.ino; full source in the attached .zip - Happy to explain anything that is unclear, yada yada.

/* BR Display Manager Test Routine */

/* *********** Libraries *********** */
#include "BR_DisplayManager-v02.h"

/* ********** Constants ********** */
// Display Manager
#define DEFAULT_REFRESH_RATE 30

// LEDs
#define LED_GREEN_PIN 8 // LED Pins
#define LED_RED_PIN 7
#define LED_BLUE_PIN 2

#define LED_BUILTIN_CYCLE_TIME 1000 // = 1 Hz
#define LED_GREEN_CYCLE_TIME 2000 // = 0.5 Hz
#define LED_RED_CYCLE_TIME 1000 / 6 // 6 Hz
#define LED_BLUE_CYCLE_TIME 3000 // 0.33 Hz

#define LED_BUILTIN_DUTYCYCLE 0.5 // Dutycycle in %, 0 - 1.0
#define LED_GREEN_DUTYCYCLE 0.1
#define LED_RED_DUTYCYCLE 0.9
#define LED_BLUE_DUTYCYCLE 0.5


/* ********** Singleton Instances ********** */
DisplayManager DM (DEFAULT_REFRESH_RATE);


/* ********** Global Instances ********** */
// Digital LEDs
DigitalLED BuiltInLED ( "BuiltInLED", LED_BUILTIN, LED_BUILTIN_CYCLE_TIME, LED_BUILTIN_DUTYCYCLE );
DigitalLED GreenLED ( "GreenLED", LED_GREEN_PIN, LED_GREEN_CYCLE_TIME, LED_GREEN_DUTYCYCLE );
DigitalLED RedLED ( "RedLED", LED_RED_PIN, LED_RED_CYCLE_TIME, LED_RED_DUTYCYCLE );
// DigitalLED BlueLED ( "BlueLED", LED_BLUE_PIN, LED_BLUE_CYCLE_TIME, LED_BLUE_DUTYCYCLE );


/* ********** Arduino Setup ********** */
void setup() {
   // setup the serial monitor
   Serial.begin(9600);

   // Add Display Elements to the Display Manager
   DM.AddDisplayElement( &BuiltInLED );
   DM.AddDisplayElement( &GreenLED );
   DM.AddDisplayElement( &RedLED );
   // DM.AddDisplayElement( &BlueLED );
}

/* ********** Arduino Loop ********** */
void loop() {

   // Call Display Manager Refresh
   if( DM.Refresh() )
       ;

   delay(1); // 1 ms delay at loop bottom
}

 

 

 

 

I edit my posts to fix typos, correct grammar, or improve clarity. On-screen keyboards are evil.


   
Dazza, Lee G and ron bentley reacted
Quote
ron bentley
(@ronbentley1)
Member
Joined: 3 years ago
Posts: 385
 

Hi Biny,

Thanks for the post which is very instructive.

If you are able to add a link to the library cited:

BR_DisplayManager-v02.h

or add a few words about its functionality that would be the 'cherry', as this is new one on me.

👍

 

Ron Bentley
Creativity is an input to innovation and change is the output from innovation. Braden Kelley
A computer is a machine for constructing mappings from input to output. Michael Kirby
Through great input you get great output. RZA
Gauss is great but Euler rocks!!


   
Biny reacted
ReplyQuote
 Biny
(@binaryrhyme)
Member
Joined: 3 years ago
Posts: 269
Topic starter  

@ronbentley1 It's not really a library - just an include file. The attached .zip has all the code files - dump them into an arduino project directory and it should just run (once hardware is set up - it's wired for a Mega). I'll post the other two files here as well so folks don't need to unpack it.

I edit my posts to fix typos, correct grammar, or improve clarity. On-screen keyboards are evil.


   
ron bentley reacted
ReplyQuote
 Biny
(@binaryrhyme)
Member
Joined: 3 years ago
Posts: 269
Topic starter  

Here is the code for BR_DisplayManager-v02a.h (updated)

#ifndef BR_DisplayManager
#define BR_DisplayManager

#include "Arduino.h"

/* ********** Defined Constants ********** */
#define MAX_DISPLAY_ELEMENTS 10 // Max # of DisplayElements in DisplayManager

/* ******************** DisplayElement ******************** */
// Abstract class for any item that displays information
// regularly as part of the DisplayManager refresh cycle
// Maximum rate of change determined by DisplayManager.frameRate
/* ******************************************************** */
class DisplayElement
{
  public:
      char* DEid;

     // Constructors
     DisplayElement();
     virtual ~DisplayElement();
     
     // Method called by the DisplayManager to refresh display.
     // Must be overridden by subclass.
     // Elapsed time argument is num of ms since Refresh last called
     // which can be accumulated to implement slower changes than the refresh rate.
    virtual void Refresh( unsigned long elapsedTime );
    
  private:
     bool needsRefresh = true; // true if item needs to refresh
};



/* ******************** DisplayManager ******************* */
// A singleton used to contain DisplayElements and control their
// refresh rate, invoking their Refresh() method as required.
/* ******************************************************* */
class DisplayManager
{
  public:
     // Constructors
     DisplayManager();
     DisplayManager( int fRate );

     // FrameRate property in Hz
     int getFrameRate();
     void setFrameRate( int fRate );
     
     // Method called periodically to request a refresh
     // The refresh on the display elements will only be called at frameRate frequency.
     // Returns true if the refresh was done, false if still waiting.
     virtual bool Refresh();

     // Adds instances of DisplayItem to displayElements list and
     // returns a reference to the item.
     void  AddDisplayElement( DisplayElement* dElement_ptr );

     // Removes instances of DisplayItem from the _displayItemsList
     // *** Currently not implemented ***
     void  RemoveDisplayElement( DisplayElement* dElement_ptr );

  private:
     int numDElements; // Current number of display items in array
     DisplayElement* dElement_ptrs [MAX_DISPLAY_ELEMENTS]; // Array pointers to display items.

     int frameRate; // Display refresh rate in Hz
     unsigned long timePerFrame; // duration of wait between refreshes in ms - set by frameRate
     unsigned long previousRefreshTime; // time of previous refresh measured in ms
     unsigned long calcTimeSinceLastRefresh();
};



/* ******************** DigitalLED Class ******************** */
// Manages voltage provided to an LED using a digital pin
// The LED can only be on, off, or blinking - does not dim
/* ********************************************************** */
class DigitalLED: public DisplayElement
{
   public:
      DigitalLED();
      DigitalLED(char* deId, int pinNum, unsigned int cTime, float dCycle);

      // Override DisplayElement.Refresh
      virtual void Refresh(unsigned long elapsedTime) override;

      // Change LED Blink
      void ChangeCycle(unsigned int cTime, float dCycle);

   private:
      void calcCycleTimes(); // uses cycleTime and dutyCycle to calc duty cycle times

      int digitalPINNum; // analog pin number driving the LED
      unsigned int cycleTime; // ms per blink cycle
      float dutyCycle; // % of time spent positive, between 0 and 1

      // Internal state variables
      int timePositivePerCycle; // Time spent high in ms
      int timeNegativePerCycle; // Time spent low in ms

      int timeSinceChange = 0; // Time since state change
      bool ledOn; // TRUE if on, FALSE if off
      
};


#endif // BR_DisplayManager

I edit my posts to fix typos, correct grammar, or improve clarity. On-screen keyboards are evil.


   
ron bentley and Lee G reacted
ReplyQuote
 Biny
(@binaryrhyme)
Member
Joined: 3 years ago
Posts: 269
Topic starter  

I edit my posts to fix typos, correct grammar, or improve clarity. On-screen keyboards are evil.


   
ron bentley and Lee G reacted
ReplyQuote
 Biny
(@binaryrhyme)
Member
Joined: 3 years ago
Posts: 269
Topic starter  

I'm going to be expanding this to add a few more features and include different types of DisplayElements (AnalogLED, NeoPixelLEDs, LCD, 7Segment LED, yada yada) and tighten up some aspects, but I thought it would lose a lot of its instructional value if I tossed in every kitchen sink.

====================

I cleaned up issues in the comments, and attached is an update (v02a). I corrected the .h and .cpp in the posts above as well. (I can't change the original .ino, - it's missing an "a" on the include statement now, but work from the downloaded .ZIP, which is attached to this post.

 

I edit my posts to fix typos, correct grammar, or improve clarity. On-screen keyboards are evil.


   
Ron, ron bentley, Lee G and 1 people reacted
ReplyQuote
frogandtoad
(@frogandtoad)
Member
Joined: 5 years ago
Posts: 1458
 

@binaryrhyme

Found it!

Posted by: @binaryrhyme

I'm going to be expanding this to add a few more features and include different types of DisplayElements (AnalogLED, NeoPixelLEDs, LCD, 7Segment LED, yada yada) and tighten up some aspects, but I thought it would lose a lot of its instructional value if I tossed in every kitchen sink.

====================

I cleaned up issues in the comments, and attached is an update (v02a). I corrected the .h and .cpp in the posts above as well. (I can't change the original .ino, - it's missing an "a" on the include statement now, but work from the downloaded .ZIP, which is attached to this post.

 

OK, again, I commend you for trying to promote and introduce the learning of OOP principles in C++ - it's something I've put forward in the past, but sadly, all I received was member push-back, and no one else supported me to take it further at the time.

I downloaded your code in the .zip file, and had a quick look.
Um... please take a seat with a stiff drink, preferably Jack Daniel's 😀

I won't go too hard on you, but I will point out some fundamental misunderstandings, because they can and have probably mislead some newbies here trying to learn OOP.

Aside from my previous comments, I think this is even far more complex for the newbie to learn.  Here you have introduced inheritance and virtual functions, with a whole bunch of logic and flow that actually detracts (IMO) from the learning process.

1) You claim to have an abstract class, but actually you do not - An abstract class must have at least one pure virtual function, which you do not have, therefore your class is not abstract - Even if it was, you do not inherit from it anyway, so there is no relationship/contract with it.

2) You claim to have implemented a Singleton class, but actually you have no such class. The Singleton class is known as a design pattern, and is mostly frowned upon by software engineers.  For it to be a Singleton class, it must conform to the Singleton design pattern, which in most cases will have a static method with private non copyable constructors and assignment operators, etc...

Additionally, constructor initialization lists are not used, which are the modern way of initializing class member data, and in fact, the only real way you can initialise a base class constructor from a child, so they are an imperative part of OOP.

File management - Header files, include guards - no explanation

Please note, the biggest point here is not that you' re code is right or wrong, but the fact that it's focus is more about the project logic than OOP itself.

I hope I haven't discouraged you to continue to post tutorial material, as that's how we all learn (by debating such material)... please continue, and reach out if you need some help.

Cheers.


   
Inst-Tech, Biny and Ron reacted
ReplyQuote
 Biny
(@binaryrhyme)
Member
Joined: 3 years ago
Posts: 269
Topic starter  

@frogandtoad Glad you found it 🙂 Yeh, this is perhaps overestimating the ability of the mean programmer to absorb the concepts without a walkthrough. I worried about that.

Yes on the abstract class not being enforced, but conceptually an abstract class is simply a class that is never instantiated - there are implementation methods that make this impossible, but they would introduce constructs I omitted - I did try to simplify. 🙂

I am well familiar with design patterns, and while a singleton is rarely employed, it is a necessary device when you only need a class that is instantiated only once. As always, "it depends" - and as I said - implementation simplifications were made - but I hear you. I could "enforce" the singleton through coding practices, but I wanted to keep the code simple, while introducing the concept. It is not necessary for a singleton to adhere to an implementation (however well recommended and standard) as the only thing actually required of a singleton is that it only has one instance. 😉

As far as constructor lists go - thank you for the input. I am 60+ years old, and some of the more mod innovations may have escaped me - I am off to my best friend, google. 🙂

Not discouraged at all. Your previous detailed critique pointed out that I hadn't covered the basics sufficiently - and now we are deep in the esoterica of professional practices - but I welcome that - and I suspect I shall, myself, improve. Excellent.

I edit my posts to fix typos, correct grammar, or improve clarity. On-screen keyboards are evil.


   
Inst-Tech and Ron reacted
ReplyQuote
Ron
 Ron
(@zander)
Father of a miniature Wookie
Joined: 4 years ago
Posts: 7700
 

@binaryrhyme Beautiful exchange guys, I for one am learning new words. Still no idea what you are talking about, but I might learn a bit and example code is the best teacher for me as I am not able to read very well any more.

First computer 1959. Retired from my own computer company 2004.
Hardware - Expert in 1401, and 360, fairly knowledge in PC plus numerous MPU's and MCU's
Major Languages - Machine language, 360 Macro Assembler, Intel Assembler, PL/I and PL1, Pascal, Basic, C plus numerous job control and scripting languages.
My personal scorecard is now 1 PC hardware fix (circa 1982), 1 open source fix (at age 82), and 2 zero day bugs in a major OS.


   
Inst-Tech and Biny reacted
ReplyQuote
frogandtoad
(@frogandtoad)
Member
Joined: 5 years ago
Posts: 1458
 

@zander

Posted by: @zander

@binaryrhyme Beautiful exchange guys, I for one am learning new words. Still no idea what you are talking about, but I might learn a bit and example code is the best teacher for me as I am not able to read very well any more.

It's 4:30 AM here and I need some sleep 🙂
I'll post a small example tomorrow regarding the use of abstract classes with polymorphism.

Cheers


   
Inst-Tech, Ron and Biny reacted
ReplyQuote
 Biny
(@binaryrhyme)
Member
Joined: 3 years ago
Posts: 269
Topic starter  

@frogandtoad Yeh, that would be cool. I think a lot of folks here want to get to the "next level" and that means a graded ramp of increasing capability and insight would be a good thing.

I edit my posts to fix typos, correct grammar, or improve clarity. On-screen keyboards are evil.


   
ReplyQuote
frogandtoad
(@frogandtoad)
Member
Joined: 5 years ago
Posts: 1458
 

   
Biny and Inst-Tech reacted
ReplyQuote
Ron
 Ron
(@zander)
Father of a miniature Wookie
Joined: 4 years ago
Posts: 7700
 

@frogandtoad I remember a similar example when I was first introduced to OOP. The question I had then was 'What has this to do with payroll, AR, AP, GL etc' Still a valid question, but of course programmers code much more interesting applications today and I do see some applicability but still question how much is gained in $ coding like this.

First computer 1959. Retired from my own computer company 2004.
Hardware - Expert in 1401, and 360, fairly knowledge in PC plus numerous MPU's and MCU's
Major Languages - Machine language, 360 Macro Assembler, Intel Assembler, PL/I and PL1, Pascal, Basic, C plus numerous job control and scripting languages.
My personal scorecard is now 1 PC hardware fix (circa 1982), 1 open source fix (at age 82), and 2 zero day bugs in a major OS.


   
frogandtoad and Biny reacted
ReplyQuote
frogandtoad
(@frogandtoad)
Member
Joined: 5 years ago
Posts: 1458
 

@zander

Posted by: @zander

@frogandtoad I remember a similar example when I was first introduced to OOP. The question I had then was 'What has this to do with payroll, AR, AP, GL etc' Still a valid question, but of course programmers code much more interesting applications today and I do see some applicability but still question how much is gained in $ coding like this.

You gain a lot, even for projects less than 1000 lines of code.


   
Biny and Inst-Tech reacted
ReplyQuote
Ron
 Ron
(@zander)
Father of a miniature Wookie
Joined: 4 years ago
Posts: 7700
 

@frogandtoad Good to know, I will keep my eyes peeled for places to use it.

First computer 1959. Retired from my own computer company 2004.
Hardware - Expert in 1401, and 360, fairly knowledge in PC plus numerous MPU's and MCU's
Major Languages - Machine language, 360 Macro Assembler, Intel Assembler, PL/I and PL1, Pascal, Basic, C plus numerous job control and scripting languages.
My personal scorecard is now 1 PC hardware fix (circa 1982), 1 open source fix (at age 82), and 2 zero day bugs in a major OS.


   
ReplyQuote
Page 1 / 4