Help with Class variable

Apologies - I'm a bit "in and out" over the next couple of days, so might not be able to reply straight away.

I have a variable in my code called _incrementIndex that isn't behaving as I'd like.

I have a class called:

class motorControl {

It has a constructor where I declare the variable in the hope that it becomes a variable I can reference later (I'm not sure quite why this works, but seems to work for some other variables - don't beat me up on this please - I've a feeling it's this part may need some work)

Public:
....
motorControl() {
....
int _incrementIndex = 1;

There are two relevant methods within the class that I'm calling. One set the value of _incrementIndex and one to retrieve it.

    int get_incrementIndex() {
      //int _incrementIndex = incrementIndex;
      Serial.println("Im in get_incrementIndex, and am about to print _incrementIndex");
      Serial.println(_incrementIndex);
      Serial.println("^^did i do it??^^");
      return _incrementIndex;
    }

    void set_increment(int increment) {
      Serial.println("set_increment");
      int _incrementIndex = increment;
      Serial.println(_incrementIndex); //only works when I declare the variable in private
    }

and I'm declaring some of the variables private

	 private:
....
    int _incrementIndex;

This is a contradiction I appreciate, but if I don't have this, then my function void set_increment(int increment) complains about undeclared variables. Which is another place where this could all be failing.

I create my objects

timeControl RATimer;
timeControl DecTimer;
timeControl IRTimer;

And i have a function that translates my infra red code. When I press button 1 on my remote, I'm expecting the increment variable int _incrementIndex to be changed to 1, and stored in the class so I reference it later.

void translateIR(unsigned long IRraw) // takes action based on IR code received
{
  //Serial.print("translateIR");
  switch (IRraw)

  {
    case 404736: //Serial.println("");
      //set increments to 1
      Serial.println("Setting increment for both motors");
      decMotor.set_increment(1);
      raMotor.set_increment(1);

      Serial.println("Getting increment indexfor both motors");
      Serial.println(decMotor.get_incrementIndex());//returns 0. Why?
      raMotor.get_incrementIndex();

In my Serial monitor, the messages here are printed:

Im in get_incrementIndex, and am about to print _incrementIndex
0
^^did i do it??^^

I'm expecting to see 1 rather than 0.

What have I missed? What do i need to change so that 1 appears instead of 0 when the code return _incrementIndex; executed when I press 1 on my remote control?

Full code here.


//======Includes=======================
#include "Arduino.h"
#include <AFMotor.h>
//IR controls
//#include "PinDefinitionsAndMore.h"
#include <IRremote.hpp>

//======Define stuff===================

#define RAMotor 1
#define DECMotor 2
#define FORWARD 1
#define BACKWARD 2
#define IR_RECEIVE_PIN A0

//====================================
//=======Classes======================
//====================================

//=======Create Classes================
class timeControl {
  public:
    unsigned long MPC;
    long countNumber;

    unsigned long currentTime;
    unsigned long storedTime;
    unsigned long TimeToWait;
    double storedNumber;
    timeControl() {
      storedTime = savedTime(micros());
      storedNumber = 6; //
      TimeToWait = 1;
      currentTime = 1;
      countNumber = 2;
      _startTime = 1;
      MPC = microsPerCount();
    }

    unsigned long getTime(uint8_t currentTime = 1) { //0 = currentTime = 0, 1 = stored time, 2 = wait time, 3 = count, 4 = RPM
      if (currentTime == 0) {
        return micros(); //return the time now
      }
      else if (currentTime == 1) {
        storedTime = _storedTime;
        return storedTime; //return the time (for last time activated)
      }
      else if (currentTime == 2) {
        return TimeToWait; //return the time to wait before attempting to activate again
      }
      else if (currentTime == 3) {
        return countNumber; //return the time to wait before attempting to activate again
      }
      else if (currentTime == 4) {
        return countNumber; //return the time to wait before attempting to activate again
      }
    }
    unsigned long savedTime(unsigned long whatTime) {
      _storedTime = whatTime;  //2) Store some arbitrary time that I pass to it so I can reference it later. normally used to save the last step time
      unsigned long storedTime = _storedTime;
      return _storedTime;
    }
    double savedNumber(unsigned long whatNumber) {
      _storedNumber = whatNumber;  //2) Store some arbitrary time that I pass to it so I can reference it later. normally used to save the last step time
      unsigned long storedNumber = _storedNumber;
      return _storedNumber;
    }

    void waitTime(unsigned long whatTime) {
      TimeToWait = whatTime;  //2) Store some arbitrary time that I pass to it so I can reference it later. normally used to store the calculated step gap
    }
    void startTimer() {
      _startTime = millis();
    }
    unsigned long get_startTime() {
      return _startTime;
    }


    double Counter (uint8_t controlCounter = 1) { //if countrolCounter = 0, then reset to 0, controlCounter = 1 then increment the counter by 1. If controlCounter = 2 then return current count

      if (controlCounter == 0) {
        _countNumber = 0;
      }
      else if (controlCounter == 1) {
        _countNumber ++;
      }
      else if (controlCounter == 2) {
        countNumber = _countNumber;
        return countNumber;

      }

    }



    unsigned long microsPerCount() {
      _endTime = micros();
      //_startTime = startTime;
      //_counts = counts;
      MPC = (_endTime  - _startTime) / _counts; //3) A function that subtracts one time against another and returns the answer.
      return MPC;
    }

    unsigned long timeDifference(long startTime, long endTime) {
      _endTime = endTime;
      _startTime = startTime;
      return _endTime  - _startTime; //3) A function that subtracts one time against another and returns the answer.
    }


  private:
    unsigned long _storedTime;
    double _storedNumber;
    long _startTime;
    long _endTime;
    long _counts;
    long _countNumber;


};

//-------------------------------------
class motorControl {



  public:
    //constructor for motorControl class
    //I think this is a constructor and should execute when the object is created AND IT DOES!! YAY!
    motorControl (uint8_t motorType) {
      _type = motorType;
    }

    //Set methods so that they are available all the time
    motorControl() {
      double _maxRPM = get_maxRPM();
      double _minRPM = get_minRPM();
      double _steps = get_Steps(1);
      double _currentRPH = 0;
      double _solarRPM = get_solarRPM();
      double _lunarRPM = get_lunarRPM();
      double _stepGap = calculate_stepGapRPM(_currentRPH, _steps);
      //double _increment = get_increment(_incrementSpeed);
      double _increment = 1;
      double _motorDirection = get_motorDirection();
      int _gap = 0;
      unsigned long _startTimeGTD = 0;
      unsigned long _endTimeGTD = 0;
      unsigned long _counterGTD = 0;
      int _incrementIndex = 1;

    }

    void begin() {

      if (_type == RAMotor) {
        Serial.println("I'm an RA Motor!");
        _currentRPH = 60;//this does nothing - setup overrides this value
        _motorDirection = FORWARD;

      }
      else if (_type == DECMotor) {
        Serial.println("I'm a DEC Motor!");
        _currentRPH = 0;
        _motorDirection = FORWARD;

      }
      else {
        Serial.println("I'm an unknown Motor!");
        _motorDirection = FORWARD;
      }

    }


    //Functions for motorControl class
    //calculate the step gap for a given number of steps and desired output RPM
    unsigned long calculate_stepGapTimeDiff(unsigned long startTimeGTD, unsigned long endTimeGTD, unsigned long counterGTD) {
      //startTime is millis (to limit overflow rollover issues - millis repeats every 47 days, micros repeats every 17 minutes)
      unsigned long _startTimeGTD = startTimeGTD;
      unsigned long _endTimeGTD = endTimeGTD;
      unsigned long _counterGTD = counterGTD;

      _stepGap = ((_endTimeGTD - _startTimeGTD) / _counterGTD);
      return _stepGap;

    }

    unsigned long calculate_stepGapRPM( double output_RPM, double steps) {
      _steps = steps;
      //Serial.println("I'm in calculate_stepGapRPM");
      //Serial.println(_steps);
      //Serial.println(output_RPM);

      //step_delay = 60L * 1000L * 1000L / number_of_steps / roles_Per_Minute;

      _stepGap = (60UL * 60UL * 1000UL * 1000UL ) / (_steps * output_RPM); //(steps * revs per hour (6 revs per hour for RA) / 3.6million MS per hour
      //_stepGap = (1 / (_steps * output_RPM) / (60L * 60L * 1000L));
      _currentRPH = output_RPM;
      //Serial.println(_stepGap);
      return _stepGap;
    }

    //store the number of steps for one rotation of the stepper motor
    //    void steps(double get_steps) {
    //      _steps = get_steps;
    //
    //    }


    double get_maxRPM() {
      double _maxRPM = _currentRPH * (1.05);
      return _maxRPM;
    }
    double get_minRPM() {
      double _minRPM = _currentRPH * (0.95);
      return _minRPM;
    }
    double get_currentRPH() {
      return _currentRPH;
    }

    void set_currentRPH(double setRPM) {
      _currentRPH = setRPM;
    }


    double get_solarRPM() {
      double _solarRPM = 6;
      return _solarRPM;
    }
    double get_lunarRPM() {
      double _lunarRPM = _currentRPH * (27.0 / 28.0);
      return _lunarRPM;
    }

    int get_incrementIndex() {
      //int _incrementIndex = incrementIndex;
      Serial.println("Im in get_incrementIndex, and am about to print _incrementIndex");
      Serial.println(_incrementIndex);//only works when I declare the variable in private
      Serial.println("^^did i do it??^^");
      return _incrementIndex;
    }

    void set_increment(int increment) {
      Serial.println("set_increment");
      int _incrementIndex = increment;
      Serial.println(_incrementIndex);
    }


    double get_incrementRPH(uint8_t incrementSpeed) {
      uint8_t _incrementSpeed = incrementSpeed;
      if (_incrementSpeed = 1) {
        _maxRPM = get_maxRPM();
        _minRPM = get_minRPM();

        Serial.println("_minRPM:");
        Serial.println(_minRPM);
        double _increment = (_maxRPM - _minRPM) / 100.0;
        return _increment;

      }  else if  (_incrementSpeed = 2) {

        _maxRPM = get_maxRPM();
        _minRPM = get_minRPM();
        Serial.println("_minRPM:");
        Serial.println(_minRPM);
        double _increment = (_maxRPM - _minRPM) / 10.0;
        return _increment;

      }  else if (_incrementSpeed = 3) {

        _maxRPM = 15;
        double _increment = 1;
        return _increment;
      }

    }


    double get_Steps(int precision) { //1 if 2048 (high precision) 2 if 1024 (low precision)
      double _steps;
      if (precision = 1) {
        return _steps = 2048;
      }
      else if (precision = 2) {
        return _steps = 1024;
      }
      else {
        return _steps = 2048;
      }
    }


    double get_stepGap(double gap) {
      gap;
      if (gap = 0) {
        return _stepGap;
      }
      else {
        _stepGap = gap;
      }

    }

    uint8_t get_motorDirection() {
      return _motorDirection;
    }
    //

  private:
    double _steps;
    double _stepGap;
    uint8_t _type;
    double _currentRPH;
    //double _currentRPM;
    double _maxRPM;
    double _minRPM;
    double _solarRPM;
    double _lunarRPM;
    int gap;
    uint8_t _incrementSpeed;
    double _increment;
    int _incrementIndex;
    uint8_t _motorDirection;
    unsigned long startTimeGTD;
    unsigned long endTimeGTD;
    unsigned long counterGTD;
};

//=======Objects=======================
motorControl raMotor(RAMotor) ;
motorControl decMotor(DECMotor) ;

AF_Stepper motor_dec_stepper(1024, 1);
AF_Stepper motor_ra_stepper(1024, 2);

timeControl RATimer;
timeControl DecTimer;
timeControl IRTimer;

//--------------------------------------
//=======Functions=====================
//--------translateIR Function----------

bool counterHasStarted;
void translateIR(unsigned long IRraw) // takes action based on IR code received
// describing Remote IR codes
//unsigned long IRraw = IrReceiver.decodedIRData.decodedRawData;
{
  //Serial.print("translateIR");
  switch (IRraw)

  {
    //Elgoo Controller
    //    case 0xFFA25D: Serial.println("POWER");       break;
    //    case 0xFFE21D: Serial.println("FUNC/STOP");   break;
    //    case 0xFF629D: Serial.println("VOL+");        break;
    //    case 0xFF22DD: Serial.println("FAST BACK");   break;
    //    case 0xFF02FD: Serial.println("PAUSE");       break;
    //    case 0xFFC23D: Serial.println("FAST FORWARD"); break;
    //    case 0xFFE01F: Serial.println("DOWN");        break;
    //    case 0xFFA857: Serial.println("VOL-");        break;
    //    case 0xFF906F: Serial.println("UP");          break;
    //    case 0xFF9867: Serial.println("EQ");          break;
    //    case 0xFFB04F: Serial.println("ST/REPT");     break;
    //    case 0xFF6897: Serial.println("0");           break;
    //    case 0xFF30CF: Serial.println("1");     break;
    //    case 0xFF18E7: Serial.println("2");     break;
    //    case 0xFF7A85: Serial.println("3");     break;
    //    case 0xFF10EF: Serial.println("4");     break;
    //    case 0xFF38C7: Serial.println("5");     break;
    //    case 0xFF5AA5: Serial.println("6");     break;
    //    case 0xFF42BD: Serial.println("7");     break;
    //    case 0xFF4AB5: Serial.println("8");     break;
    //    case 0xFF52AD: Serial.println("9");     break;

    //Sony Blu-Ray controller
    case 404758: Serial.println("Eject");        break;
    case 165: Serial.println("Input Select");    break;
    case 149: Serial.println("TV Power");    break;
    case 929045: Serial.println("Main Power");        break;
    case 404736: //Serial.println("");
      //set increments to 1
      Serial.println("Setting increment for both motors");
      decMotor.set_increment(1);
      raMotor.set_increment(1);

      Serial.println("Getting increment indexfor both motors");
      Serial.println(decMotor.get_incrementIndex());
      raMotor.get_incrementIndex();

      
      Serial.println(decMotor.get_incrementRPH(decMotor.get_incrementIndex()));
      Serial.println(raMotor.get_incrementRPH(raMotor.get_incrementIndex()));

      break;
    case 404737: Serial.println("2");
      Serial.println("button 2 pressed");
      //set increments to 2
      break;
    case 404738: Serial.println("3");
      Serial.println("button 3 pressed");
      //set increments to 3
      break;
    case 929027: Serial.println("4");          break;
    case 929028: Serial.println("5");          break;
    case 929029: Serial.println("6");          break;
    case 929030: Serial.println("7");          break;
    case 929031: Serial.println("8");          break;
    case 929032: Serial.println("9");          break;
    case 929033: Serial.println("0");          break;
    case 929127: Serial.println("Red");          break;
    case 929128: Serial.println("Green");          break;
    case 929129: Serial.println("Yellow");         break;
    case 929126: Serial.println("Blue");           break;
    case 929068: Serial.println("Top Menu");       break;
    case 929065: Serial.println("Pop Up/Menu");    break;
    case 929091: Serial.println("Return");         break;
    case 929087: Serial.println("Options");        break;
    case 929090:
      Serial.println("Home");
      Serial.println("RATimer.countNumber");
      Serial.println(RATimer.countNumber);
      if (counterHasStarted == true) { //if the counter has been run before, then
        Serial.println("I'm going to start the RA timer");
        raMotor.get_stepGap(RATimer.microsPerCount());//calculate the micros Per Count (step gap), and store it
        RATimer.startTimer();//reset the timer
        RATimer.Counter(0); //reset the counter
      } else {
        counterHasStarted = true;
        RATimer.startTimer();
        RATimer.Counter(0);
        //raMotor.get_stepGap(raMotor.calculate_stepGapRPM(raMotor.get_solarRPM(), raMotor.get_Steps(1)) ) ;
      }
      Serial.println("New Step Gap");
      Serial.println(raMotor.get_stepGap(0));

      Serial.println("");
      break;
    case 929081: Serial.println("Up");
      // get current speed
      decMotor.get_currentRPH();
      Serial.println(decMotor.get_incrementRPH(decMotor.get_incrementIndex()));
      // get increment
      Serial.println(raMotor.get_incrementRPH ( raMotor.get_incrementIndex())); //1 = slow, 2 = medium, 3 = fast
      // add both and recalculate speed

      break;
    case 929082: Serial.println("Down");           break;
    case 929083: Serial.println("Left");           break;
    case 929084: Serial.println("Right");          break;
    case 929085: Serial.println("Select/OK");      break;
    case 929050: Serial.println(">");              break;
    case 929049: Serial.println("\"");             break;
    case 929051: Serial.println("<< ");            break;
    case 929052: Serial.println(">>");             break;
    case 929111: Serial.println("|<< or Pentax Shutter Release");    break;
    case 929110: Serial.println(">>| or Pentax Shutter Release");    break;
    case 929048: Serial.println("Stop");           break;
    case 929123: Serial.println("Subtitles");      break;
    case 929124: Serial.println("Audio");          break;
    case 146: Serial.println("Vol + ");            break;
    case 147: Serial.println("Vol - ");            break;
    case 148: Serial.println("Mute");              break;
    case 929118: Serial.println("Favourite");      break;
    case 929089: Serial.println("Display");        break;
    default: Serial.println(IRraw); break;

  }// End Case

  //Serial.print(step_delay);
} //END translateIR





//=======Global Variables=======================
int doit = 1;
double last_IR_Time;

//=======SET UP=======================
void setup() {
  Serial.begin(9600);
  counterHasStarted = false;
  raMotor.begin();
  decMotor.begin();
  IrReceiver.begin(IR_RECEIVE_PIN, ENABLE_LED_FEEDBACK);




  //waitTime
  Serial.println("Initialise Timers");
  RATimer.savedTime(RATimer.getTime(1));//save the time NOW
  DecTimer.savedTime(DecTimer.getTime(1));
  IRTimer.savedTime(IRTimer.getTime(1));

  Serial.println(RATimer.getTime(0));
  Serial.println(RATimer.getTime(1));
  Serial.println(RATimer.getTime(2));

  Serial.println("wait time (setup)");
  RATimer.waitTime(raMotor.calculate_stepGapRPM(2000 , 2048)); //6 RPH
  DecTimer.waitTime(decMotor.calculate_stepGapRPM(60, 2048)); //change to 0 when live - //add line to release motor if 0.
  Serial.println(RATimer.getTime(2));

  //DecTimer.waitTime(decMotor.);
  IRTimer.waitTime(500);
  Serial.println("END Initialise Timers");



}
//=======MAIN LOOP=======================
void loop() {
  // raMotor.steps(2048);

  //serial
  //Wait for IR Time to pass
  //need to initialise these variables then write the code in
  if   (micros() >= IRTimer.getTime(1) + IRTimer.getTime(2)) {
      //check the wait time here!! is it working?


    if (IrReceiver.decode()) {
      translateIR(IrReceiver.decodedIRData.decodedRawData);
      IrReceiver.resume(); // Enable receiving of the next value
    }
  };


  if (micros() >= (RATimer.getTime(1) + RATimer.getTime(2)))

  {
    //Serial.println("time difference-desired difference");
    //Serial.println(RATimer.getTime(2));
    //Serial.println("time difference-actual error gap");
    //Serial.println(RATimer.timeDifference(RATimer.getTime(1), micros())- RATimer.getTime(2));
    //Serial.println("GAP");
    //Serial.println(RATimer.getTime(2));

    motor_ra_stepper.step(1, BACKWARD, DOUBLE); // need to change direction to variable
    RATimer.savedTime(micros());//save the time of the last step
    RATimer.Counter(1);//increment the counter



  }  if (micros() >= (DecTimer.getTime(1) + DecTimer.getTime(2)))
  {
    //    Serial.println("time difference-desired difference");
    //    Serial.println(DecTimer.getTime(2));
    //Serial.println("time difference-actual error gap");
    //Serial.println(DecTimer.timeDifference(DecTimer.getTime(1), micros())- DecTimer.getTime(2));

    motor_dec_stepper.step(1, FORWARD, DOUBLE); // need to change direction to variable
    DecTimer.savedTime(micros());//save the time of the last step
    DecTimer.Counter(1);//increment the counter



  }

};

When you do this you are creating local variables with the same names as your member variables. When the constructor ends, those local variables disappers.

    //Set methods so that they are available all the time
    motorControl()
    {
      double _maxRPM = get_maxRPM();
      double _minRPM = get_minRPM();
      double _steps = get_Steps(1);
      double _currentRPH = 0;
      double _solarRPM = get_solarRPM();
      double _lunarRPM = get_lunarRPM();
      double _stepGap = calculate_stepGapRPM(_currentRPH, _steps);
      //double _increment = get_increment(_incrementSpeed);
      double _increment = 1;
      double _motorDirection = get_motorDirection();
      int _gap = 0;
      unsigned long _startTimeGTD = 0;
      unsigned long _endTimeGTD = 0;
      unsigned long _counterGTD = 0;
      int _incrementIndex = 1;
    }

What you probably WANTED to do is set the values of your member varibles.

    //Set methods so that they are available all the time
    motorControl()
    {
      _maxRPM = get_maxRPM();
      _minRPM = get_minRPM();
      _steps = get_Steps(1);
      _currentRPH = 0;
      _solarRPM = get_solarRPM();
      _lunarRPM = get_lunarRPM();
      _stepGap = calculate_stepGapRPM(_currentRPH, _steps);
      //_increment = get_increment(_incrementSpeed);
      _increment = 1;
      _motorDirection = get_motorDirection();
      _gap = 0;
      _startTimeGTD = 0;
      _endTimeGTD = 0;
      _counterGTD = 0;
      _incrementIndex = 1;
    }

You will need to add member variable named '_gap'.

1 Like

This is common beginner mistake: using the assignment operator (=) when trying to compare for equality (==):

1 Like

Thanks for this @johnwasser . Seems to make sense. I’ll give it a try tomorrow evening and let you know how I get on. Sorry for the slow reply and thanks for taking the time :+1:

Yes - I think you are right. I've modified the code, and I've made _incrementIndex public, and removed it elsewhere. I can now access and update that anytime so that's much better than before.

Yes - well spotted. I updated all the bits where I missed that. I'm sure that wasn't helping either.

Thanks for taking the time to look through my code. Much appreciated.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.