First project - a dial indicator reader

Wanted to post my first Arduino project - a dial indicator reader. This was very easy and took me only a few hours to figure out, and I’m not a very good programmer. The intended use is to provide a remote reading from an indicator that will connected to a focuser mounted on a telescope, enabling one (me) to determine best focus (while staying warm inside). Comments would be greatly appreciated! --Keith

:slight_smile:

//indicator_3 K. Warner 10/29/10
//
//This Arduino code takes a 24 bit serial data stream from a CenTech (Harbor Freight) #93295
//dial indicator and inverts it to ASCII on the serial port. The encoder uses a 1.55V watch
//battery with its positive terminal grounded; HIGH is 0V and LOW is about 1.3V. To trigger the
//digital inputs on 5V logic the clock and data outputs are buffered with pullup transistors. The
//code and description are written with reference to the pulse streams as observed on an
//oscilloscope connected to the buffer outputs, which are connected to digital inputs on an
//Arduino Uno board; HIGH is 5V and LOW is 0V.
//
//The clock is connected to digital pin 2, which is used as interrupt 0; it has the form
// H560/L220/H560/L220/H560/L220/H560/L1000…repeat 6 times…/L280000/…
//with units in microseconds. (Values are approximate.) The data output is connected to pin 3,
//and is inverted (NOT 2’s complement, as some other indicator outputs are encoded). The data
//has the form
// L340/Bit0 440/L340/Bit1 440/L340/Bit2 440/L340/Bit3 1200/…6X…/L290000/…
//thus, the bits are read when the clock goes low. The data has the form
// B0…B11 - binary value of dial readout, inverted
// B12…B19 - not used
// B20 - sign bit (’-’ is high, ‘+’ is low)
// B21…B22 - not used
// B23 - units bit (‘in’ is high, ‘mm’ is low)
//
//NOTE THAT THIS ROUTINE HAS BEEN WRITTEN FOR A SPECIFIC INDICATOR. The term “SPC output” is used
//by various manufacturers to describe a data output that can be used for process control (I take
//“SPC” to mean “statistical process control” but there may be another meaning); in any event the
//term DOES NOT describe a standard protocol. Others have decoded outputs from Mitotoyo, Starrett,
//and generic (primarily Chinese) tools; as far as can tell from a web search no one has posted a
//translator for this particular indicator. I also do not know if it would work with other “CenTech”
//tools.
//
//
//Global declarations
volatile long valout=0; //valout is a 32 bit long integer that will contain the 24 bit data
volatile int n=0; //n is a pointer for the 24 data bits in valout
word value=0; //value will contain the binary value of the 12 bit data
char sign=’+’; //the data sign
String unit=“xxx”; //the units string
float unit_div=1; //the scale factor for mm or in
int unit_plcs=1; //the number of places to the right of the dp to display
float val_final=0; //the final value to be displayed, as a floating point number which takes care of the dp position

//Initial settings and start interrupt
void setup()
{
Serial.begin(9600); //set com to 9600 baud
pinMode(2,INPUT); //Set the pins to input; actually this is the default
pinMode(3,INPUT);
attachInterrupt(0,clk,FALLING); //Set the interrupt to read the data pin when the clock goes low
}

//Read the bits returned from the interrupt, convert and send the data out; loop continuously
void loop()
{
while (n!=23); //this is a critical step - loop while the pointer is not equal to 23
//- the pointer increments during the interrupt to a total of 24 bits
if (bitRead(valout,20)==HIGH) //Read the sign bit (bit 20)
{
sign=’-’;
}
else
{
sign=’+’;
}
if (bitRead(valout,23)==HIGH) //Read the units bit (bit 23)
{
unit = " in";
unit_plcs = 4;
unit_div = 2000;
}
else
{
unit = " mm";
unit_plcs = 2;
unit_div = 100;
}
for (int m=0; m<=11; m++) //Read the first 12 bits of valout to get the actual value
{
bitWrite(value,m,bitRead(valout,m));
}
val_final=float(value)/unit_div; //scale the data as determined by the units
Serial.print(sign); //print the sign
Serial.print(val_final,unit_plcs); //print the value
Serial.println(unit); //print the unit type
n=0; //reset the bit pointer
}

//The interrupt handler - on the falling edge of each clock pulse, read the corresponding data bit
void clk()
{
bitWrite(valout,n,!digitalRead(3)); //Read the data bit and write its inverse to the n bit in valout
n=n+1; //increment the pointer
}

Looks cool! Nice job ;D

--Dylan

The Harbor Freight documentation doesn't mention anything about a serial interface. How are you connecting to the dial indicator? Is there a socket? Can you post pictures? Thanks.