Omron encoder with Arduino

Hi there, I'm trying to generate an Arduino code for a system consists of
1- Omron encoder 1000P/R (E6B2-CWZ6C)
2- Arduino Uno board
3- Led 5v
and I want this code to let the led on every one revolution of the encoder and the serial monitor shows the degrees of encoder rotation, number of rotations, and the status of led if on or off.
the code below gives zero and led is off always

// Define the pin connections
const int encoderPinA = 2;  // Encoder A output connected to digital pin 2
const int encoderPinB = 3;  // Encoder B output connected to digital pin 3
const int encoderPinZ = 4;  // Encoder Z output connected to digital pin 4
const int ledPin = 13;      // LED connected to digital pin 13

volatile long pulseCount = 0;    // Variable to store the number of pulses
volatile long rotationCount = 0; // Variable to store the number of rotations
const int pulsesPerRotation = 1000;  // Number of pulses per rotation

volatile bool ledState = false;  // Variable to store the LED state

void setup() {
  // Set the pin modes
  pinMode(encoderPinA, INPUT_PULLUP);
  pinMode(encoderPinB, INPUT_PULLUP);
  pinMode(encoderPinZ, INPUT_PULLUP);
  pinMode(ledPin, OUTPUT);

  // Initialize the LED state
  digitalWrite(ledPin, LOW);

  // Initialize serial communication for debugging
  Serial.begin(9600);

  // Attach interrupts to the encoder pins
  attachInterrupt(digitalPinToInterrupt(encoderPinA), countPulse, RISING);
  attachInterrupt(digitalPinToInterrupt(encoderPinZ), handleIndexPulse, RISING);
}

void loop() {
  // Disable interrupts temporarily to safely read pulseCount and rotationCount
  noInterrupts();
  long localPulseCount = pulseCount;
  long localRotationCount = rotationCount;
  bool localLedState = ledState;
  interrupts();

  // Calculate the degrees of rotation
  float degrees = (localPulseCount % pulsesPerRotation) * (360.0 / pulsesPerRotation);

  // Print the status to the serial monitor
  Serial.print("Degrees: ");
  Serial.print(degrees);
  Serial.print(", Rotations: ");
  Serial.print(localRotationCount);
  Serial.print(", LED: ");
  Serial.println(localLedState ? "ON" : "OFF");

  // Add a small delay to avoid flooding the serial monitor
  delay(500);
}

// Interrupt service routine to count pulses on channel A
void countPulse() {
  // Read the B channel to determine the direction
  if (digitalRead(encoderPinB) == LOW) {
    pulseCount++;
  } else {
    pulseCount--;
  }
}

// Interrupt service routine to handle index pulses on channel Z
void handleIndexPulse() {
  // Increment rotation count
  rotationCount++;

  // Toggle the LED state
  ledState = !ledState;

  // Flash the LED
  digitalWrite(ledPin, HIGH);
  delay(100);  // LED on for 100 milliseconds
  digitalWrite(ledPin, LOW);

  // Print a message to the serial monitor
  Serial.println("Index pulse detected");

  // Debug statement
  Serial.print("Rotation Count: ");
  Serial.println(rotationCount);
}
"

Try with the encoder library

using delay(100) in an ISR (or printing from the ISR) is not a great idea...

The Uno only has two interrupt pins, being 2 and 3.
Pin 4 cannot be used for interrupt input
So put Z on pin 3

1 Like

Hi, @mostafagemy

Can you please post a copy of your circuit, a picture of a hand drawn circuit in jpg, png?
Hand drawn and photographed is perfectly acceptable.
Please include ALL hardware, power supplies, component names and pin labels.

Your encoder.

Connections.


Tom... :smiley: :+1: :coffee: :australia:


thanks for you all, the connections are shown , and i modified the code for the next step, but still the led is not blinking at each rotation and its status in serial monitor is on for whole the rotation and off for whole the next rotation, and i want it to only blinks when single rotation is completed , i will also add camera to take a picture but not included yet.

// Define the pin connections
const int encoderPinA = 2;  // Encoder A output connected to digital pin 2
const int encoderPinB = 4;  // Encoder B output connected to digital pin 3
const int encoderPinZ = 3;  // Encoder Z output connected to digital pin 4
const int ledPin = 12;      // LED connected to digital pin 13
const int cameraPin = 7;    // Camera trigger pin connected to digital pin 7

volatile long pulseCount = 0;    // Variable to store the number of pulses
volatile long rotationCount = 0; // Variable to store the number of rotations
const int pulsesPerRotation = 1000;  // Number of pulses per rotation

volatile bool ledState = false;  // Variable to store the LED state

void setup() {
  // Set the pin modes
  pinMode(encoderPinA, INPUT_PULLUP);
  pinMode(encoderPinB, INPUT_PULLUP);
  pinMode(encoderPinZ, INPUT_PULLUP);
  pinMode(ledPin, OUTPUT);
  pinMode(cameraPin, OUTPUT);

  // Initialize the LED and Camera states
  digitalWrite(ledPin, LOW);
  digitalWrite(cameraPin, LOW);

  // Initialize serial communication for debugging
  Serial.begin(9600);

  // Attach interrupts to the encoder pins
  attachInterrupt(digitalPinToInterrupt(encoderPinA), countPulse, RISING);
  attachInterrupt(digitalPinToInterrupt(encoderPinZ), handleIndexPulse, RISING);
}

void loop() {
  // Disable interrupts temporarily to safely read pulseCount and rotationCount
  noInterrupts();
  long localPulseCount = pulseCount;
  long localRotationCount = rotationCount;
  bool localLedState = ledState;
  interrupts();

  // Calculate the degrees of rotation
  float degrees = (localPulseCount % pulsesPerRotation) * (360.0 / pulsesPerRotation);

  // Print the status to the serial monitor
  Serial.print("Degrees: ");
  Serial.print(degrees);
  Serial.print(", Rotations: ");
  Serial.print(localRotationCount);
  Serial.print(", LED: ");
  Serial.println(localLedState ? "ON" : "OFF");

  // Add a small delay to avoid flooding the serial monitor
  delay(500);
}

// Interrupt service routine to count pulses on channel A
void countPulse() {
  // Read the B channel to determine the direction
  if (digitalRead(encoderPinB) == LOW) {
    pulseCount++;
  } else {
    pulseCount--;
  }
}

// Interrupt service routine to handle index pulses on channel Z
void handleIndexPulse() {
  // Increment rotation count
  rotationCount++;

  // Flash the LED
  digitalWrite(ledPin, HIGH);
  delay(100);  // LED on for 100 milliseconds
  digitalWrite(ledPin, LOW);

  // Trigger the camera to take a picture
  digitalWrite(cameraPin, HIGH);
  delay(100);  // Camera trigger pulse duration
  digitalWrite(cameraPin, LOW);

  // Update the LED state
  ledState = !ledState;

  // Print a message to the serial monitor
  Serial.println("Index pulse detected");

  // Debug statement
  Serial.print("Rotation Count: ");
  Serial.println(rotationCount);
}

Just use the Z index, since it only happens once each rotation.

You need to implement the recommendations of post #2.

The led does not blink because delay does not work inside an interrupt.

The z axis isr needs to look something like this

void handleIndexPulse() {
  // Increment rotation count
  rotationCount++;
  newZpulse = true; //new volatile boolean variable
}

Then in loop you will have a conditional statement

if(newZpulse)
{
newZpulse = false;
//do everything you want to do if there is a new pulse
//led flashing with delay
//Serial printing
}

You still need to fix the handleIndexPulse ISR so that is does not use delays

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.