Issues with Measuring Conveyor Belt Speed Using Quadrature Encoder and ESP32

Subject: Issues with Measuring Conveyor Belt Speed Using Quadrature Encoder and ESP32

Hello everyone,

I’m working on a project where I need to measure the speed of a conveyor belt using a quadrature encoder connected to an ESP32. I’ve implemented the code to read the encoder signals and calculate the speed in meters per minute, but I’m encountering an issue.

Even when the conveyor belt is not moving, the system is outputting a non-zero speed value. I suspect this might be due to noise or incorrect pulse counting, but I’m not sure how to address this effectively.

Here’s a brief overview of my setup:

  • Encoder Pins: Connected to GPIO14 and GPIO12 on the ESP32.
  • Encoder Specifications: Pulses per revolution = 600; Roller diameter = 0.06369 meters.
  • Code Implementation: I’ve implemented an interrupt service routine (ISR) for the encoder signals and calculate the speed every second.

CODE)-

#include <Arduino.h>

#define ENCODER_A_PIN 14  // GPIO14 for encoder A
#define ENCODER_B_PIN 12  // GPIO12 for encoder B

volatile int pulseCount = 0;
volatile bool direction = true;  // true = forward, false = backward

// Constants
const int pulsesPerRevolution = 600;  // Replace with your encoder's PPR
const float rollerDiameter = 0.06369;     // Replace with your roller's diameter in meters
const float circumference = 3.14159 * rollerDiameter;
const float distancePerPulse = circumference / pulsesPerRevolution;

const unsigned long debounceDelay = 5;  // Debounce delay in milliseconds

unsigned long lastInterruptTime = 0;

void IRAM_ATTR encoderISR() {
  unsigned long currentTime = millis();
  // Check if the interrupt is within the debounce period
  if (currentTime - lastInterruptTime > debounceDelay) {
    lastInterruptTime = currentTime;
    
    bool stateA = digitalRead(ENCODER_A_PIN);
    bool stateB = digitalRead(ENCODER_B_PIN);
    
    direction = (stateA == stateB);
    pulseCount += direction ? 1 : -1;
  }
}

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

  pinMode(ENCODER_A_PIN, INPUT);
  pinMode(ENCODER_B_PIN, INPUT);

  attachInterrupt(digitalPinToInterrupt(ENCODER_A_PIN), encoderISR, CHANGE);
  attachInterrupt(digitalPinToInterrupt(ENCODER_B_PIN), encoderISR, CHANGE);
}

void loop() {
  static unsigned long lastTime = 0;
  static int lastCount = 0;

  unsigned long currentTime = millis();
  int currentCount = pulseCount;

  if (currentTime - lastTime >= 1000) {  // Update every 1 second
    int pulses = currentCount - lastCount;
    float distance = pulses * distancePerPulse;  // Distance traveled in meters
    float speed = (distance / ((currentTime - lastTime) / 1000.0)) * 60.0;  // Speed in meters per minute

    Serial.print("Speed: ");
    Serial.print(speed);
    Serial.println(" m/min");

    lastTime = currentTime;
    lastCount = currentCount;
  }
}

this is the encoder i used-
[Rotary Quadrature Encoder 600PPR/2400CPR Rotary Quadrature Encoder 600PPR/2400CPR [RMCS-5105] - ₹1,150.00 : Robokits India, Easy to use, Versatile Robotics & DIY kits]

press "Edit this post" and place code between CODE tags

1 Like

I think noise is a good probabability. You might want to research encoders and bouncing or smoothing, ideas like that.

1 Like

your input pins acting as antenna, use this:

pinMode(ENCODER_A_PIN, INPUT_PULLUP);
pinMode(ENCODER_B_PIN, INPUT_PULLUP);
1 Like

sorry, i am new here. Thanks for the suggestion

"Open collector and NPN configuration."

The input pins should be:

  pinMode(ENCODER_A_PIN, INPUT_PULLUP);
  pinMode(ENCODER_B_PIN, INPUT_PULLUP);