Long ago I bought a Mitutoyo linear scale for my milling machine. Not wanting to spend $3000.00 at the time, I interfaced it to a PC but that was inconvenient so I seldom used it.
Now I have to do some precision gunsmithing and I needed a digital readout.
I found some good quadrature code by jrraines and Daniel J. Gonzalez at
Quadrature Encoders in Arduino, done right. Done right.
https://yameb.blogspot.com/2012/11/quadrature-encoders-in-arduino-done.html
and
**broken link removed** using high performance reads and writes with
digitalWriteFast.h at https://code.google.com/p/digitalwritefast/
He is reading motor position. I just don't want to ever miss a beat.
I am using an Arduino Nano and this Serial LCD for Arduino
https://www.mpja.com/Serial-2-X-16-LCD-Display-for-Arduino/productinfo/31164+MP
Read the comments on that page. The library that works with this chip set is available at this link. https://www.play-zone.ch/en/fileuploader/download/download/?d=0&file=custom/upload/File-1345667375.zip
With an external 5 volt wall wart, it fits inside an audio cassette case. You will want a momentary N.O. reset switch to reset / zero it.
This is my version of the sketch by jrraines. Quadrature input to the Arduino are on digital pins 2 & 3. The Serial LCD just needs +5v, grnd, SDA & SCL
I cheated on the X axis table travel.
Now I have to do some precision gunsmithing and I needed a digital readout.
I found some good quadrature code by jrraines and Daniel J. Gonzalez at
Quadrature Encoders in Arduino, done right. Done right.
https://yameb.blogspot.com/2012/11/quadrature-encoders-in-arduino-done.html
and
**broken link removed** using high performance reads and writes with
digitalWriteFast.h at https://code.google.com/p/digitalwritefast/
He is reading motor position. I just don't want to ever miss a beat.
I am using an Arduino Nano and this Serial LCD for Arduino
https://www.mpja.com/Serial-2-X-16-LCD-Display-for-Arduino/productinfo/31164+MP
Read the comments on that page. The library that works with this chip set is available at this link. https://www.play-zone.ch/en/fileuploader/download/download/?d=0&file=custom/upload/File-1345667375.zip
With an external 5 volt wall wart, it fits inside an audio cassette case. You will want a momentary N.O. reset switch to reset / zero it.
This is my version of the sketch by jrraines. Quadrature input to the Arduino are on digital pins 2 & 3. The Serial LCD just needs +5v, grnd, SDA & SCL
C:
/*
*Quadrature Decoder
*/
#include "Arduino.h"
#include <digitalWriteFast.h> // library for high performance reads and writes by jrraines
// see http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1267553811/0
// and http://code.google.com/p/digitalwritefast/
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,16,2); // set the LCD address to 0x27 for a 16 chars and 2 line display
//LiquidCrystal_I2C lcd(0x20,16,2); // Alternate LCD address of 0x20 if 0x27 doesn't work
//LiquidCrystal_I2C lcd(0x3F,16,2); // Alternate LCD address of 0x3F if 0x27 doesn't work
// It turns out that the regular digitalRead() calls are too slow and bring the arduino down when
// I use them in the interrupt routines while the motor runs at full speed.
// Quadrature encoders
#define InterruptA 0
#define InterruptB 1
#define PinA 2
#define PinB 3
volatile bool ASet;
volatile bool BSet;
volatile bool APrev;
volatile bool BPrev;
float Ticks = 0;
float OldTicks = 0;
void setup()
{
lcd.init(); // initialize the lcd
lcd.backlight();
Serial.begin(9600);
// Quadrature encoders
pinMode(PinA, INPUT); // sets pin A as input
pinMode(PinB, INPUT); // sets pin B as input
attachInterrupt(InterruptA, HandleInterruptA, CHANGE);
attachInterrupt(InterruptB, HandleInterruptB, CHANGE);
// So it starts with current condition
ASet = digitalReadFast(PinA);
APrev = ASet;
BSet = digitalReadFast(PinB);
BPrev = BSet;
Ticks = 0;
}
void loop()
{
// Serial.print("Encoder Ticks: ");
// Serial.print(Ticks);
// Serial.print("\n");
lcd.setCursor( 0, 0 ); //Top left
lcd.print(Ticks * 0.00019685 ,4); // To 4 decimal place 1/5080 on linear scale
lcd.print(" Inches ");
lcd.setCursor( 5, 1 ); //Second row
lcd.print(" MM ");
lcd.print(Ticks * 0.005 ,3); // To 3 decimal place 25.4/5080 on linear scale
lcd.print(" ");
OldTicks = Ticks;
}
// Interrupt service routines for the A quadrature encoder Pin
void HandleInterruptA(){
BSet = digitalReadFast(PinB);
ASet = digitalReadFast(PinA);
Ticks+=ParseEncoder();
APrev = ASet;
BPrev = BSet;
}
// Interrupt service routines for the B quadrature encoder Pin
void HandleInterruptB(){
// Test transition;
BSet = digitalReadFast(PinB);
ASet = digitalReadFast(PinA);
Ticks+=ParseEncoder();
APrev = ASet;
BPrev = BSet;
}
int ParseEncoder(){
if(APrev && BPrev){
if(!ASet && BSet) return 1;
if(ASet && !BSet) return -1;
}else if(!APrev && BPrev){
if(!ASet && !BSet) return 1;
if(ASet && BSet) return -1;
}else if(!APrev && !BPrev){
if(ASet && !BSet) return 1;
if(!ASet && BSet) return -1;
}else if(APrev && !BPrev){
if(ASet && BSet) return 1;
if(!ASet && !BSet) return -1;
}
}
I cheated on the X axis table travel.