2

I have a rotary encoder (ppr = 600) and I want to write code to achieve the implementation to read current angle and direction.

Here is my code. I think it is correct but it donot have any output on the serial monitor.

#include <Servo.h>
// Rotary Encoder Connections
int encoderPinA = 2; // Connect the CLK pin of the encoder to digital pin 2
int encoderPinB = 3; // Connect the DT pin of the encoder to digital pin 3
// Variables
volatile int encoderPos = 0; // Current position of the encoder
volatile int lastEncoderPos = 0; // Previous position of the encoder
int clockwiseSteps = 0; // Total clockwise steps turned
int counterclockwiseSteps = 0; // Total counterclockwise steps turned
int latestOperation = 0; // Latest rotation operation (1 for clockwise, -1 for counterclockwise)
int degreesPerStep = 360 / 600; // Degrees per step for a 600-pulse rotary encoder
int aLastState = digitalRead(encoderPinA); // Default state of Pin A
void setup() {
 // Set encoder pins as inputs
 pinMode(encoderPinA, INPUT_PULLUP);
 pinMode(encoderPinB, INPUT_PULLUP);
 // Attach interrupts to the encoder pins
 attachInterrupt(digitalPinToInterrupt(encoderPinA), updateEncoder, CHANGE);
 attachInterrupt(digitalPinToInterrupt(encoderPinB), updateEncoder, CHANGE);
 // Initialize Serial communication
 Serial.begin(9600);
}
void loop() {
 // Print the total degrees turned in both directions
 if (encoderPos != lastEncoderPos) {
 int rotation = encoderPos - lastEncoderPos;
 if (rotation > 0) {
 clockwiseSteps += rotation;
 latestOperation = 1;
 } else {
 counterclockwiseSteps += rotation;
 latestOperation = -1;
 }
 lastEncoderPos = encoderPos;
 int currentAngle;
 if (latestOperation == 1) {
 currentAngle = (clockwiseSteps - counterclockwiseSteps) * degreesPerStep;
 Serial.print("CW | ");
 } else {
 currentAngle = (clockwiseSteps - counterclockwiseSteps) * degreesPerStep;
 Serial.print("CCW | ");
 }
 Serial.println(currentAngle);
 }
}
void updateEncoder() {
 int aState = digitalRead(encoderPinA); // Reads the "current" state of the outputA
 // If the previous and the current state of the outputA are different, that means a Pulse has occured
 if (aState != aLastState){ 
 // If the outputB state is different to the outputA state, that means the encoder is rotating clockwise
 if (digitalRead(encoderPinB) != aState) { 
 encoderPos++;
 } else {
 encoderPos--;
 }
 } 
 aLastState = aState; // Updates the previous state of the outputA with the current state
 }

Why there is no output? Seem like the interrupt function not working. How to fix it? enter image description here

enter image description here

asked Jun 29, 2023 at 6:53
12
  • Can you add the exact type of your rotary encoder (and the link to a datasheet, if you can find it)? Because your code reads a "raw" rotary encoder, but the pin names CLK and DT in your code comment suggest that the encoder rather speaks something like SPI. Also, all variables declared outside and used inside an interrupt handler should be declared volatile. aLastState does not have this flag. Commented Jun 29, 2023 at 8:13
  • 1
    We definitely need to know the part number of the rotary encoder and a link to the datasheet, or at least more information about it. Commented Jun 29, 2023 at 8:43
  • @NickGammon I update the information in the text Commented Jun 29, 2023 at 8:54
  • 1
    Since the interrupt routine only does anything if the A pin has changed, the second attachInterrupt line is not needed. You don't need an interrupt for the B pin if you aren't going to react to changes on the B pin. Commented Jun 29, 2023 at 16:01
  • 1
    int degreesPerStep = 360 / 600; This integer division resolves to 0. Use a float datatype instead of int. If this solves the problem then create an answer showing the code changes you made. Commented Jun 30, 2023 at 21:30

0

Know someone who can answer? Share a link to this question via email, Twitter, or Facebook.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.