Help with types/ overflow

This function is written as part of a class:

    //Functions for motorControl class
    //calculate the step gap for a given number of steps and desired output RPM

    double calculate_stepGap( double output_RPM, double steps) {
      _steps = steps;
      Serial.println("I'm in calculate_stepGap");
      Serial.println(_steps);
      Serial.println(output_RPM);
      
      //step_delay = 60L * 1000L * 1000L / number_of_steps / roles_Per_Minute;
      
      _stepGap = 1 / ((_steps * output_RPM) / (60L * 60L * 1000L )); //(steps * revs per hour (6 revs per hour for RA) / 3.6million MS per hour
      //_stepGap = (1 / (_steps * output_RPM) / (60L * 60L * 1000L));

      Serial.println(_stepGap);
      return _stepGap;
    }

This line uses the function:
Serial.println(raMotor.calculate_stepGap(6, raMotor.get_Steps(1)));

I'm trying to update this line of code in the function:
60L * 60L * 1000L
to this
60L * 60L * 1000L * 1000L

But I get this message:
warning: integer overflow in expression [-Woverflow]

So I think this is a problem with my chosen type as 60L * 60L * 1000L * 1000L returns 3.6 Billion

So I then update the type from double to long double like so:
long double calculate_stepGap( double output_RPM, double steps)

But now I get this error:

call of overloaded 'println(long double)' is ambiguous

I'm not sure why the type is now ambiguous. How do I update this line 60L * 60L * 1000L * 1000L?

Full code attached if that helps
V004_Controlling_Motors.ino (15.7 KB)

Many members, myself included, do not like to have to download code. Read the forum guidelines to see how to properly post code and some good information on making a good post.
Use the IDE autoformat tool (ctrl-t or Tools, Auto format) before posting code in code tags.

1 Like

full code is 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 slowAdjust 1
#define mediumAdjust 2
#define fastAdjust 3
#define IR_RECEIVE_PIN A0

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

//=======Create Classes================
class timeControl {
  public:


    unsigned long getTime(uint8_t currentTime = 1) { //currentTime = 1, Return the time (in micros) of right now
      //currentTime = 0, Returns storeSometime value
      if (currentTime==0){return micros();} //return the time now
      else if (currentTime ==1) {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
    }
    void 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
    }
    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 stopClockStart(unsigned long whatTime) {
      _startTime = whatTime;
    }
    double Counter (uint8_t controlCounter = 1) { //if controlCounter = 1, then increment the counter by 1. If controlCounter = 0 then reset to 0
      if (controlCounter ==1) {
        countNumber ++;
      }
      else return countNumber;
      countNumber = 0;
    }
    
    unsigned long microsPerCount(long startTime, long endTime, long counts) {
      _endTime = endTime;
      _startTime=startTime;
      _counts=counts;      
      return (_endTime  - _startTime)/_counts; //3) A function that subtracts one time against another and returns the answer.
    }
        
    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;
    unsigned long TimeToWait;
    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 _defaultRPM = get_defaultRPM();
      double _solarRPM = get_solarRPM();
      double _lunarRPM = get_lunarRPM();
      double _stepGap = calculate_stepGap(_defaultRPM, _steps);
      double _increment = get_increment(_incrementSpeed);
      double _motorDirection = get_motorDirection();
      double _currentRPM = set_currentRPM(_defaultRPM);
    }

    void begin() {

      if (_type == RAMotor) {
        Serial.println("I'm an RA Motor!");
        _defaultRPM = 6;
        _motorDirection = FORWARD;

      }
      else if (_type == DECMotor) {
        Serial.println("I'm a DEC Motor!");
        _defaultRPM = 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

    long double calculate_stepGap( double output_RPM, double steps) {
      _steps = steps;
      Serial.println("I'm in calculate_stepGap");
      Serial.println(_steps);
      Serial.println(output_RPM);
      
      //step_delay = 60L * 1000L * 1000L / number_of_steps / roles_Per_Minute;
      
      _stepGap = 1 / ((_steps * output_RPM) / (60L * 60L * 1000L * 1000L )); //(steps * revs per hour (6 revs per hour for RA) / 3.6million MS per hour
      //_stepGap = (1 / (_steps * output_RPM) / (60L * 60L * 1000L));

      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 set_currentRPM(double output_RPM) {
      _currentRPM = output_RPM;
      return _currentRPM;
    }

    double get_maxRPM() {
      double _maxRPM = _defaultRPM * (1.05);
      return _maxRPM;
    }
    double get_minRPM() {
      double _minRPM = _defaultRPM * (0.95);
      return _minRPM;
    }
    double get_defaultRPM() {
      double _defaultRPM = 6;
      return _defaultRPM;
    }

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

    double get_increment(uint8_t incrementSpeed) {
      uint8_t _incrementSpeed = incrementSpeed;
      if (_incrementSpeed = slowAdjust) {
        _maxRPM = get_maxRPM();
        _minRPM = get_minRPM();
        double _increment = (_maxRPM - _minRPM) / 100.0;
        return _increment;

      }  else if  (_incrementSpeed = mediumAdjust) {

        _maxRPM = get_maxRPM();
        _minRPM = get_minRPM();
        double _increment = (_maxRPM - _minRPM) / 10.0;
        return _increment;

      }  else if (_incrementSpeed = fastAdjust) {

        _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() {
      return _stepGap;
    }

    uint8_t get_motorDirection() {
      _motorDirection = _motorDirection;
      return _motorDirection;
    }
    //

  private:
    double _steps;
    double _stepGap;
    uint8_t _type;
    double _defaultRPM;
    double _currentRPM;
    double _maxRPM;
    double _minRPM;
    double _solarRPM;
    double _lunarRPM;

    uint8_t _incrementSpeed;
    double _increment;

    uint8_t _motorDirection;

};
//--------------------------------------
//=======Functions=====================
//--------translateIR Function----------
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 929046: 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 929024: Serial.println("1");          break;
    case 929025: Serial.println("2");          break;
    case 929026: Serial.println("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");
    //startTimer           
    break;
    case 929081: Serial.println("Up");            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



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

AF_Stepper motor2(1024, 2);
AF_Stepper motor1(1024, 1);

timeControl RATimer;
timeControl DecTimer;
timeControl IRTimer;

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


//=======SET UP=======================
void setup() {
  Serial.begin(9600);
  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));
  
  //RATimer.waitTime(raMotor.);
  //DecTimer.waitTime(decMotor.); 
  IRTimer.waitTime(500);
  Serial.println(RATimer.getTime(0));
  Serial.println(DecTimer.getTime(0));
  Serial.println(IRTimer.getTime(0));
  Serial.println("END Initialise Timers");

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

  if (doit == 1) {
    //add these one by one
    // Serial.println ("print RA Motor things") ;
    Serial.println (raMotor.get_Steps(1));
    //Serial.println (raMotor.get_stepGap());
    Serial.println (raMotor.get_defaultRPM());
    Serial.println (raMotor.get_maxRPM());
    Serial.println (raMotor.get_minRPM());
    Serial.println (raMotor.get_solarRPM());
    Serial.println (raMotor.get_lunarRPM());
    Serial.println (raMotor.get_increment(slowAdjust));
    Serial.println(raMotor.calculate_stepGap(6, raMotor.get_Steps(1)));
    Serial.println (raMotor.get_motorDirection());//returns shite, needs fixing
    doit = 2;
  }


  //Wait for IR Time to pass
  //need to initialise these variables then write the code in
  if   (IRTimer.timeDifference(IRTimer.getTime(0), IRTimer.getTime(1)) > IRTimer.getTime(2)) {



    if (IrReceiver.decode()) {

      translateIR(IrReceiver.decodedIRData.decodedRawData);
      delay(500);
      IrReceiver.resume(); // Enable receiving of the next value
    }
  }
  //Wait for RA Stepper time to pass
  //If TimerControl.RATimer(NOW) - TimerControl.RATimer(Micros())> MotorControl.RAstepGap then
  //step RA Stepper one step

  //    If motor1 step time has passed, then rotate one step
  //
  //    motor1.step(1, stepperControl.direction, DOUBLE);
  //    motor1.step(1, FORWARD, DOUBLE);
  //
  //    If motor2 step time has passed, then rotate one step
  //    motor2.step(1, stepperControl.direction, DOUBLE);
  //    motor2.step(1, FORWARD, DOUBLE);

  //wait for DEC stepper time to pass
  //If TimerControl.DECTimer(NOW) - TimerControl.DECTimer(Micros())> MotorControl.DECstepGap then
  //step DEC stepper one step


}

Yes. Rewrite that calculation so that you do not need such ridiculously large numbers.

1 Like

Fair one. :laughing: I was giving the advice you gave in another post a try by converting millis() to micros()! Surprised that there's nothing else I can do though? Why doesn't double long just work? 3.6 BN is within the bounds?

60L * 60L * 1000L * 1000L  // signed expression overflows on 32 bit

60UL * 60UL * 1000UL * 1000UL  // could work

But even if that works, the next overflow is near. :grinning:

does work!

As I invert the number I'm thinking I'll be OK :grimacing:.... the "big" number doesn't grow, it shrinks... that's the theory anyway....!:laughing:

The compiler could even be able to handle

60LL * 60LL * 1000LL * 1000LL
1 Like

No, it is not, for a signed long. And AVR based Arduinos do not support double.

Instead double is treated as a 32 bit float, which has considerably less numerical precision than integer type double.

1 Like

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