updating object variables outside of the constructor

Hi all.
I wrote this class which allows me to create objects which pulse led's on different pins at different speeds. it works fine but i would like to dynamically update the values so i can change the speeds.
I have tried making the objects variables public and accessing them in the loop but that didnt seem to work.
i also tried creating a variable with the time values in and inputting that in the object constructor and then updating it it in the loop but still didnt work.
i feel i know whats wrong, ie. the object is only using the values from the original constructor and i need to tweak the code so it looks to an 'outside variable' but i don't know how to implement it.
Any help would be much appreciated. thanks, Danny

class Pulse {


    bool isRising = true;
    byte analogVal = 0;
    unsigned long risingTime; 
    unsigned long fallingTime;
    int pin;
    unsigned long timer;
    float risingTimingVal;
    float fallingTimingVal;
  public:  bool play = false; bool once = true;


  public:
    Pulse(unsigned long risingTime_, unsigned long fallingTime_, int pin_) {
      risingTime = risingTime_;
      fallingTime = fallingTime_;
      pin = pin_;
      timer = millis();
      risingTimingVal = risingTime / 255; //this is the value which will be put inbetween each analogwrite increment(0-255)
      fallingTimingVal = fallingTime / 255;
      pinMode(pin, OUTPUT);
    }

    void update() {
      if (isRising == true) {
        if (millis() - timer > risingTimingVal) {
          timer = millis();

          if (analogVal < 255) {
            analogWrite(pin, analogVal);
            analogVal++;
          }
          else {
            isRising = false;
          }
        }
      }
      else {
        if (millis() - timer > fallingTimingVal) {
          timer = millis();

          if (analogVal > 0) {
            analogWrite(pin, analogVal);
            analogVal--;
          }
          else {
            isRising = true;
          }
        }
      }
    }
};

Private member variables can only be changed with a member function. If you look at other classes (or libraries) you will see get and set functions to change or read those private variables.

Make a member set function like

void setRisingTime( unsigned long newTime)
{
 risingTime = newTime;
}

Then in your sketch, call the set function with the new value.

Hmmm....i havent managed to get that to work as per the following...
I put in a println and the time does change but the result doesnt...(ps. thanks for the quick reply)

class Pulse {


    bool isRising = true;
    byte analogVal = 0;
    unsigned long risingTime;
    unsigned long fallingTime;
    int pin;
    unsigned long timer;
    float risingTimingVal;
    float fallingTimingVal;
  public:  bool play = false; bool once = true;


  public:
    Pulse(unsigned long risingTime_, unsigned long fallingTime_, int pin_) {
      risingTime = risingTime_;
      fallingTime = fallingTime_;
      pin = pin_;
      timer = millis();
      risingTimingVal = risingTime / 255; //this is the value which will be put inbetween each analogwrite increment(0-255)
      fallingTimingVal = fallingTime / 255;
      pinMode(pin, OUTPUT);
    }

    void update() {
      if (isRising == true) {
        if (millis() - timer > risingTimingVal) {
          timer = millis();

          if (analogVal < 255) {
            analogWrite(pin, analogVal);
            analogVal++;
          }
          else {
            isRising = false;
          }
        }
      }
      else {
        if (millis() - timer > fallingTimingVal) {
          timer = millis();

          if (analogVal > 0) {
            analogWrite(pin, analogVal);
            analogVal--;
          }
          else {
            isRising = true;
          }
        }
      }
    }

    void setTimes(unsigned long newRisingTime, unsigned long newFallingTime){
      risingTime = newRisingTime;
      fallingTime = newFallingTime;
      Serial.println(risingTime);
    }

any thoughts?

Post the complete code.

but the result doesnt

I am not sure what that means. Can you post a complete (small) sketch that demonstrates the problem? One that we can load and run to see the result?

byte led0 = 3;
byte button = 13;

int led0_risingTime = 1000;
int led0_fallingTime = 1000;

void setup() {
  Serial.begin(9600);
  pinMode(button, INPUT_PULLUP); //pull the button pin up so connecting to ground creates a false 
}

class Pulse {

    bool isRising = true;
    byte analogVal = 0;
    unsigned long risingTime;
    unsigned long fallingTime;
    int pin;
    unsigned long timer;
    float risingTimingVal;
    float fallingTimingVal;
  public:  bool play = false; bool once = true;


  public:
    Pulse(unsigned long risingTime_, unsigned long fallingTime_, int pin_) {
      risingTime = risingTime_;
      fallingTime = fallingTime_;
      pin = pin_;
      timer = millis();
      risingTimingVal = risingTime / 255; //this is the value which will be put inbetween each analogwrite increment(0-255)
      fallingTimingVal = fallingTime / 255;
      pinMode(pin, OUTPUT);
    }

    void update() {
      if (isRising == true) {
        if (millis() - timer > risingTimingVal) {
          timer = millis();

          if (analogVal < 255) {
            analogWrite(pin, analogVal);
            analogVal++;
          }
          else {
            isRising = false;
          }
        }
      }
      else {
        if (millis() - timer > fallingTimingVal) {
          timer = millis();

          if (analogVal > 0) {
            analogWrite(pin, analogVal);
            analogVal--;
          }
          else {
            isRising = true;
          }
        }
      }
    }

    void setTimes(unsigned long newRisingTime, unsigned long newFallingTime){
      risingTime = newRisingTime;
      fallingTime = newFallingTime;
//      Serial.println(risingTime);
    }
};

Pulse pulse0(led0_risingTime, led0_fallingTime, led0);

void loop() {
    pulse0.update();

  if (digitalRead(button) == 0 ){
    pulse0.setTimes(100,100);
//    Serial.println(pulse0.risingTime);
  }

}

Should'nt you also:

    void setTimes(unsigned long newRisingTime, unsigned long newFallingTime){
      risingTime = newRisingTime;
      fallingTime = newFallingTime;
      risingTimingVal = risingTime / 255; //this is the value which will be put inbetween each analogwrite increment(0-255)
      fallingTimingVal = fallingTime / 255;
      Serial.println(risingTime);
    }

Jacques

The code works when your setTimes function is replaced with the setTimes function provided by jbellavance.

One thing. Setting the pinMode in the constructor is not good practice. If the constructor is called before setup() the hardware is not necessarily ready. That is why, often, you see a begin() method called in setup() to take care of the hardware settings once you know that everything is ready to go.

Fantastic, all working, thanks for the help and advice folks.

Constructor and begin:

    Pulse(unsigned long risingTime_, unsigned long fallingTime_, int pin_) {
      pin = pin_;
      timer = millis();
      setTimes(risingTime_, fallingTime);  //Just call the code that is already written
     }

    void begin() {  
      pinMode(pin, OUTPUT);  //This should not be placed in the constructor. The hardware may not be ready
    }

Jacques

I have been thinking about using millis() in a constructor. What do you think, Jacques? Would that be sort of the same as pinMode in terms of the hardware being setup?

I found the answer to the millis() in constructor question. This thread (replies #6 and #9) explains that millis() would belong in the begin() method for the same reason as pinMode.

I would avoid it - it seems like a similar problem as you would get with pinmode . On the other hand, what do you get if you try?

groundFungus:
I have been thinking about using millis() in a constructor. What do you think, Jacques? Would that be sort of the same as pinMode in terms of the hardware being setup?

if the constructor is called before init() has finished, it's likely to return zero if at all. So if you have a global instance, you can just initialize to zero.

or try

myValue = millis()? millis() : 0;

if you are dynamically creating objects...

Didn't know that.

I was told that I couldn't use pinMode() within the constructor because the hardware was not ready. Now I learn that I can't use millsi() because the init() method is not called until after all constructors are called.

We learn every day don't we?

BulldogLowell:
or try

myValue = millis()? millis() : 0;

if you are dynamically creating objects...

If you are dynamically creating the object, there is NO chance init() has NOT finished...
Regards,
Ray L.

wildbill:
On the other hand, what do you get if you try?

Always zero. The timer is not running when the (global) constructor is called. While calling millis in a (global) constructor won't cause any harm it is a waste of both Flash and CPU time. It is also misleading / confusing to anyone (including the future you) who maintains the code.

RayLivingston:
If you are dynamically creating the object, there is NO chance init() has NOT finished...
Regards,
Ray L.

I meant that with the above sample line of code, it would accomplish the initialization properly either way, as a Global object or dynamically...

whats init() ?

It is part on the code that the IDE automatically adds to your sketch. The code for init() is in wiring.c located at (on my system, for instance) e:\arduino-1.6.7\hardware\arduino\avr\cores\arduino. The init() function does the hardware set up.