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
lang-cpp
CLK
andDT
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 declaredvolatile
.aLastState
does not have this flag.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.