0

I have recently bought an Arduino which uses C++ to code on. I am familiar with Java and as C++ allows OO programming I didn't think it would have been that difficult. But...

CODE:

// LEDCLOCK CLASS /////////////////////////////////////////////////////////////////////////
class LedClock{
  private:
    int hours;
    int minutes;
    int seconds;
    static const long secondInterval = 1000;
    unsigned long previousMilliseconds;
    unsigned long currentMilliseconds;

  public:
    LedClock(){
      hours = 0;
      minutes = 0;
      seconds = 0;
      previousMilliseconds = 0;
      currentMilliseconds = 0;
    };
    
    int getHours(){
      return hours;
    };
    
    int getMinutes(){
      return minutes;
    };
    
    int getSeconds(){
      return seconds;
    };
    
    long getSecondInterval(){
      return secondInterval;
    };
    
    unsigned long getPreviousMilliseconds(){
      return previousMilliseconds;
    };
    
    void setHours(int h){
      if(h < 24 && h >= 0){
        hours = h;
      }else{
        hours = 0;
      }
    };
    
    void setMinutes(int m){
      if(m < 60 && m > 0){
        minutes = m;        
      }else{
        minutes = 0;
      }
    };
    
    void setSeconds(int s){
      if(s < 60 && s > 0){
        seconds = s;        
      }else{
        seconds = 0;
      }
    };
    
    void setPreviousMilliseconds(unsigned long ms){
      previousMilliseconds = ms;
    };
    
    void increaseOneHour(){
      // as there is no day counter to increment  atm this if-else statement is a bit useless.
      // setHour(getHours() + 1) would have sufficed here with the current setter
      if(getHours()==23){
        setHours(0);
      }else{
        setHours(getHours() + 1);
      }
    };
    
    void increaseOneMinute(){
      if(getMinutes() == 59){
        increaseOneHour();
        setMinutes(0);
      }else{
        setMinutes(getMinutes() + 1);
      }
    };
    
    void increaseOneSecond(){
      if(getSeconds() == 59){
        increaseOneMinute();
        setSeconds(0);
      }else{
        setSeconds(getSeconds() + 1);
      }
    };
    
    void tick(){
      currentMilliseconds = millis();
      if(currentMilliseconds - getPreviousMilliseconds() >= getSecondInterval()){
        setPreviousMilliseconds(currentMilliseconds);
        increaseOneSecond();
      }
    };
};

// LEDCLOCKCONTROLLER CLASS ////////////////////////////////////////////////////////////////
class LedClockController{
  private:
    LedClock ledClock;
    int mode = 2;


  public:
    LedClockController(LedClock lc){
      ledClock = lc;
    };

    LedClock getLedClock(){
      return ledClock;
    };
    
    int getMode(){
      return mode;
    };

    void setMode(int newMode){
      mode = newMode;
    };

};

// ARDUINO CODE /////////////////////////////////////////////////////////////////////////

LedClock lc = LedClock();
LedClockController lcc(lc);

void setup() {
  Serial.begin(9600); //Begin serializer to print out value

}

void loop() {
//doesn't give me updated values
  if(lcc.getLedClock().getPreviousMilliseconds()<63000){
    Serial.println(lcc.getLedClock().getSeconds());
    lcc.getLedClock().tick();
  }

//does give me updated values
//commented out for now
/*
  if(lc.getPreviousMilliseconds()<63000){
    Serial.println(lc.getSeconds());
    lc.tick();
  }
*/

}

Q1: I have difficulties to update attributes of my LedClock attribute in my Controller class. When I target the LedClock by itself, everything runs fine but when I would update it via the Controller, then it wouldn't. In short, when getting the seconds in the first case, I could see the increment in values in the output. When I did the same thing but via the controller, the seconds stayed 0.

So I am missing something vital here. Can someone help/explain what I am missing?

Q2: Ideally I would want to create the LedClock object inside the constructor but didn't seem to find how to. I tried things that could make sense but with the issues I have been having, I was holding off on this:

LedClockController lcc(LedClock lc());
LedClockController lcc(LedClock);

//would make sense to me, I noticed C++ doesn't use the 'new' keyword so have no idea how to do that then
LedClockController lcc(LedClock());

All of those ran into compilation issues so probably another important C++ thing that I haven't taken into account.

P.S. I have been noticing that there are some different views on getter and setters (accessing the attributes directly vs actual functions). I have been using the method I am used to (and were mentioned on W3schools) because I will rely on setting logic in 1 place.

9duust
  • 33
  • 2
  • 1
    short version: use `LedClockController(LedClock& lc) : ledClock(lc) {`. In C and C++ parameters are a copy. `LedClock&` is a reference so the reference is copied, not the object – Juraj Dec 11 '21 at 12:38
  • Oooh, ok wasn't aware it was copying instead of using the same object. Cool! Is there a need to inherit the LedClock? I saw you adding : LedClock(lc) at the end? – 9duust Dec 11 '21 at 14:32
  • it is `: ledClock(lc)`. that is not inheriting. read something about C++. that is initialization of member variables. reference can't be assigned with = so the only way to get it into an object is over the member initialization. other way would be to store a pointer. – Juraj Dec 11 '21 at 15:04
  • Thanks! It is a bit difficult to get around the way I used to think for these things. And indeed, was a bit to quick to jump to inheritance by just having seen the ':'. Found some info about initialization but will need to find more on WHY you can't use = (https://www.oreilly.com/library/view/c-cookbook/0596007612/ch08s02.html). This topic is answered – 9duust Dec 12 '21 at 08:45
  • https://stackoverflow.com/questions/57483/what-are-the-differences-between-a-pointer-variable-and-a-reference-variable-in/57492#57492 – Juraj Dec 12 '21 at 09:32

0 Answers0