Endless loop problem

This is really a strange one, yesterday this section of code was working but now it goes into an endless loop.

I have 3 KY-040 Rotary Encoders setting Encoder#1 runSpeed1000, Encoder#2 runSpeed100 and Encoder#3 runSpeed10.

Encoder#1 runSpeed1000 and Encoder#3 runSpeed100 go into an endless loop.

Encoder#1 runSpeed10 does not go into an endless loop, it behaves correctly.

Output from one turn of #1 Encoder run1000:
Encoder RotPosition1: 1

1000

clockwise1

Encoder RotPosition1: 2

2000

clockwise1

Encoder RotPosition1: 3

3000

clockwise1

Encoder RotPosition1: 4

4000

clockwise1

Encoder RotPosition1: 5

5000

This is an endless loop it should only increment once!

/* 
Author: Ralph Hulslander a non programmer rhulslander@gmail.com 

Contributing Author: Danny van den Brande, Arduinosensors.nl using the KY-040 Rotary encoder. 
Encoder 1 
 */

 #include <AccelStepper.h>

// Motor Connections (constant current, step/direction bipolar motor driver)
const int dirPin = 4;
const int stepPin = 5;

  AccelStepper myStepper(AccelStepper::DRIVER, stepPin, dirPin); 

 int runSpeed1000 = 0;
 int runSpeed100  = 0;
 int runSpeed10   = 0;
 int runSpeed     = 0;

 int CLK1 = 2;  // Pin 9 to clk on encoder
 int DT1  = 8;  // Pin 8 to DT on encoder
 int RotPosition1 = 0; 
 int rotation1;  
 int value1;
 
 int CLK2 = 3;  // Pin 9 to clk on encoder
 int DT2 = 11;  // Pin 8 to DT on encoder
 int RotPosition2 = 0; 
 int rotation2;  
 int value2;
 
 int CLK3 = 21;  // Pin 9 to clk on encoder
 int DT3 = 12;  // Pin 8 to DT on encoder
 int RotPosition3 = 0; 
 int rotation3;  
 int value3;
  
 boolean LeftRight1;
 boolean LeftRight2;
 boolean LeftRight3;
 
 void setup() {

   myStepper.setMaxSpeed(10000);
   myStepper.setSpeed(50);

   Serial.begin (9600);
   
   pinMode (CLK1,INPUT);
   pinMode (DT1,INPUT);
   rotation1 = digitalRead(CLK1); 
   
   pinMode (CLK2,INPUT);
   pinMode (DT2,INPUT);
   rotation2 = digitalRead(CLK2); 
   
   pinMode (CLK3,INPUT);
   pinMode (DT3,INPUT);
   rotation3 = digitalRead(CLK3);  
 } 
 void loop()
 //------------------------------------------- Start runSpeed1000 Encoder1 
 { 
value1 = digitalRead(CLK1);
     if (value1 != rotation1)
     { 
     	// we use the DT pin to find out which way we turning.
     	if (digitalRead(DT1) != value1) 
     		{  // Clockwise
       		RotPosition1 ++;
       		LeftRight1 = true;
       		runSpeed1000 = runSpeed1000 + 1000;
      	} 
      		else 
      			{ //Counterclockwise
       				LeftRight1 = false;
       				RotPosition1--;
       				runSpeed1000 = runSpeed1000 - 1000;
       			}
		        	if (runSpeed1000 <= 0)
          			{
            			runSpeed1000 = 0;
          			}     				
     			if (LeftRight1)
     				{ 
       				Serial.println ("clockwise1");
 		       		//digitalWrite("runSpeed1000",(runSpeed1000));
       		 		//Serial.println(runSpeed1000);
     				}
     					else
     						{         
       						Serial.println("counterclockwise1");
    						}
    		//this will print in the serial monitor.
     			Serial.print("Encoder RotPosition1: ");
     			Serial.println(RotPosition1);
     			Serial.println(runSpeed1000);
    } 
//------------------------------------  Stop Encoder1
//------------------------------------  Start runSpeed100 Encoder2
  value2 = digitalRead(CLK2);
     if (value2 != rotation2)
     { 
     	// we use the DT pin to find out which way we turning.
     	if (digitalRead(DT2) != value2) 
     		{  // Clockwise
       		RotPosition2 ++;
       		LeftRight2 = true;
       		runSpeed100 = runSpeed100 + 100;
      	} 
      		else 
      			{ //Counterclockwise
       				LeftRight2 = false;
       				RotPosition2--;
       				runSpeed100 = runSpeed100 - 100;
       			}
		        	if (runSpeed100 <= 0)
          			{
            			runSpeed100 = 0;
          			}
          		if (runSpeed100 >= 900)
          			{
          				runSpeed100 = 900;   // This Stops the program from decrementing
          			}     				
     			if (LeftRight2)
     				{ 
       				Serial.println ("clockwise2");
     				}
     					else
     						{         
       						Serial.println("counterclockwise2");
    						}
    		//this will print in the serial monitor.
     			Serial.print("Encoder RotPosition2: ");
     			Serial.println(RotPosition2);
     			Serial.println(runSpeed100);
    }
//------------------------------------  End   runSpeed100 Encoder2
//------------------------------------  Start runSpeed10  Encoder3
    value3 = digitalRead(CLK3);
     if (value3 != rotation3)
     { 
     	// we use the DT pin to find out which way we turning.
     	if (digitalRead(DT3) != value3) 
     		{  // Clockwise
       		RotPosition3 ++;
       		LeftRight3 = true;
       		runSpeed10 = runSpeed10 + 10;
      	} 
      		else 
      			{ //Counterclockwise
       				LeftRight3 = false;
       				RotPosition3--;
       				runSpeed10 = runSpeed10 - 10;
       			}
		        	if (runSpeed10 <= 0)
          			{
            			runSpeed10 = 0;
          			}
          		if (runSpeed10 >= 90)
          			{
          				runSpeed10 = 90;   
          			}     				
     			if (LeftRight3)
     				{ 
       				Serial.println ("clockwise3");
     				}
     					else
     						{         
       						Serial.println("counterclockwise3");
    						}
    		//this will print in the serial monitor.
     			Serial.print("Encoder RotPosition3: ");
     			Serial.println(RotPosition3);
     			Serial.println(runSpeed10);
//------------------------------------  End   runSpeed10 Encoder3  
   rotation1 = value1;
   rotation2 = value2;
   rotation3 = value3;

   runSpeed = runSpeed1000 + runSpeed100 + runSpeed10;
   
   myStepper.setSpeed(runSpeed);
   myStepper.runSpeed();
   Serial.print(runSpeed);
  }
}

Damm,

Encoder#1 runspeed1000 and Encoder#2 runSpeed100 go into endless loops.

Use the encoder library - will make your life easier :slight_smile:

Otherwise indent the code properly and see if the {} are where they need to be

( ➜ in the IDE, that’s done by pressing ctrlT on a PC or cmdT on a Mac)

1 Like

Thanks for the reply, I really do not like the look after ctrlT.
All of the {} appear correct.

Each section of the code "should" be the same with the variables changed.
Ralph

Can you post the indented code ?

I read on my iPhone and can’t tell if it’s ok

You will get more and faster answers if you follow the world-wide common indention-habits that were created by pressing ctrl-T. If your code gets indented more than two lines this can be adapted.
Anyway you should post your complete code from the very first line to the very last line.
It might be that you are missing a parenthesis or a curly brace
if other shall check this for you it is must to post your complete code

runSpeed1000 an runSpeed100 cause endless loop.

/* 
Author: Ralph Hulslander a non programmer rhulslander@gmail.com 

Contributing Author: Danny van den Brande, Arduinosensors.nl using the KY-040 Rotary encoder. 
Encoder 1 
 */

#include <AccelStepper.h>

// Motor Connections (constant current, step/direction bipolar motor driver)
const int dirPin = 4;
const int stepPin = 5;

AccelStepper myStepper(AccelStepper::DRIVER, stepPin, dirPin);

int runSpeed1000 = 0;
int runSpeed100 = 0;
int runSpeed10 = 0;
int runSpeed = 0;

int CLK1 = 2;  // Pin 2 to clk on encoder
int DT1 = 8;   // Pin 8 to DT on encoder
int RotPosition1 = 0;
int rotation1;
int value1;

int CLK2 = 3;  // Pin 3 to clk on encoder
int DT2 = 11;  // Pin 11 to DT on encoder
int RotPosition2 = 0;
int rotation2;
int value2;

int CLK3 = 21;  // Pin 21 to clk on encoder
int DT3 = 12;   // Pin 12 to DT on encoder
int RotPosition3 = 0;
int rotation3;
int value3;

boolean LeftRight1;
boolean LeftRight2;
boolean LeftRight3;

void setup() {

  myStepper.setMaxSpeed(10000);
  myStepper.setSpeed(50);

  Serial.begin(9600);

  pinMode(CLK1, INPUT);
  pinMode(DT1, INPUT);
  rotation1 = digitalRead(CLK1);

  pinMode(CLK2, INPUT);
  pinMode(DT2, INPUT);
  rotation2 = digitalRead(CLK2);

  pinMode(CLK3, INPUT);
  pinMode(DT3, INPUT);
  rotation3 = digitalRead(CLK3);
}
void loop()
//------------------------------------------- Start runSpeed1000 Encoder1
{
  value1 = digitalRead(CLK1);
  if (value1 != rotation1) {
    // we use the DT pin to find out which way we turning.
    if (digitalRead(DT1) != value1) {  // Clockwise
      RotPosition1++;
      LeftRight1 = true;
      runSpeed1000 = runSpeed1000 + 1000;
    } else {  //Counterclockwise
      LeftRight1 = false;
      RotPosition1--;
      runSpeed1000 = runSpeed1000 - 1000;
    }
    if (runSpeed1000 <= 0) {
      runSpeed1000 = 0;
    }
    if (LeftRight1) {
      Serial.println("clockwise1");
      
    } else {
      Serial.println("counterclockwise1");
    }
    //this will print in the serial monitor.
    Serial.print("Encoder RotPosition1: ");
    Serial.println(RotPosition1);
    Serial.println(runSpeed1000);
  }
  //------------------------------------  Stop Encoder1
  //------------------------------------  Start runSpeed100 Encoder2
  value2 = digitalRead(CLK2);
  if (value2 != rotation2) {
    // we use the DT pin to find out which way we turning.
    if (digitalRead(DT2) != value2) {  // Clockwise
      RotPosition2++;
      LeftRight2 = true;
      runSpeed100 = runSpeed100 + 100;
    } else {  //Counterclockwise
      LeftRight2 = false;
      RotPosition2--;
      runSpeed100 = runSpeed100 - 100;
    }
    if (runSpeed100 <= 0) {
      runSpeed100 = 0;
    }
    if (runSpeed100 >= 900) {
      runSpeed100 = 900;  // This Stops the program from decrementing
    }
    if (LeftRight2) {
      Serial.println("clockwise2");
    } else {
      Serial.println("counterclockwise2");
    }
    //this will print in the serial monitor.
    Serial.print("Encoder RotPosition2: ");
    Serial.println(RotPosition2);
    Serial.println(runSpeed100);
  }
  //------------------------------------  End   runSpeed100 Encoder2
  //------------------------------------  Start runSpeed10  Encoder3
  value3 = digitalRead(CLK3);
  if (value3 != rotation3) {
    // we use the DT pin to find out which way we turning.
    if (digitalRead(DT3) != value3) {  // Clockwise
      RotPosition3++;
      LeftRight3 = true;
      runSpeed10 = runSpeed10 + 10;
    } else {  //Counterclockwise
      LeftRight3 = false;
      RotPosition3--;
      runSpeed10 = runSpeed10 - 10;
    }
    if (runSpeed10 <= 0) {
      runSpeed10 = 0;
    }
    if (runSpeed10 >= 90) {
      runSpeed10 = 90;
    }
    if (LeftRight3) {
      Serial.println("clockwise3");
    } else {
      Serial.println("counterclockwise3");
    }
    //this will print in the serial monitor.
    Serial.print("Encoder RotPosition3: ");
    Serial.println(RotPosition3);
    Serial.println(runSpeed10);
    //------------------------------------  End   runSpeed10 Encoder3
    rotation1 = value1;
    rotation2 = value2;
    rotation3 = value3;

    runSpeed = runSpeed1000 + runSpeed100 + runSpeed10;

    myStepper.setSpeed(runSpeed);
    myStepper.runSpeed();
    Serial.print(runSpeed);
  }
}

Stefan, I posted complete code.

See. With the blocks lined up it was quick and easy for me to see the problem. The other way I would never have noticed it because it wasn't clear what part was nested inside what part without me having to count braces by hand.

This part of the code is inside the runSpeed10 bit. It's inside an if statement that only runs if (value3 != rotation3)

But that's where the values of rotation1, and rotation2 get updated. So if rotation3 is equal to value3, rotation1 and rotation2 never get updated and those sections continue to run over and over.

You should move each of those lines into the section they belong in so that rotation1 is updated in the section that checks against rotation1 and rotation2 gets updated in the section that checks against rotation2.

Thanks Delta_G!
I do not understand what you are saying but I modified the code.
TaDa it works.

But only Encoder#3 shows the correct desired runSpeed.

clockwise1

Encoder RotPosition1: 1

1000

clockwise2

Encoder RotPosition2: 1

100

clockwise3

Encoder RotPosition3: 1

10

1110

/* 
Author: Ralph Hulslander a non programmer rhulslander@gmail.com 

Contributing Author: Danny van den Brande, Arduinosensors.nl using the KY-040 Rotary encoder. 
Encoder 1 
 */

#include <AccelStepper.h>

// Motor Connections (constant current, step/direction bipolar motor driver)
const int dirPin = 4;
const int stepPin = 5;

AccelStepper myStepper(AccelStepper::DRIVER, stepPin, dirPin);

int runSpeed1000 = 0;
int runSpeed100 = 0;
int runSpeed10 = 0;
int runSpeed = 0;

int CLK1 = 2;  // Pin 2 to clk on encoder
int DT1 = 8;   // Pin 8 to DT on encoder
int RotPosition1 = 0;
int rotation1;
int value1;

int CLK2 = 3;  // Pin 3 to clk on encoder
int DT2 = 11;  // Pin 11 to DT on encoder
int RotPosition2 = 0;
int rotation2;
int value2;

int CLK3 = 21;  // Pin 21 to clk on encoder
int DT3 = 12;   // Pin 12 to DT on encoder
int RotPosition3 = 0;
int rotation3;
int value3;

boolean LeftRight1;
boolean LeftRight2;
boolean LeftRight3;

void setup() {

  myStepper.setMaxSpeed(10000);
  myStepper.setSpeed(50);

  Serial.begin(9600);

  pinMode(CLK1, INPUT);
  pinMode(DT1, INPUT);
  rotation1 = digitalRead(CLK1);

  pinMode(CLK2, INPUT);
  pinMode(DT2, INPUT);
  rotation2 = digitalRead(CLK2);

  pinMode(CLK3, INPUT);
  pinMode(DT3, INPUT);
  rotation3 = digitalRead(CLK3);
}
void loop()
//------------------------------------------- Start runSpeed1000 Encoder1
{
  value1 = digitalRead(CLK1);
  if (value1 != rotation1) {
    // we use the DT pin to find out which way we turning.
    if (digitalRead(DT1) != value1) {  // Clockwise
      RotPosition1++;
      LeftRight1 = true;
      runSpeed1000 = runSpeed1000 + 1000;
    } else {  //Counterclockwise
      LeftRight1 = false;
      RotPosition1--;
      runSpeed1000 = runSpeed1000 - 1000;
    }
    if (runSpeed1000 <= 0) {
      runSpeed1000 = 0;
    }
    if (LeftRight1) {
      Serial.println("clockwise1");
      
    } else {
      Serial.println("counterclockwise1");
    }
    //this will print in the serial monitor.
    Serial.print("Encoder RotPosition1: ");
    Serial.println(RotPosition1);
    Serial.println(runSpeed1000);
    rotation1 = value1;
    rotation2 = value2;
    rotation3 = value3;
  }
  //------------------------------------  Stop Encoder1
  //------------------------------------  Start runSpeed100 Encoder2
  value2 = digitalRead(CLK2);
  if (value2 != rotation2) {
    // we use the DT pin to find out which way we turning.
    if (digitalRead(DT2) != value2) {  // Clockwise
      RotPosition2++;
      LeftRight2 = true;
      runSpeed100 = runSpeed100 + 100;
    } else {  //Counterclockwise
      LeftRight2 = false;
      RotPosition2--;
      runSpeed100 = runSpeed100 - 100;
    }
    if (runSpeed100 <= 0) {
      runSpeed100 = 0;
    }
    if (runSpeed100 >= 900) {
      runSpeed100 = 900;  // This Stops the program from decrementing
    }
    if (LeftRight2) {
      Serial.println("clockwise2");
    } else {
      Serial.println("counterclockwise2");
    }
    //this will print in the serial monitor.
    Serial.print("Encoder RotPosition2: ");
    Serial.println(RotPosition2);
    Serial.println(runSpeed100);
    rotation1 = value1;
    rotation2 = value2;
    rotation3 = value3;
  }
  //------------------------------------  End   runSpeed100 Encoder2
  //------------------------------------  Start runSpeed10  Encoder3
  value3 = digitalRead(CLK3);
  if (value3 != rotation3) {
    // we use the DT pin to find out which way we turning.
    if (digitalRead(DT3) != value3) {  // Clockwise
      RotPosition3++;
      LeftRight3 = true;
      runSpeed10 = runSpeed10 + 10;
    } else {  //Counterclockwise
      LeftRight3 = false;
      RotPosition3--;
      runSpeed10 = runSpeed10 - 10;
    }
    if (runSpeed10 <= 0) {
      runSpeed10 = 0;
    }
    if (runSpeed10 >= 90) {
      runSpeed10 = 90;
    }
    if (LeftRight3) {
      Serial.println("clockwise3");
    } else {
      Serial.println("counterclockwise3");
    }
    //this will print in the serial monitor.
    Serial.print("Encoder RotPosition3: ");
    Serial.println(RotPosition3);
    Serial.println(runSpeed10);
    //------------------------------------  End   runSpeed10 Encoder3
    rotation1 = value1;
    rotation2 = value2;
    rotation3 = value3;

    runSpeed = runSpeed1000 + runSpeed100 + runSpeed10;

    myStepper.setSpeed(runSpeed);
    myStepper.runSpeed();
    Serial.print(runSpeed);
  }
}

Only Encoder#3 has this code

    runSpeed = runSpeed1000 + runSpeed100 + runSpeed10;

    myStepper.setSpeed(runSpeed);
    myStepper.runSpeed();
    Serial.print(runSpeed);

Also, question: are your encoders operating consistently and correctly? The code doesn't work well with the encoders I have available. Just say yes and I'll be quiet. :expressionless:

a7

Yes alto777, the encoders are operating consistently.

Yes the position of the brace closing the Encoder#3 section was in the wrong place.

	}				// move here
    runSpeed = runSpeed1000 + runSpeed100 + runSpeed10;
	 // move here  Not here
    myStepper.setSpeed(runSpeed);
    myStepper.runSpeed();
    Serial.print(runSpeed);
    // move this brace up to end if 
}

I moved the brace from line 166 to line 160.
This almost works. I am seeing the runSpeed but again in a endless loop.
2000

23502350235023502350235023502350235023502350235023502350235023502350235023502350235023502350235023502350235023502350235023502350235023502350235023502350235023502350235023502350235023502350235023502350235023502350235023502350235023502350235023502350235023502350235023502350235023502350235023502350235023502350235023502350235023502350235023502350235023502350235023502350235023502350235023502350235023502350235023502350235023502350235023502350235023502350235023502350235023502350235023502350235023502350235023502350235023502350235023502350235023502350235023502350235023502350235023502350235023502350235023502350235023502350235023502350235023502350235023502350235023502350235023502350235023502350235023502350235023502350235023502350235023502350235023502350counterclockwise1

Encoder RotPosition1: 1

1000

1350135013501350135013501350135013501350135013501350135013501350135013501350135013501350135013501350135013501350135013501350135013501350135013501350135013501350135013501350135013501350135013501350135013501350135013501350135013501350135013501350135013501350135013501350135013501350135013501350135013501350135013501350135013501350135013501350135013501350135013501350135013501350135013501350135013501350135013501350135013501350135013501350135013501350135013501350135013501350135013501350135013501350135013501350135013501350135013501350135013501350135013501350135013501350135013501350135013501350135013501350135013501350135013501350135013501350135013501350135013501350135013501350135013501350135013501350135013501350135013501350135013501350135013501350135013501350135013501350135013501350135013501350135013501350135013501350135013501350135013501350135013501350135013501350135013501350135013501350135013501350135013501350135013501350135013501350135013501350135013501350135013501350135013501350135013501350135013501350135013501350135013501350135013501350135013501350135013501350135013501350135013501350135013501350135013501350135013501350135013501350135013501350135013501350135013501350135013501350135013501350135013501350135013501350135013501350counterclockwise1

Encoder RotPosition1: 0





Read the code. Put your finger on it. I can't, just now in transit, but it sounds and looks like you now print every time through the loop.

Triplicate the printing - put it in each encoder block.

a7

dear @Ralphpdq

You should make a fundamental decision between
way A
and
way B

way A is:
staying on a pretty low level of understanding how writing C++-Code works and then depending on the grace of other users to modify your code again and again and again

way B:
taking some hours time to really learn the fundamentals and then beeing able to at least understand and modify your code yourself if something like

Life will become much easier if you use a library for the encoders and a different library for the stepper-motor

Here is a code-version that uses a encoder-library which uses a state-table. This has the advantage of automatic debouncing and really reliable up/down-counting

I have put the code that is polling the three encoder-states into a timer-interrupt.

This code-version uses the mobaTools for the stepper-motor.
This has the advantage that the step-pulses are created in the background which enables to execute code in parallel to the step-pulse-creation.

The code compiles but I don't have your hardware on the table. This means there can still be bugs in this code-version

/* Demo-Code that uses the Rotary-library from GitHub-User https://github.com/buxtronix
 * using his library https://github.com/buxtronix/arduino/tree/master/libraries/Rotary  
 * in combination with a timer-interrupt executed 10000 times per second
 * Copyright 2023 StefanL38. Licenced under the GNU GPL Version 3.
 * A T T E N T I O N ! 
 * this demo-code uses Timer2 which is used by other libraries too. 
 * This means using this code can interfere with other libraries
 * causing malfunction of both
 * 
 * As timer-interrupts are very hardware-sepcific
 * this demo-code works with Arduino-Uno R3 based on the chip AtMega328P
 * if you want to use it on other microcontrollers you will have to
 * modify setting up the timer-interrupt according to the hardware
 * of this other microcontroller
 * 
 * The demo-code simply prints the value of variable myCounter 
 * each time the value of the variable changes
 */
#include <Rotary.h>
#include <MobaTools.h>

const byte dirPin = 4;
const byte stepPin = 5;
const int  stepsPerRev = 200;

MoToStepper myStepper( stepsPerRev, STEPDIR );  // create a stepper instance

const byte CLK1 = 2;
const byte DT1  = 8;

const byte CLK2 = 3;
const byte DT2  = 11;

const byte CLK3 = 21;
const byte DT3  = 12;

Rotary rotary1 = Rotary(CLK1, DT1);
Rotary rotary2 = Rotary(CLK2, DT2);
Rotary rotary3 = Rotary(CLK3, DT3);

unsigned long myISR_TimerFrequency = 1000;
// Cnt1000, Cnt100, Cnt10 that will be incremented or decremented by rotation.
// as these variables are changed in an interrupt-service-routine
// this variable MUST !! be declared volatile to make sure 
// that it works properly !

volatile unsigned char Cnt1000 = 0;
volatile unsigned char Cnt100  = 0;
volatile unsigned char Cnt10   = 0;

long runSpeed = 0;
long last_runSpeed = 0;


void setupTimerInterrupt(unsigned long ISR_call_frequency) {
  long OCR2A_value;

  const byte Prescaler___8 = (1 << CS21);
  const byte Prescaler__32 = (1 << CS21) + (1 << CS20);
  const byte Prescaler__64 = (1 << CS22);
  const byte Prescaler_128 = (1 << CS22) + (1 << CS20);
  const byte Prescaler_256 = (1 << CS22) + (1 << CS21);
  const byte Prescaler1024 = (1 << CS22) + (1 << CS21) + (1 << CS20);

  const unsigned long CPU_Clock = 16000000;

  cli();//stop interrupts

  TCCR2A = 0;// set entire TCCR2A register to 0
  TCCR2B = 0;// same for TCCR2B
  TCNT2  = 0;//initialize counter value to 0

  TCCR2A |= (1 << WGM21); // turn on CTC mode
  TIMSK2 |= (1 << OCIE2A); // enable timer compare interrupt

  TCCR2B = Prescaler__32; 
  // OCR2A_value must be smaller than 256
  // use a different prescaler if OCR2A_value is > 256
  OCR2A_value = (CPU_Clock / ( 32 * ISR_call_frequency) )  - 1;

  OCR2A = OCR2A_value; // set the value of OCR2A

  sei();//allow interrupts
}


// timer-interrupt-service-function for AtMega328P
ISR(TIMER2_COMPA_vect) {
  processEncoders();
}


// counts up/down with each encoder-click
void processEncoders() {
  unsigned char result;
  
  result = rotary1.process();
  if (result == DIR_CW) {
    Cnt1000++;
  }
  else if (result == DIR_CCW) {
    Cnt1000--;
  }
  if (Cnt1000 < 0) {
    Cnt1000 = 0;
  }
  
  result = rotary2.process();
  if (result == DIR_CW) {
    Cnt100++;
  }
  else if (result == DIR_CCW) {
    Cnt100--;
  }
  if (Cnt100 < 0) {
    Cnt100 = 0;
  }
  
  result = rotary3.process();
  if (result == DIR_CW) {
    Cnt10++;
  }
  else if (result == DIR_CCW) {
    Cnt10--;
  }
  if (Cnt10 < 0) {
    Cnt10 = 0;
  }
}


void PrintFileNameDateTime() {
  Serial.println( F("Code running comes from file ") );
  Serial.println( F(__FILE__) );
  Serial.print( F("  compiled ") );
  Serial.print( F(__DATE__) );
  Serial.print( F(" ") );
  Serial.println( F(__TIME__) );
}


// easy to use helper-function for non-blocking timing
boolean TimePeriodIsOver (unsigned long &startOfPeriod, unsigned long TimePeriod) {
  unsigned long currentMillis  = millis();
  if ( currentMillis - startOfPeriod >= TimePeriod ) {
    // more time than TimePeriod has elapsed since last time if-condition was true
    startOfPeriod = currentMillis; // a new period starts right here so set new starttime
    return true;
  }
  else return false;            // actual TimePeriod is NOT yet over
}

unsigned long MyTestTimer = 0;  // Timer-variables MUST be of type unsigned long
const byte    OnBoard_LED = 13;


void BlinkHeartBeatLED(int IO_Pin, int BlinkPeriod) {
  static unsigned long MyBlinkTimer;
  pinMode(IO_Pin, OUTPUT);

  if ( TimePeriodIsOver(MyBlinkTimer, BlinkPeriod) ) {
    digitalWrite(IO_Pin, !digitalRead(IO_Pin) );
  }
}


void setup() {
  Serial.begin(115200);
  Serial.println("Setup-Start");
  PrintFileNameDateTime();
  setupTimerInterrupt(myISR_TimerFrequency);
  
  myStepper.attach( stepPin, dirPin );
  myStepper.setMaxSpeed(1000 * 10);
  myStepper.setSpeed(50 * 10);
  myStepper.setRampLen(0);
  myStepper.rotate(1); // other rotation-direction myStepper.rotate(-1);
}


void loop() {

  BlinkHeartBeatLED(OnBoard_LED, 250);

  runSpeed = Cnt1000 * 1000 + Cnt100 * 100 + Cnt10 * 10;

  // check if value has changed
  if (last_runSpeed != runSpeed) {
    // only if value REALLY HAS changed
    myStepper.setSpeed(runSpeed);
    last_runSpeed = runSpeed; // update last_runSpeed
    Serial.print("runSpeed=");
    Serial.println(runSpeed);
  }
}

best regards Stefan

See - indentation was a good thing…

just to give you an idea of the complexity of the code (without the motors) using the encoder library

You can try that here:

#include <Encoder.h>                        // https://www.pjrc.com/teensy/td_libs_Encoder.html

struct ExtendedCoder {
  Encoder encoder;
  const char * name;
  long oldPosition;
  long position;
  long multiplier;

  bool changed() {
    position = encoder.read() >> 2; // 4 ticks par click on divise par 4
    if (oldPosition != position) {
      oldPosition = position;
      return true;
    }
    return false;
  }
};

ExtendedCoder extendedEncoders[] = {
  {{ 3,  2}, "encoder10",   -1, 0, 10},
  {{ 7,  6}, "encoder100",  -1, 0, 100},
  {{11, 10}, "encoder1000", -1, 0, 1000},
};

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

void loop() {
  for (auto& ec : extendedEncoders)
    if (ec.changed()) {
      Serial.print(ec.name);
      Serial.print("\t");
      Serial.println(ec.position * ec.multiplier);
    }
}

basically the loop goes through each encoder and if it has changed, display the new calculated value.

This should be a new Subject

Arduino IDE, cannot find Encoder.h.
I have the Encoder library installed I even copied the Encoder.h and Encoder.cpp to the skecth folder.

C:\Users\Ralph\Documents\Arduino\SpindleRun\SpindleRun-3\SpindleRun-4\SpindleRun-5\SpindleRun-6\SpindleRun-6.ino:16:10: 
fatal error: Rotary.h: No such file or directory
 #include <Rotary.h>
          ^~~~~~~~~~
compilation terminated.

exit status 1

Compilation error: Rotary.h: No such file or directory

Encoder installed:

this is a different library

Thanks, now how do I add a library to the newest version of Arduino?

see manual installation if it's not visible in the IDE