Anda di halaman 1dari 5

# 06/05/2019 How to read encoder speed through an interrupt with an Arduino based PLC's | Industrial Shields

(http://blog.industrialshields.com/en/)

## HOW TO READ ENCODER SPEED

THROUGH AN INTERRUPT WITH AN
ARDUINO BASED PLC’S

In this post it is showed how to read the speed of an encoder with an Arduino based PLC’s.

## The requirements for this example are:

Encoder
One of our PLC’s
2 resistors of 4k7

06/05/2019 How to read encoder speed through an interrupt with an Arduino based PLC's | Industrial Shields

In this example we have used an E6B2-C OMRON encoder and an M-Duino 21 I/O’s

(https://www.industrialshields.com/es/shop/m-duino-plc-arduino-21-i-

os-analog-digital/)

## How to connect the devices?

The power supply of the E6B2-C OMRON encoder is between 5V to 24V, we used the 7V from the M-Duino to power
supply the encoder. The two resistors are connected, as a Pull-up configuration, between the two phases to the 7V
of the M-Duino. And the two phases are connected to I0.4 (phase B) and I0.5 (phase A). And  all the GND are
connected to the M-Duino GND.

Once all is connected we can proceed to programming the M-Duino. Remember that the encoder convert
revolutions to pulses.

## How to read these pulses? How to know the rotate direction?

On this example we use an external interrupt to know when the encoder is rotating. The phase A is connected to
the interrupt 0 (I0.5). The interrupt will be configured to active when it appears a rising edge on I0.5. Every rising
edge on the phase A will indicate us that the encoder is rotating (one pulse). But to know rotate direction we have
to read if value of the phase B is low or high. If the rotate direction is forward (CW; phase B = LOW) and if the rotate
direction is going backward (CCW; phase B = HIGH). Next it is showed a signal to get a better understanding of that.

Counting pulses through an external interrupt is the best option, because you get sure that you do not lose any
pulse while the microcontroller is executing other code.

06/05/2019 How to read encoder speed through an interrupt with an Arduino based PLC's | Industrial Shields

With every interrupt we add pulses (pulses++) if the encoder is rotating forward and we subtract pulses if the
encoder is rotating backward. Once we have the pulses counting on the right way we just need to know the time to
be able to convert these pulses to a speed value. To know the time while we are getting  pulses we will use two
variables, one for initial time (time0) and other to final time (timeF). Using the function micros() (also you can use
millis() function) we will set the two values to implement our equation.

The  E6B2-C OMRON encoder that is used on this example has a resolution of 500 pulses for revolution. So, our
equation will be:

## Speed = (pulses/500)   /   ( (timeF-timeO)/60000000 )   rev/min

In this example we display the speed of the encoder on serial monitor. To display it you have to introduce a “p” of
print through the serial monitor.

IMPORTANT: remember, the interrupt has to be as fast as possible, if not you can get some Aliasing!

To add more information of the functions that are used on this code take a look on the Arduino Reference: millis
millis
(https://www.arduino.cc/en/Reference/Millis)(),
(https://www.arduino.cc/en/Reference/Millis)(),  micros (https://www.arduino.cc/en/Reference/Micros)
(),  attachInterrupt (https://www.arduino.cc/en/Reference/AttachInterrupt)(),
(https://www.arduino.cc/en/Reference/AttachInterrupt)(),  detachInterrupt
(https://www.arduino.cc/en/Reference/DetachInterrupt)()
(https://www.arduino.cc/en/Reference/DetachInterrupt)()

## Next it is showed how to convert this to code on Arduino IDE:

06/05/2019 How to read encoder speed through an interrupt with an Arduino based PLC's | Industrial Shields

## const int phaseB = I0_4;

const int phaseA = I0_5;
int valuePhaseB = 0;
volatile long pulses = 0;
unsigned long timeO = 0;
unsigned long timeF = 0;
float encoderSpeed = 0;

void setup() {
Serial.begin(9600);
pinMode(phaseA, INPUT); // configure the I.0 as a INPUTS
pinMode(phaseB, INPUT);
attachInterrupt(digitalPinToInterrupt(phaseA), detectPulses, RISING); // enable ex
timeO = micros(); // Initialize initial time
}

void loop() {
if (Serial.available() && Serial.read() == 'p') {
timeF = micros(); // Geting the final time to get the speed
encoderSpeed = ((float)pulses/500.0) / ((float)(timeF - timeO) / (60000000.0));
Serial.print("Speed: ");
Serial.print(encoderSpeed); // Printing speed value
Serial.println(" rev/min");
pulses = 0; // Initialize pulses to count again
timeO = micros(); // Initialize initial time again
}
}

void detectPulses() {
if (digitalRead(phaseB) == LOW) { //Confirm if we are turning on CW direction.
}
else { //Confirm if we are turning on CCW direction.
pulses--; // Substraing pulses
}
}

encoder-with-arduino-based-plcs/),  HOW TO TOUCH UP DATA FROM THE EEPROM
(http://blog.industrialshields.com/en/how-to-touch-up-data-from-the-eeprom/),  HOW TO USE STEPPER MOTOR
WITH ARDBOX ANALOG (http://blog.industrialshields.com/en/how-to-use-stepper-motor-with-ardbox-
analog/), HOW TO CONNECT AND CONFIGURE A LOAD CELL USING HX711 TRANSMITTER WITH OUR EQUIPMENT’S
our-equipments/),  HOW TO GENERATE A DIFFERENT PWM’S SIGNALS WITH OURS EQUIPMENT’S
(http://blog.industrialshields.com/en/how-to-generate-a-di erent-pwms-signals-with-ours-equipments/),  HOW
TO USE THE WATCHDOG (http://blog.industrialshields.com/en/how-to-use-the-watchdog/),  RS-485
COMMUNICATION EXAMPLE USING OUR LIBRARIES (http://blog.industrialshields.com/en/rs-485-communication-
example-using-our-libraries/),  HOW TO CREATE A WEB SERVER TO READ A SD CARD WITH OUR PLC’S