Done.
Wiring:
Uses iGaging Scales on the X and Y axis, Quad Encoder on the Z axis and infrared emitter/detector for the RPM.
Code X:
/******************************************************************/
/* */
/* MillDRO - X */
/* */
/* May 10, 2015 */
/* */
/******************************************************************/
// iGaging Scale
// Red 3.3 Vcc
// White Clock -> Scale W Pin 2
// Green Data <- Scale G Pin 3
// Black Gnd
// Display 8 digit MAX7219 -a-
// VCC R 5 Vcc f b
// DIN W MOSI Pin 11 -g-
// CS Y SS Pin 10 e c
// CLK B SCK Pin 13 -d- p
// GND B Gnd pgfe dcba
// Zero switch
// COM B Gnd
// NO Y Pin 9
/******************************************************************/
#include <LedControl.h>
LedControl lc=LedControl(11,13,10,1);
/******************************************************************/
#define SCF -3.906250 // Scale factor (1/2560*10000)
#define DLY 100 // Refresh period (100 ms)
#define SCC 2 // Scale clock (Pin 2)
#define SCD 3 // Scale data (Pin 3)
#define SWZ 9 // Zero switch (Pin 9)
byte DroIni; // DRO init state
long DroCnt; // DRO raw counter
long DroOfs; // DRO offset (zero)
long DroMea; // DRO measurement (inch *10000)
float DroKft; // DRO scale factor
/******************************************************************/
void setup()
{
IniSwz(); // Init Zero switch
IniScl(); // Init Scale
IniDsp(); // Init Display
IniClc(); // Init Calc
}
void loop()
{
ThrSwz(); // Test Zero switch
ThrScl(); // Inquire Scale
ThrClc(); // Calc measure
ThrDsp(); // Display measure
delay(DLY);
}
/******************************************************************/
void IniClc(void) // Init Calc
{
DroIni=1;
DroCnt=0;
DroOfs=0;
DroMea=0;
DroKft=SCF;
}
void ThrClc(void) // Calc measure
{
if(DroIni)
{
DroIni=0;
DroOfs=DroCnt;
}
DroMea=FltLng((float)(DroCnt-DroOfs)*DroKft);
}
/******************************************************************/
void IniDsp(void) // Init Display
{
lc.shutdown(0,false); // MAX7219 out of power-saving mode
lc.setIntensity(0,8); // Mediun value for brightness
lc.clearDisplay(0); // Clear display
}
void ThrDsp(void) // Display measure
{
long v;
int i,n,m;
n=0;
v=DroMea;
if(v<0)
{
n=1;
v*=-1;
}
for(i=0;i<8;i++)
{
m=v%10;
switch(i)
{
case 0:
if(m>=5)
lc.setDigit(0,i,5,false);
else
lc.setDigit(0,i,0,false);
break;
case 1:
case 2:
case 3:
lc.setDigit(0,i,m,false);
break;
case 4:
lc.setDigit(0,i,m,true);
break;
case 5:
case 6:
case 7:
if(m)
lc.setDigit(0,i,m,false);
else
{
if(n)
{
n=0;
lc.setChar(0,i,'-',false);
}
else
lc.setChar(0,i,' ',false);
}
break;
}
v/=10;
}
}
/******************************************************************/
void IniSwz(void) // Init Zero switch
{
pinMode(SWZ,INPUT_PULLUP);
}
void ThrSwz(void) // Test Zero switch
{
if(!digitalRead(SWZ))
DroOfs=DroCnt;
}
/******************************************************************/
void IniScl(void) // Init Scale
{
digitalWrite(SCC,LOW);
pinMode(SCC,OUTPUT);
pinMode(SCD,INPUT);
}
void ThrScl(void) // Inquire Scale
{
int i;
long v;
v=0;
for(i=0;i<20;i++)
{
ClkScl();
if(BitScl())
v|=0x80000000;
v>>=1;
v&=0x7FFFFFFF;
}
v>>=11;
ClkScl();
if(BitScl())
v|=0xFFF00000;
DroCnt=v;
}
void ClkScl(void) // Clock Scale
{
digitalWrite(SCC,HIGH);
delayMicroseconds(20);
digitalWrite(SCC,LOW);
delayMicroseconds(100);
}
int BitScl(void) // Get Scale bit
{
int i;
int h,l;
h=l=0;
for(i=0;i<5;i++)
{
if(digitalRead(SCD))
h++;
else
l++;
delayMicroseconds(SCD);
}
if(h>l)
return(1);
return(0);
}
/******************************************************************/
long FltLng(float v)
{
return((v<0)?(long)(v-0.5):(long)(v+0.5));
}
Code Y:
/******************************************************************/
/* */
/* MillDRO - Y */
/* */
/* May 10, 2015 */
/* */
/******************************************************************/
// iGaging Scale
// Red 3.3 Vcc
// White Clock -> Scale W Pin 2
// Green Data <- Scale G Pin 3
// Black Gnd
// Display 8 digit MAX7219 -a-
// VCC R 5 Vcc f b
// DIN W MOSI Pin 11 -g-
// CS Y SS Pin 10 e c
// CLK B SCK Pin 13 -d- p
// GND B Gnd pgfe dcba
// Zero switch
// COM B Gnd
// NO Y Pin 9
/******************************************************************/
#include <LedControl.h>
LedControl lc=LedControl(11,13,10,1);
/******************************************************************/
#define SCF 3.906250 // Scale factor (1/2560*10000)
#define DLY 100 // Refresh period (100 ms)
#define SCC 2 // Scale clock (Pin 2)
#define SCD 3 // Scale data (Pin 3)
#define SWZ 9 // Zero switch (Pin 9)
byte DroIni; // DRO init state
long DroCnt; // DRO raw counter
long DroOfs; // DRO offset (zero)
long DroMea; // DRO measurement (inch *10000)
float DroKft; // DRO scale factor
/******************************************************************/
void setup()
{
IniSwz(); // Init Zero switch
IniScl(); // Init Scale
IniDsp(); // Init Display
IniClc(); // Init Calc
}
void loop()
{
ThrSwz(); // Test Zero switch
ThrScl(); // Inquire Scale
ThrClc(); // Calc measure
ThrDsp(); // Display measure
delay(DLY);
}
/******************************************************************/
void IniClc(void) // Init Calc
{
DroIni=1;
DroCnt=0;
DroOfs=0;
DroMea=0;
DroKft=SCF;
}
void ThrClc(void) // Calc measure
{
if(DroIni)
{
DroIni=0;
DroOfs=DroCnt;
}
DroMea=FltLng((float)(DroCnt-DroOfs)*DroKft);
}
/******************************************************************/
void IniDsp(void) // Init Display
{
lc.shutdown(0,false); // MAX7219 out of power-saving mode
lc.setIntensity(0,8); // Mediun value for brightness
lc.clearDisplay(0); // Clear display
}
void ThrDsp(void) // Display measure
{
long v;
int i,n,m;
n=0;
v=DroMea;
if(v<0)
{
n=1;
v*=-1;
}
for(i=0;i<8;i++)
{
m=v%10;
switch(i)
{
case 0:
if(m>=5)
lc.setDigit(0,i,5,false);
else
lc.setDigit(0,i,0,false);
break;
case 1:
case 2:
case 3:
lc.setDigit(0,i,m,false);
break;
case 4:
lc.setDigit(0,i,m,true);
break;
case 5:
case 6:
case 7:
if(m)
lc.setDigit(0,i,m,false);
else
{
if(n)
{
n=0;
lc.setChar(0,i,'-',false);
}
else
lc.setChar(0,i,' ',false);
}
break;
}
v/=10;
}
}
/******************************************************************/
void IniSwz(void) // Init Zero switch
{
pinMode(SWZ,INPUT_PULLUP);
}
void ThrSwz(void) // Test Zero switch
{
if(!digitalRead(SWZ))
DroOfs=DroCnt;
}
/******************************************************************/
void IniScl(void) // Init Scale
{
digitalWrite(SCC,LOW);
pinMode(SCC,OUTPUT);
pinMode(SCD,INPUT);
}
void ThrScl(void) // Inquire Scale
{
int i;
long v;
v=0;
for(i=0;i<20;i++)
{
ClkScl();
if(BitScl())
v|=0x80000000;
v>>=1;
v&=0x7FFFFFFF;
}
v>>=11;
ClkScl();
if(BitScl())
v|=0xFFF00000;
DroCnt=v;
}
void ClkScl(void) // Clock Scale
{
digitalWrite(SCC,HIGH);
delayMicroseconds(20);
digitalWrite(SCC,LOW);
delayMicroseconds(100);
}
int BitScl(void) // Get Scale bit
{
int i;
int h,l;
h=l=0;
for(i=0;i<5;i++)
{
if(digitalRead(SCD))
h++;
else
l++;
delayMicroseconds(SCD);
}
if(h>l)
return(1);
return(0);
}
/******************************************************************/
long FltLng(float v)
{
return((v<0)?(long)(v-0.5):(long)(v+0.5));
}
Code Z:
/******************************************************************/
/* */
/* MillDRO - Z */
/* */
/* May 10, 2015 */
/* */
/******************************************************************/
// Quad Encoder 600 ppr LPA3806
// Red 5 Vcc
// White Chanel A Pin 2 (Int 1)
// Green Chanel B Pin 3 (Int 2)
// Black Gnd
// Display 8 digit MAX7219 -a-
// VCC R 5 Vcc f b
// DIN W MOSI Pin 11 -g-
// CS Y SS Pin 10 e c
// CLK B SCK Pin 13 -d- p
// GND B Gnd pgfe dcba
// Zero switch
// COM B Gnd
// NO Y Pin 9
/******************************************************************/
#include <LedControl.h>
LedControl lc=LedControl(11,13,10,1);
/******************************************************************/
#define SCF 4.000000 // Encoder factor (1/((600*4)/(12*0.08))*10000)
#define DLY 100 // Refresh period (100 ms)
#define QCA 2 // Encoder Chanel A (Pin 2)
#define QCB 3 // Encoder Chanel B (Pin 3)
#define QIA 0 // Encoder Chanel A (Int 1)
#define QIB 1 // Encoder Chanel B (Int 2)
#define SWZ 9 // Zero switch (Pin 9)
long DroCnt; // DRO raw counter
long DroOfs; // DRO offset (zero)
long DroMea; // DRO measurement (inch *10000)
float DroKft; // DRO scale factor
/******************************************************************/
void setup()
{
IniSwz(); // Init Zero switch
IniEnc(); // Init Encoder
IniDsp(); // Init Display
IniClc(); // Init Calc
}
void loop()
{
ThrSwz(); // Test Zero switch
ThrClc(); // Calc measure
ThrDsp(); // Display measure
delay(DLY);
}
/******************************************************************/
void IniClc(void) // Init Calc
{
DroCnt=0;
DroOfs=0;
DroMea=0;
DroKft=SCF;
}
void ThrClc(void) // Calc measure
{
DroMea=FltLng((float)(DroCnt-DroOfs)*DroKft);
}
/******************************************************************/
void IniDsp(void) // Init Display
{
lc.shutdown(0,false); // MAX7219 out of power-saving mode
lc.setIntensity(0,8); // Mediun value for brightness
lc.clearDisplay(0); // Clear display
}
void ThrDsp(void) // Display measure
{
long v;
int i,n,m;
n=0;
v=DroMea;
if(v<0)
{
n=1;
v*=-1;
}
for(i=0;i<8;i++)
{
m=v%10;
switch(i)
{
case 0:
if(m>=5)
lc.setDigit(0,i,5,false);
else
lc.setDigit(0,i,0,false);
break;
case 1:
case 2:
case 3:
lc.setDigit(0,i,m,false);
break;
case 4:
lc.setDigit(0,i,m,true);
break;
case 5:
case 6:
case 7:
if(m)
lc.setDigit(0,i,m,false);
else
{
if(n)
{
n=0;
lc.setChar(0,i,'-',false);
}
else
lc.setChar(0,i,' ',false);
}
break;
}
v/=10;
}
}
/******************************************************************/
void IniSwz(void) // Init Zero switch
{
pinMode(SWZ,INPUT_PULLUP);
}
void ThrSwz(void) // Test Zero switch
{
if(!digitalRead(SWZ))
DroOfs=DroCnt;
}
/******************************************************************/
void IniEnc(void) // Init Encoder
{
pinMode(QCA,INPUT_PULLUP);
pinMode(QCB,INPUT_PULLUP);
attachInterrupt(QIA,QenChAInt,CHANGE);
attachInterrupt(QIB,QenChBInt,CHANGE);
}
void QenChAInt(void) // Interruption chanel A
{
if(PIND&4)
{ // Chanel A High
if(PIND&8)
DroCnt++; // Chanel B High (increase)
else
DroCnt--; // Chanel B Low (decrease)
}
else
{ // Chanel A Low
if(PIND&8)
DroCnt--; // Chanel B High (decrease)
else
DroCnt++; // Chanel B Low (increase)
}
}
void QenChBInt(void) // Interruption chanel B
{
if(PIND&8)
{ // Chanel B High
if(PIND&4)
DroCnt--; // Chanel A High (decrease)
else
DroCnt++; // Chanel A Low (increase)
}
else
{ // Chanel B Low
if(PIND&4)
DroCnt++; // Chanel A High (increase)
else
DroCnt--; // Chanel A Low (decrease)
}
}
/******************************************************************/
long FltLng(float v)
{
return((v<0)?(long)(v-0.5):(long)(v+0.5));
}
Code R:
/******************************************************************/
/* */
/* MillDRO - R */
/* */
/* May 10, 2015 */
/* */
/******************************************************************/
// IR Sensor TCRT5000
// Red 5 Vcc
// White Aout
// Green Dout Pin 3 (Int 2)
// Black Gnd
// Display 4 digit SAA1064
// 3/8 None -a-
// 5/8 None f b
// VCC R 5 Vcc -g-
// ADR B Gnd (Read Addr 0x70 / Write Addr 0x71) e c
// SDA W Pin A4 SDA -d- p
// SCL Y Pin A5 SCL
// GND B Gnd pgfe dcba
/******************************************************************/
#include <Wire.h>
#define DSP 0x38 // Display Addr (0x70>>1)
byte DspDig[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
/******************************************************************/
#define MXL 0xffffffff // Maximum timer count (us)
#define RCF 60000000 // RPM factor
#define RMX 6000 // Maximum RPM time us (debounce) 10000 RPM
#define RMN 6000000 // Minimum RPM time us (zero) 10 RPM
#define DLY 100 // Refresh period (500 ms)
#define SNS 3 // Sensor digital out (Pin 3)
#define SIT 1 // Sensor (Int 2)
unsigned long RpmTmr; // RPM timer (microseconds)
unsigned long RpmCnt; // RPM counter (microsecond)
unsigned long RpmFac; // RPM factor
int RpmMea; // RPM measurement
int RpmAvr[10]; // RPM measurement average
/******************************************************************/
void setup()
{
IniSns(); // Init Sensor
IniDsp(); // Init Display
ClrDsp(); // Clear Display
IniClc(); // Init Calc
}
void loop()
{
ThrClz(); // Test RPM
ThrClc(); // Calc RPM
ThrDsp(); // Display RPM
delay(DLY);
}
/******************************************************************/
void IniClc(void) // Init Calc
{
byte i;
RpmTmr=micros();
RpmCnt=0;
RpmMea=0;
RpmFac=RCF;
for(i=0;i<10;i++)
RpmAvr[i]=0;
}
void ThrClz(void) // Test rpm zero
{
unsigned long t,d;
t=micros();
if(t>RpmTmr)
d=t-RpmTmr;
else
d=MXL-t+RpmTmr;
if(d>RMN) // Test RPM counter zero
RpmCnt=0;
}
void ThrClc(void) // Calc rpm measure
{
byte i,j;
int r,p,s;
if(RpmCnt>0)
{
r=RpmFac/RpmCnt;
s=RpmMea*10;
if((r<s)||(s==0))
{
s=0;
for(i=0,j=1;i<9;i++,j++)
{
p=RpmAvr[j];
RpmAvr[i]=p;
s+=p;
}
RpmAvr[i]=r;
s+=r;
s/=10;
RpmMea=s;
}
}
else
RpmMea=0;
}
/******************************************************************/
void IniDsp(void) // Init Display
{
Wire.begin(); // Start up I2C bus
delay(500);
Wire.beginTransmission(DSP);
Wire.write(B00000000); // Instruction byte. Zero: the next byte is the control byte
Wire.write(B00100111); // Control byte (dynamic mode, digits 1+3 on, digits 2+4 on, 6 mA current
Wire.endTransmission();
}
void ClrDsp(void) // Clear display
{
Wire.beginTransmission(DSP);
Wire.write(B00000001); // Instruction byte. One: first digit is 1 (right side)
Wire.write(B00000000); // Digit 1 (Right)
Wire.write(B00000000); // Digit 2
Wire.write(B00000000); // Digit 3
Wire.write(B00000000); // Digit 4 (Left)
Wire.endTransmission();
}
void ThrDsp(void) // Display measure
{
int i;
long v;
byte d[4];
v=RpmMea;
for(i=0;i<4;d[i]=v%10,v/=10,i++);
Wire.beginTransmission(DSP);
Wire.write(B00000001); // Instruction byte. One: first digit is 1 (right side)
Wire.write(DspDig[d[3]]); // Digit 4 (left)
Wire.write(DspDig[d[2]]); // Digit 3
Wire.write(DspDig[d[1]]); // Digit 2
Wire.write(DspDig[d[0]]); // Digit 1 (right)
Wire.endTransmission();
}
/******************************************************************/
void IniSns(void) // Init Sensor
{
pinMode(SNS,INPUT_PULLUP);
attachInterrupt(SIT,SnsInt,FALLING);
}
void SnsInt(void) // Sensor Interruption
{
unsigned long t,d;
t=micros();
if(t>RpmTmr)
d=t-RpmTmr;
else
d=MXL-t+RpmTmr;
if(d>RMX) // Debounce
RpmCnt=d;
RpmTmr=t;
}