Attempt to bring the interruptRotator.ino into my existing code and can't compile

Hi I'm learning a little more about this rotary encoder library it uses interrupts one or both to maintain an accurate count of position. I read in the description that your program can be doing things for 6-hole seconds then Rember its current position after completion of another task. first ill post its code and then Ill post my attempt to implement it as I copy the code from it and paste it into my current attempt with my sketch Im looking at this encoder library as a way to improve the motion of the stepper motor in my sketch and control the spot at which it stops with greater accuracy. I consider myself extremely new at Arduino and c++ . a lot of responses' so far have been hard to understand sometimes completely misunderstood. I know it's not easy for professionals to craft responses that undereducated people can understand i do appreciate your attempts. thank you . here is the working example followed by the non-working sketch that won't compile after the code has been added .

'''// -----
// InterruptRotator.ino - Example for the RotaryEncoder library.
// This class is implemented for use with the Arduino environment.
//
// Copyright (c) by Matthias Hertel, http://www.mathertel.de
// This work is licensed under a BSD 3-Clause License. See http://www.mathertel.de/License.aspx
// More information on: http://www.mathertel.de/Arduino
// -----
// 18.01.2014 created by Matthias Hertel
// 04.02.2021 conditions and settings added for ESP8266
// 03.07.2022 avoid ESP8266 compiler warnings.
// 03.07.2022 encoder instance not static.
// -----

// This example checks the state of the rotary encoder using interrupts and in the loop() function.
// The current position and direction is printed on output when changed.

// Hardware setup:
// Attach a rotary encoder with output pins to
// * 2 and 3 on Arduino UNO. (supported by attachInterrupt)
// * A2 and A3 can be used when directly using the ISR interrupts, see comments below.
// * D5 and D6 on ESP8266 board (e.g. NodeMCU).
// Swap the pins when direction is detected wrong.
// The common contact should be attached to ground.
//
// Hints for using attachinterrupt see https://www.arduino.cc/reference/en/language/functions/external-interrupts/attachinterrupt/

#include <Arduino.h>
#include <RotaryEncoder.h>

#if defined(ARDUINO_AVR_UNO) || defined(ARDUINO_AVR_NANO_EVERY)
// Example for Arduino UNO with input signals on pin 2 and 3
#define PIN_IN1 A2
#define PIN_IN2 A3

#elif defined(ESP8266)
// Example for ESP8266 NodeMCU with input signals on pin D5 and D6
#define PIN_IN1 D5
#define PIN_IN2 D6

#endif

// A pointer to the dynamic created rotary encoder instance.
// This will be done in setup()
RotaryEncoder *encoder = nullptr;

#if defined(ARDUINO_AVR_UNO) || defined(ARDUINO_AVR_NANO_EVERY)
// This interrupt routine will be called on any change of one of the input signals
void checkPosition()
{
  encoder->tick(); // just call tick() to check the state.
}

#elif defined(ESP8266)
/**
   @brief The interrupt service routine will be called on any change of one of the input signals.
*/
IRAM_ATTR void checkPosition()
{
  encoder->tick(); // just call tick() to check the state.
}

#endif


void setup()
{
  Serial.begin(115200);
  while (!Serial)
    ;
  Serial.println("InterruptRotator example for the RotaryEncoder library.");

  // setup the rotary encoder functionality

  // use FOUR3 mode when PIN_IN1, PIN_IN2 signals are always HIGH in latch position.
  // encoder = new RotaryEncoder(PIN_IN1, PIN_IN2, RotaryEncoder::LatchMode::FOUR3);

  // use FOUR0 mode when PIN_IN1, PIN_IN2 signals are always LOW in latch position.
  // encoder = new RotaryEncoder(PIN_IN1, PIN_IN2, RotaryEncoder::LatchMode::FOUR0);

  // use TWO03 mode when PIN_IN1, PIN_IN2 signals are both LOW or HIGH in latch position.
  encoder = new RotaryEncoder(PIN_IN1, PIN_IN2, RotaryEncoder::LatchMode::TWO03);

  // register interrupt routine
  attachInterrupt(digitalPinToInterrupt(PIN_IN1), checkPosition, CHANGE);
  attachInterrupt(digitalPinToInterrupt(PIN_IN2), checkPosition, CHANGE);
} // setup()


// Read the current position of the encoder and print out when changed.
void loop()
{
  static int pos = 0;

  encoder->tick(); // just call tick() to check the state.

  int newPos = encoder->getPosition();
  if (pos != newPos) {
    Serial.print("pos:");
    Serial.print(newPos);
    Serial.print(" dir:");
    Serial.println((int)(encoder->getDirection()));
    pos = newPos;
  } // if
} // loop ()


// To use other pins with Arduino UNO you can also use the ISR directly.
// Here is some code for A2 and A3 using ATMega168 ff. specific registers.

// Setup flags to activate the ISR PCINT1.
// You may have to modify the next 2 lines if using other pins than A2 and A3
//   PCICR |= (1 << PCIE1);    // This enables Pin Change Interrupt 1 that covers the Analog input pins or Port C.
//   PCMSK1 |= (1 << PCINT10) | (1 << PCINT11);  // This enables the interrupt for pin 2 and 3 of Port C.

// The Interrupt Service Routine for Pin Change Interrupt 1
// This routine will only be called on any signal change on A2 and A3.
// ISR(PCINT1_vect) {
//   encoder->tick(); // just call tick() to check the state.
// }

// The End'''

and the non-working

 #include <AccelStepper.h>
#include <Servo.h>
#include <RotaryEncoder.h>
Servo throttleServo;  // create servo object to control a throttleServo
#define motorInterfaceType 1                                                                                                                                          
#define startIndicator 7 
#define servoPin 4 
#define stepperMove 6

//2 lines of code below may need to change to the 2 lines after that 

#define outputA 5 // output of the rotry encoder input of the ardrino lower left of stepper driver
#define outputB 3// output of the rotry encoder input of the ardrino lower left of stepper driver
#define PIN_IN1 5
#define PIN_IN2 3


#define outputC 1//this is a magnetic switch on stepper motor
#define stepperEnable 8//
#define magnetSwitchStepper  2
#define stepperDirecton 10//
int currentStateA;
AccelStepper ForwardReverseStepper(motorInterfaceType, stepperMove, stepperDirecton);
int   counter;
int lastStateA;
int   A;
int   B;
int   C = 0;
int  highServoPosision  = 1600;      // this should prevent exceding max throttle // in miliseconds
int  LowhServoPosision  = 1000;      // this sets the lowest Idle speed// in miliseconds
int  highStepperPosision = 275 ;    // this this is the furthest the shifter will move in forward
int  LowhstepperPosision = -275;    // this  this is the furthest the shifter will move in revers
int  ForwardGearStop = 15;    //   gear shifting the spot at wich you have gone into F gear
int  ReverseGearStop = -15;   //   gear shifting the spot at wich you have gone into R gear
int  startServoPosision = 0;//
int  currentStepperPosision = 0;// 1500 microsecondsis writen as 1500
int  currentServoPosision = LowhServoPosision;
//void(* resetFunc) (void) = 0;
void setup() {
   ForwardReverseStepper.setMaxSpeed(90000);
  ForwardReverseStepper.setAcceleration(90000);
  ForwardReverseStepper.setSpeed(90000);
  ForwardReverseStepper.moveTo(0);
  pinMode(stepperEnable, OUTPUT);
  pinMode(stepperDirecton, OUTPUT);
  pinMode(stepperMove, OUTPUT); 
  pinMode(startIndicator, INPUT_PULLUP);  
  pinMode(outputB, INPUT_PULLUP);//outputA
  pinMode(outputA, INPUT_PULLUP);//outputB
  attachInterrupt(digitalPinToInterrupt(PIN_IN1), checkPosition, CHANGE);//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  attachInterrupt(digitalPinToInterrupt(PIN_IN2), checkPosition, CHANGE);//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 // attachInterrupt(digitalPinToInterrupt(2), nutralDetect, RISING);//
 // Serial.begin(115200);
  // Read the initial state of outputA on the rotory encoder
  lastStateA = digitalRead(outputA);
}
void loop() {
  static int pos = 0;
  int newPos = encoder->getPosition();//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
   encoder->tick(); // just call tick() to check the state.//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  if (pos != newPos) 
 {
    Serial.print("pos:");
    Serial.print(newPos);
    Serial.print(" dir:");
    Serial.println((int)(encoder->getDirection()));
    pos = newPos;
 // } // if
  currentStateA = digitalRead(outputA);
  if (currentStateA != lastStateA  && currentStateA == 1) {
    if (digitalRead(outputB) != currentStateA) {
      counter =(counter-1);//    increased from 1 to 2.2 because too many revolutions   currentDir = "CW";
    } else {
      // Encoder is rotating CW so increment
      counter  =(counter+1);//     increased from 1 to 2.2 because too many revolutions
         //                    currentDir = "CW";currentDir = "CCW";
    }
  }
  //**********************************************************************************
  // the servo control for throtle in forward ............. ie rotating  CW Blue 7 White 6
  //***********************************************************************************
  if (counter >= ForwardGearStop) {   
          // next 3 lines one last chance to get that stepper to the desired gear
  // ForwardReverseStepper.moveTo(currentStepperPosision);
   // while (ForwardReverseStepper.currentPosition() != currentStepperPosision)
   //   ForwardReverseStepper.run();
   
    //digitalWrite(stepperEnable, HIGH);// disable stepper high disables we
                                        //are soon to throtle up in forward                                   
    throttleServo.attach(servoPin);  // enable throttle servo attaches the servo on pin servoPin
    //exmap(counter, fromLow, fromHigh, toLow, toHigh)
    A = map(counter, 0 , 500, 0, 3000);// should amplify the throttle posision a higher
                                             //"to high"moves throtle faster                                                                                      
    B = A - 1 ; // I thought this was coing to b = a minus
                      //reverse gear stop so throttle 0 would be counter zero                    
          // next linelimits range of  values to between Idle rpm and full throtle
    B = constrain(B, LowhServoPosision , highServoPosision);
    currentServoPosision = B; // a declaration
    throttleServo.writeMicroseconds(currentServoPosision);  // moves the servo position according to the scaled
  }
  //**************************************************************************************
  // Servo control for throtle in reverse...................... Encoder is CCW Blue 7 White 6
  // ****************************************** ******************************************
  if (counter <= ReverseGearStop) {
    // next 3 lines one last chance to get that stepper to the desired gear
   //ForwardReverseStepper.moveTo(currentStepperPosision);
  //  while (ForwardReverseStepper.currentPosition() != currentStepperPosision)
  //    ForwardReverseStepper.run();  
  //  digitalWrite(stepperEnable, HIGH); //disable stepper high disables we
                                        //are soon to throtle up in reverse
    throttleServo.attach(servoPin);  // enable throttle servo attaches the servo on pin servoPin
    A = map(counter, 0 , 500, 0, -3000);
    B = A + 1;// I thought this was going to b equal to a plus
                //reverse gear stop so throttle 0 would be counter zero seems not matter              
        // next linelimits range of  values to between Idle rpm and full throtle
    B = constrain(B, LowhServoPosision , highServoPosision);
    currentServoPosision = B;
    throttleServo.writeMicroseconds(currentServoPosision);
  }
  //**************************************************************************
  // (Stepper) control between  reverse and Forward including nutral
  // **********************************************************************
  if ((counter < ForwardGearStop ) && (counter > ReverseGearStop)&&(counter > -44 ) && (counter < 44)) 
  {
    digitalWrite(stepperEnable, LOW);// low enables   
    throttleServo.writeMicroseconds(currentServoPosision); //one last chance to get that
                                                            ///hrotle servo to the Idle posision   
   throttleServo.detach();// disable servo
    //   exmap(counter, fromLow, fromHigh, toLow, toHigh)
    C = map(counter, 0 , -10, 5, -150); //stepper should respond faster as tolow and to high
                                       // get farther appart                                           
   //  next linelimits range of  values to between reverse and Nutral   
    C = constrain(C, LowhstepperPosision , highStepperPosision); //
    currentStepperPosision = C;
    ForwardReverseStepper.moveTo(currentStepperPosision);
 //  detachInterrupt(digitalPinToInterrupt(2));
 while (ForwardReverseStepper.currentPosition() != currentStepperPosision)
      ForwardReverseStepper.run();  
 // attachInterrupt(digitalPinToInterrupt(2), nutralDetect, RISING);//      
         }

         
  lastStateA = currentStateA; 
}

void nutralDetect() {
  ForwardReverseStepper.stop();
counter = 0;

}
void checkPosition()
{
  encoder->tick(); // just call tick() to check the state.
}

Where is the closing brace of the loop() function in your sketch ?

Did you forget to create an instance of RotaryEncoder named encoder in your sketch ?

Try this modified sketch. It compiles but I cannot test it

#include <AccelStepper.h>
#include <Servo.h>
#include <RotaryEncoder.h>
Servo throttleServo;  // create servo object to control a throttleServo
#define motorInterfaceType 1
#define startIndicator 7
#define servoPin 4
#define stepperMove 6

//2 lines of code below may need to change to the 2 lines after that

#define outputA 5  // output of the rotry encoder input of the ardrino lower left of stepper driver
#define outputB 3  // output of the rotry encoder input of the ardrino lower left of stepper driver
#define PIN_IN1 5
#define PIN_IN2 3

#define outputC 1        //this is a magnetic switch on stepper motor
#define stepperEnable 8  //
#define magnetSwitchStepper 2
#define stepperDirecton 10  //
int currentStateA;
AccelStepper ForwardReverseStepper(motorInterfaceType, stepperMove, stepperDirecton);
int counter;
int lastStateA;
int A;
int B;
int C = 0;
int highServoPosision = 1600;    // this should prevent exceding max throttle // in miliseconds
int LowhServoPosision = 1000;    // this sets the lowest Idle speed// in miliseconds
int highStepperPosision = 275;   // this this is the furthest the shifter will move in forward
int LowhstepperPosision = -275;  // this  this is the furthest the shifter will move in revers
int ForwardGearStop = 15;        //   gear shifting the spot at wich you have gone into F gear
int ReverseGearStop = -15;       //   gear shifting the spot at wich you have gone into R gear
int startServoPosision = 0;      //
int currentStepperPosision = 0;  // 1500 microsecondsis writen as 1500
int currentServoPosision = LowhServoPosision;
//void(* resetFunc) (void) = 0;

RotaryEncoder *encoder = nullptr;

void setup()
{
    ForwardReverseStepper.setMaxSpeed(90000);
    ForwardReverseStepper.setAcceleration(90000);
    ForwardReverseStepper.setSpeed(90000);
    ForwardReverseStepper.moveTo(0);
    pinMode(stepperEnable, OUTPUT);
    pinMode(stepperDirecton, OUTPUT);
    pinMode(stepperMove, OUTPUT);
    pinMode(startIndicator, INPUT_PULLUP);
    pinMode(outputB, INPUT_PULLUP);                                          //outputA
    pinMode(outputA, INPUT_PULLUP);                                          //outputB
    attachInterrupt(digitalPinToInterrupt(PIN_IN1), checkPosition, CHANGE);  //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    attachInterrupt(digitalPinToInterrupt(PIN_IN2), checkPosition, CHANGE);  //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
                                                                             // attachInterrupt(digitalPinToInterrupt(2), nutralDetect, RISING);//
                                                                             // Serial.begin(115200);
    // Read the initial state of outputA on the rotory encoder
    lastStateA = digitalRead(outputA);
}

void loop()
{
    static int pos = 0;
    int newPos = encoder->getPosition();  //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    encoder->tick();                      // just call tick() to check the state.//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    if (pos != newPos)
    {
        Serial.print("pos:");
        Serial.print(newPos);
        Serial.print(" dir:");
        Serial.println((int)(encoder->getDirection()));
        pos = newPos;
        // } // if
        currentStateA = digitalRead(outputA);
        if (currentStateA != lastStateA && currentStateA == 1)
        {
            if (digitalRead(outputB) != currentStateA)
            {
                counter = (counter - 1);  //    increased from 1 to 2.2 because too many revolutions   currentDir = "CW";
            }
            else
            {
                // Encoder is rotating CW so increment
                counter = (counter + 1);  //     increased from 1 to 2.2 because too many revolutions
                                          //                    currentDir = "CW";currentDir = "CCW";
            }
        }
        //**********************************************************************************
        // the servo control for throtle in forward ............. ie rotating  CW Blue 7 White 6
        //***********************************************************************************
        if (counter >= ForwardGearStop)
        {
            // next 3 lines one last chance to get that stepper to the desired gear
            // ForwardReverseStepper.moveTo(currentStepperPosision);
            // while (ForwardReverseStepper.currentPosition() != currentStepperPosision)
            //   ForwardReverseStepper.run();

            //digitalWrite(stepperEnable, HIGH);// disable stepper high disables we
            //are soon to throtle up in forward
            throttleServo.attach(servoPin);  // enable throttle servo attaches the servo on pin servoPin
            //exmap(counter, fromLow, fromHigh, toLow, toHigh)
            A = map(counter, 0, 500, 0, 3000);  // should amplify the throttle posision a higher
                                                //"to high"moves throtle faster
            B = A - 1;                          // I thought this was coing to b = a minus
                                                //reverse gear stop so throttle 0 would be counter zero
                                                // next linelimits range of  values to between Idle rpm and full throtle
            B = constrain(B, LowhServoPosision, highServoPosision);
            currentServoPosision = B;                               // a declaration
            throttleServo.writeMicroseconds(currentServoPosision);  // moves the servo position according to the scaled
        }
        //**************************************************************************************
        // Servo control for throtle in reverse...................... Encoder is CCW Blue 7 White 6
        // ****************************************** ******************************************
        if (counter <= ReverseGearStop)
        {
            // next 3 lines one last chance to get that stepper to the desired gear
            //ForwardReverseStepper.moveTo(currentStepperPosision);
            //  while (ForwardReverseStepper.currentPosition() != currentStepperPosision)
            //    ForwardReverseStepper.run();
            //  digitalWrite(stepperEnable, HIGH); //disable stepper high disables we
            //are soon to throtle up in reverse
            throttleServo.attach(servoPin);  // enable throttle servo attaches the servo on pin servoPin
            A = map(counter, 0, 500, 0, -3000);
            B = A + 1;  // I thought this was going to b equal to a plus
                        //reverse gear stop so throttle 0 would be counter zero seems not matter
            // next linelimits range of  values to between Idle rpm and full throtle
            B = constrain(B, LowhServoPosision, highServoPosision);
            currentServoPosision = B;
            throttleServo.writeMicroseconds(currentServoPosision);
        }
        //**************************************************************************
        // (Stepper) control between  reverse and Forward including nutral
        // **********************************************************************
        if ((counter < ForwardGearStop) && (counter > ReverseGearStop) && (counter > -44) && (counter < 44))
        {
            digitalWrite(stepperEnable, LOW);                       // low enables
            throttleServo.writeMicroseconds(currentServoPosision);  //one last chance to get that
                                                                    ///hrotle servo to the Idle posision
            throttleServo.detach();                                 // disable servo
            //   exmap(counter, fromLow, fromHigh, toLow, toHigh)
            C = map(counter, 0, -10, 5, -150);                           //stepper should respond faster as tolow and to high
                                                                         // get farther appart
                                                                         //  next linelimits range of  values to between reverse and Nutral
            C = constrain(C, LowhstepperPosision, highStepperPosision);  //
            currentStepperPosision = C;
            ForwardReverseStepper.moveTo(currentStepperPosision);
            //  detachInterrupt(digitalPinToInterrupt(2));
            while (ForwardReverseStepper.currentPosition() != currentStepperPosision)
                ForwardReverseStepper.run();
            // attachInterrupt(digitalPinToInterrupt(2), nutralDetect, RISING);//
        }

        lastStateA = currentStateA;
    }
}

void nutralDetect()
{
    ForwardReverseStepper.stop();
    counter = 0;
}
void checkPosition()
{
    encoder->tick();  // just call tick() to check the state.
}
1 Like

You never create an instance so this code will not work. If you look at the library examples, you need to create an instance based on how the pins behave. This should be part of setup().

  // setup the rotary encoder functionality

  // use FOUR3 mode when PIN_IN1, PIN_IN2 signals are always HIGH in latch position.
  // encoder = new RotaryEncoder(PIN_IN1, PIN_IN2, RotaryEncoder::LatchMode::FOUR3);

  // use FOUR0 mode when PIN_IN1, PIN_IN2 signals are always LOW in latch position.
  // encoder = new RotaryEncoder(PIN_IN1, PIN_IN2, RotaryEncoder::LatchMode::FOUR0);

  // use TWO03 mode when PIN_IN1, PIN_IN2 signals are both LOW or HIGH in latch position.
  encoder = new RotaryEncoder(PIN_IN1, PIN_IN2, RotaryEncoder::LatchMode::TWO03);

This does not make sense. A stepper motor will take a precise number of steps and stop. There is not uncertainty. Are you talking about the Servo position instead?

try and imagine a CNC lathe or something similar cutting threads onto a bolt its cutter is controlled by a stepper motor, yet it still has a homing switch to improve accuracy. since my stepper motor is controlling the shifter on a gasoline engine and the shifters clutch dog is indexed to mesh at 20 degree intervals every other 20 degrees of rotation . and i did not feel like calculating the crank shaft position to within 1 half of 20 degrees based on ignition timing of top dead center. So therefor I have decided the next best curse of action is to make my steeper motor mechanism have a homing switch that knows where is once in a while and gives feed back to the progrm.

Its compiling but I still have work to do. The stepper wasn't moving so I temporarily added a Serial output just to see what the encoder count was at, and I discovered it's not advancing at all like the example is. I'm now commenting out lines of code here and there to try and find out what specific thing is causing it to not work like the example code. thanks for your help in discovering why it wouldn't compile. I didn't even know what that line did before I forgot to put it in there.

ts compiling but I still have work to do. The stepper wasn't moving so I temporarily added a Serial output just to see what the encoder count was at, and I discovered it's not advancing at all like the example is. I'm now commenting out lines of code here and there to try and find out what specific thing is causing it to not work like the example code. thanks for your help in discovering why it wouldn't compile. I didn't even know what that line did before I forgot to put it in there.