Why?
This might be useful for accurate position sensing in home made / hacked computer aided manufacture systems. Adds USB functionality to your callipers.
A great reference on reading digital callipers can be found at:
http://www.shumatech.com/support/chinese_scales.htm
What this instructable adds to the shumatech tutorial is:
How to use an Arduino to read the callipers (using very few extra components).
Details of another protocol found to be in use on some callipers.
Basic Arduino code is provided.
To see more of my work please visit j44industries.
Remove these ads by
Signing UpStep 1The Callipers
After some experimenting with a multi meter and a jyetech oscilloscope (a very cheap basic oscilloscope that can be bought in kit form for under £40) I found the pins to be as shown in the diagram.
| « Previous Step | Download PDFView All Steps | Next Step » |











































TIA, -joe
I use the serial monitor part of the arduino software (button next to upload).
It does not need any commands, and even if you have go the wiring wrong you should still get the" ready" message from the code. If you are having problems with my code try using the Graph example sketch which can be found in the communications section of the examples to test getting data from the arduino.
J44
I learned quite a bit playing with your script, and one from another forum. My goal was to have the arduino convert the binary to a decimal value. I could not figure a way to change your script to capture the 1 and 0 (sent via serial.print.) to a string or array. Is there a command so that you can append a string with bits as they are read in a loop?
Anyways, I now have a script that mostly works; the binary string is truncated properly and converted. I need work and find a way to set the value to be divided by 1000- so that is shows inchs with a decimal place rather than thousanths of a inch (it now rounds to 1 if divided by 1000). Also, I need mod it so that it will display negative readings.
//http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1235853702/0
volatile int count = 0;
int total = 0;
char data[14];
int dataPin = 4;
int gauge = 0; // display of calipers reading
int factor = 0;
unsigned long sec;
void setup(){
pinMode(dataPin, INPUT); //DATA line goes to Arduino digital pin 4
Serial.begin(9600);
delay(500);
//attachInterrupt(0,getBit,FALLING); //CLOCK line goes to Arduino digital pin 2
}
void loop(){
int i,time;
for(i=2;i<14;i++){ //initialize array of bits to 0
data[i]=0;
}
do{time = pulseIn(2, LOW);} //repeatedly get the length of LOW pulses until one is longer than 130uS
while(time < 130);
attachInterrupt(0,getBit,FALLING); //start watching data line
while(count < 14){} //wait till all bits are filled in
detachInterrupt(0);
count = 0;
for(i=2;i<14;i++){
}
gauge = 0; //the following is code for converts least significant bit first binary to decminal, units are thousandths of an inch
factor = 1;
for(i=2; i<14; i++){
gauge += data[i]*factor;
factor = factor*2;
}
Serial.print("Time (sec):");
sec = millis();
Serial.print(sec/1000);
Serial.print(" Inches:");
Serial.print(gauge);
delay(1000);
Serial.println();
}
void getBit(){
char sample = 0; //variable used for "triple sampling"
if(digitalRead(dataPin) == HIGH) //here the dataPin is checked three times for a HIGH value.
sample++;
if(digitalRead(dataPin) == HIGH)
sample++;
if(digitalRead(dataPin) == HIGH)
sample++;
if(sample > 1) //if the pin was HIGH at least twice, a 1 is recorded
data[count] = 1;
count++; //increment count so main() knows when the entire string of bits is ready
}
// gnd data clk vcc1.5
// from china
int dataIn = 3;
int clockIn = 2;
int isin=0; //inch=1mm=0
int isfs=0; ///p
int index;
unsigned long xData,oData;// ȁpn
int ledPin = 13; // the number of the LED pin
int ledState = LOW; // ledState used to set the LED
long previousMillis = 0; // will store last time LED was updated
long interval = 500; // interval at which to blink (milliseconds)
long previousGetMillis = 0; // !-
long Timeout = 8; // 8ms
void setup(){
digitalWrite(dataIn, 1);
digitalWrite( clockIn, 1);
pinMode(dataIn, INPUT); //DATA line goes to Arduino digital pin 4
pinMode(clockIn, INPUT);
Serial.begin(9600);
delay(500);
attachInterrupt(0,getBit,RISING); //CLOCK line goes to Arduino digital pin 2 G
index =0;
xData=0;
oData=999;
}
void loop(){
//
if ((index !=0) && (millis() - previousGetMillis > Timeout) ) {
index=0;
xData=0;
};
//
if (index >23) {
if (oData !=xData) {
if (isfs==1)
Serial.print('-');
if (isin==1){ // inch
xData *=5;
Serial.print(xData/10000);
Serial.print('.');
if ((xData % 10000)<1000){
if ((xData % 10000)<100){
if ((xData % 10000)<10){
Serial.print('0');
};
Serial.print('0');
};
Serial.print('0');
};
Serial.println(xData % 10000);
}else { //l6 mm
Serial.print(xData/100);
Serial.print('.');
if ((xData % 100)<10) //e0
Serial.print('0');
Serial.println(xData % 100);
};
}; //if l6
oData =xData;
index=0;
xData=0;
};
if (millis() - previousMillis > interval) {
previousMillis = millis();
if (ledState == LOW)
ledState = HIGH;
else
ledState = LOW;
digitalWrite(ledPin, ledState);
}
}
void getBit(){
previousGetMillis=millis();
if(index < 20){
if(digitalRead(dataIn)==1){
xData|= 1<<index;
};
} else {
if (index==20) //,21M:&M -
isfs=digitalRead(dataIn);
if (index==23) //,24M:l6 1=6inch
isin=digitalRead(dataIn);
};
index++;
}
Sadly I do not have my arduinos at hand, but when I do I will try this code out.
// gnd data clk vcc1.5
// from china
int dataIn = 3;
int clockIn = 2;
int isin=0; //inch=1mm=0
int isfs=0; ///p
int index;
unsigned long xData,oData;// ȁpn
int ledPin = 13; // the number of the LED pin
int ledState = LOW; // ledState used to set the LED
long previousMillis = 0; // will store last time LED was updated
long interval = 500; // interval at which to blink (milliseconds)
long previousGetMillis = 0; // !-
long Timeout = 8; // 8ms
void setup(){
digitalWrite(dataIn, 1);
digitalWrite( clockIn, 1);
pinMode(dataIn, INPUT); //DATA line goes to Arduino digital pin 4
pinMode(clockIn, INPUT);
Serial.begin(9600);
delay(500);
attachInterrupt(0,getBit,RISING); //CLOCK line goes to Arduino digital pin 2 G
index =0;
xData=0;
oData=999;
}
void loop(){
//
if ((index !=0) && (millis() - previousGetMillis > Timeout) ) {
index=0;
xData=0;
};
//
if (index >23) {
if (oData !=xData) {
if (isfs==1)
Serial.print('-');
if (isin==1){ // inch
xData *=5;
Serial.print(xData/10000);
Serial.print('.');
if ((xData % 10000)<1000){
if ((xData % 10000)<100){
if ((xData % 10000)<10){
Serial.print('0');
};
Serial.print('0');
};
Serial.print('0');
};
Serial.println(xData % 10000);
}else { //l6 mm
Serial.print(xData/100);
Serial.print('.');
if ((xData % 100)<10) //e0
Serial.print('0');
Serial.println(xData % 100);
};
}; //if l6
oData =xData;
index=0;
xData=0;
};
if (millis() - previousMillis > interval) {
previousMillis = millis();
if (ledState == LOW)
ledState = HIGH;
else
ledState = LOW;
digitalWrite(ledPin, ledState);
}
}
void getBit(){
previousGetMillis=millis();
if(index < 20){
if(digitalRead(dataIn)==1){
xData|= 1<
};
} else {
if (index==20) //,21M:&M -
isfs=digitalRead(dataIn);
if (index==23) //,24M:l6 1=6inch
isin=digitalRead(dataIn);
};
index++;
}