[Newbie] cannot convert 'RotaryEncoder::Direction' to 'int' in initialization

Hey,

I am struggling to get this code to work. It's for the controller of a DIY Polishing Machine (French). I thought "Cool, I just order the parts upload the code and be done" :smiley:

Any help would be very much epreciated!

the error message I get when compiling reads the following:

exit status 1
cannot convert 'RotaryEncoder::Direction' to 'int' in initialization

And the line that causes the error:

  encoder.tick();

  long newVal = encoder.getPosition();
  int dir = encoder.getDirection(); <- This part is highlighted
 

I googled for a solution but, my "fix" just causes more errors :face_with_diagonal_mouth:

This is the full code:

#include <RotaryEncoder.h>
#include <SevSeg.h>
#include <EveryTimer.h>
#include <AccelStepper.h>

// PIN USAGE
#define SEVSEG_DIGIT_1    16
#define SEVSEG_DIGIT_2    17
#define SEVSEG_DIGIT_3    3
#define SEVSEG_DIGIT_4    4
#define SEVSEG_COLON      2
#define SEVSEG_SEGMENT_A  8
#define SEVSEG_SEGMENT_B  14
#define SEVSEG_SEGMENT_C  6
#define SEVSEG_SEGMENT_D  A1
#define SEVSEG_SEGMENT_E  23
#define SEVSEG_SEGMENT_F  7
#define SEVSEG_SEGMENT_G  5
#define SEVSEG_SEGMENT_H  22

#define ROT_BUTT    11
#define ROT_ENC_1   12
#define ROT_ENC_2   13
#define ROT_ENC_DIR -1

#define STEPPER_STEP              10
#define STEPPER_DIRECTION         0
#define STEPPER_ENABLE            A5

//SETTINGS
#define SEVSEG_REFRESH            250   // Refresh rate in ms
#define SEVSEG_BRIGHTNESS         100  // 100%, full brightness
#define STEPPER_MAX_SPEED         5000
#define STEPPER_MIN_SPEED         0
#define STEPPER_ACCELERATION      30.0
#define STEP_MOTOR_STEPS_PER_TURN 200
#define STEPPER_MICROSTEP         8

SevSeg sevseg; //Instantiate a seven segment controller object

// Setup a RoraryEncoder for pins 12 and 13:
RotaryEncoder encoder(ROT_ENC_1, ROT_ENC_2);

AccelStepper stepper(1, STEPPER_STEP, STEPPER_DIRECTION);

EveryTimer cntdwn;
EveryTimer calc_dspl;

//Global variables

byte numDigits = 4;
byte digitPins[] = {SEVSEG_DIGIT_1, SEVSEG_DIGIT_2,
                    SEVSEG_DIGIT_3, SEVSEG_DIGIT_4};
byte segmentPins[] = {SEVSEG_SEGMENT_A, SEVSEG_SEGMENT_B, 
                      SEVSEG_SEGMENT_C, SEVSEG_SEGMENT_D,
                      SEVSEG_SEGMENT_E, SEVSEG_SEGMENT_F,
                      SEVSEG_SEGMENT_G, SEVSEG_SEGMENT_H};
bool resistorsOnSegments = false; // 'false' means resistors are on digit pins
byte hardwareConfig = COMMON_ANODE; // See README.md for options
bool updateWithDelays = false; // Default. Recommended
bool leadingZeros = false; // Use 'true' if you'd like to keep the leading zeros
long refresh_timer = 0;

long countdown = 0;
byte days = 0;
byte hours = 0;
byte minutes = 0;
byte seconds = 0;
int current_rpm = 0;
int new_rpm = 0;
static bool currBut = true;
byte mode = 0;

void countdown_callback() {
  if (current_rpm != 0) {   // if speed = 0 => pause countdown
    countdown--;
    if (countdown < 0) {
      countdown = 0;
    }
    recalculate_DHMS();
    //Serial.println(countdown);
  }
  else {
    Serial.println("Pause");
  }
}

void calculate_display_callback() {
  // Update data to be displayed
  if (mode == 0) {          // mode 0 = display speed
    digitalWrite(SEVSEG_COLON, false);  
    sevseg.setNumber(current_rpm);
  } 
  else if (mode == 1) {     // mode 1 = display countdown
    //Blink colon each seconds
    if (countdown % 2) {
      digitalWrite(SEVSEG_COLON, true);
    }
    else {
      digitalWrite(SEVSEG_COLON, false);
    }
    //Display dd:HH if there is more than 1day left, HH:MM if less or MM:SS if there is less than 1h left
    if (days) {
      char dispBuf[] = "0d00";
      dispBuf[0] = days + 48;
      dispBuf[2] = (hours / 10) + 48;
      dispBuf[3] = (hours % 10) + 48;
      sevseg.setChars(dispBuf);
    }
    else if (hours) {
      sevseg.setNumber(100*hours+minutes);
    } else {
      sevseg.setNumber(100*minutes+seconds);
    }
  }
}

void update_encoder() {
  static long currVal = 0;
  int multiplier = 10;
  
  encoder.tick();

  long newVal = encoder.getPosition();
  int dir = encoder.getDirection();
 
  if (currVal != newVal) {
    currVal = newVal;
    if (mode == 0) {    // Mode 0 : speed setting
      multiplier = 10;
      if (current_rpm >= 500) {
        multiplier = 100;   // default : 1 encoder step = +/- 10 step/min
                            // if speed > 500 : encoder step = +/- 100 step/min
      }
      new_rpm += multiplier * dir * ROT_ENC_DIR;
      if (new_rpm < STEPPER_MIN_SPEED) {
        new_rpm = STEPPER_MIN_SPEED;
      }
      if (new_rpm > STEPPER_MAX_SPEED) {
        new_rpm = STEPPER_MAX_SPEED;
      }
    }
    if (mode == 1) {    //mode 1 : countdown setting
      multiplier = 60;  // default : 1 encoder step = +/- 1min
                        // if countdown > 1h : encoder step = +/- 10min (600s)
                        // if countdown > 1d : encoder step = +/- 1h (3600s)
      if (countdown >= 86400) {
        multiplier = 3600;
      }
      else if (countdown >= 3600) {
        multiplier = 600;
      }
      countdown += multiplier * dir * ROT_ENC_DIR;

      //Min: 0 = no negative timer value
      if (countdown < 0) {
        countdown = 0;
      }
      
      // Max: 864000s = 10 days
      if (countdown >= 864000) {
        countdown = 863999;
      }
      
      recalculate_DHMS();
    }
    Serial.print("RPM: ");
    Serial.print(new_rpm);
    Serial.print(" | Countdown: ");
    Serial.println(countdown);
  }

  //Check button for mode change
  bool newBut = digitalRead(ROT_BUTT);
  if (newBut != currBut) {
    currBut = newBut;
    if (currBut) {
      mode++;
    }
    
    if (mode == 2) {
      mode = 0;
    }
    else if (mode == 0) {
      encoder.setPosition(current_rpm);
    }
    else if (mode == 1) {
      encoder.setPosition(countdown);
    }
    Serial.print("Mode :");
    Serial.println(mode);
  }
}

void update_stepper() {

  //Update speend setting and ENABLE pin if new speed value
  if (new_rpm != current_rpm) {
    current_rpm = new_rpm;
    stepper.setSpeed(current_rpm);
    // Enable/Disable motor
    if (current_rpm == 0) {
      stepper.disableOutputs();
      Serial.println("Stepper : Off");
    }
    else {
      stepper.enableOutputs();
      Serial.println("Stepper : On");
    }
  }
  //if Countdown = 0 => pause (no move but keep speed setting)
  if (countdown != 0 and current_rpm != 0) {
    //Serial.println("Run motor !");
    stepper.runSpeed();
  }
}

void recalculate_DHMS() {
  //Calculate days, hours, minutes and seconds to be display
  if (countdown >= 86400) {
    days = countdown / 86400;
    hours = (countdown % 86400) / 3600;  
  }
  else {
    days = 0;
    minutes = (countdown / 60) % 60;
    if (countdown >= 3600) {
      hours = countdown / 3600;  
    }
    else {
      hours = 0;
      seconds = countdown % 60;
    }
  }
}

void setup()
{  
  Serial.begin(115200);

  pinMode(ROT_BUTT, INPUT_PULLUP);
  pinMode(SEVSEG_COLON, OUTPUT);
  
  sevseg.begin(hardwareConfig, numDigits, digitPins, segmentPins, resistorsOnSegments, updateWithDelays, leadingZeros);
  sevseg.setBrightness(SEVSEG_BRIGHTNESS);

  stepper.setEnablePin(STEPPER_ENABLE);
  stepper.disableOutputs();
  stepper.setMaxSpeed(STEPPER_MAX_SPEED);
  stepper.setAcceleration(STEPPER_ACCELERATION);
  stepper.setSpeed(0);  

  cntdwn.Every(1000, countdown_callback);
  calc_dspl.Every(SEVSEG_REFRESH, calculate_display_callback);
}

void loop() {
  update_encoder();

  //Make the motor move
  update_stepper();

  //Update countdown
  cntdwn.Update();

  //refresh the 7-segment display
  calc_dspl.Update();
  sevseg.refreshDisplay();
}


The return value of

encoder.getDirection()

is not int, so you need to cast it to int if you want assign it.

See the examples for RotaryEncoder library

The getDirection() function does not return an 'int'. It returns an enum element of type 'Direction':

  enum class Direction {
    NOROTATION = 0,
    CLOCKWISE = 1,
    COUNTERCLOCKWISE = -1
  };

Try:

  RotaryEncoder::Direction dir = encoder.getDirection();

Replacing int dir = encoder.getDirection(); with RotaryEncoder::Direction dir = encoder.getDirection(); ( I hope this is what i was supposed to do :sweat_smile:)

It throws the next error:

no match for 'operator*' (operand types are 'int' and 'RotaryEncoder::Direction')

  else if (countdown >= 3600) {
    multiplier = 600;
  }
  countdown += multiplier * dir * ROT_ENC_DIR; <- This is highlighted

try

int dir = (int)encoder.getDirection();

I wrote - see how it's done in the library examples

Yea, if you want to use the return value for math operations, you'll have to cast it. I prefer to use datatypes as defined (or define them to be useful), but that's a workaround.

That seems to have fixed it! :smiley:

now i can finally check if the circuit works.
thank you so much for your patience and support.

-Max