Reading Digital Callipers With an Arduino / USB

216,824

223

47

Introduction: Reading Digital Callipers With an Arduino / USB

How to use an Arduino to read the signal from a set of digital callipers and send the reading over USB.

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.


Step 1: The Callipers

The callipers I have been working with were the Electronic Digital Callipers by Precision Gold. I bought the callipers from Maplin (item code N48AA) in the UK for just under £20.

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.


Step 2: Voltages: Logic and Power

The Arduino uses 5V logic but the callipers output 1.5V logic. This is a bit of a bodge and may not always work, really a proper logic level conversion circuit should be used but the flowing is a simple hack that worked well with my Arduino:

My Arduino changed between logic high and logic low at about 2.5V (this could vary a bit between boards).

Connecting the positive pin on the callipers to the 3.3V supply means when the clock and data pins are connected to the arduino their voltage seems to vary between 3.3V and 1.8V, which is the Arduino reads as logic high and low respectively.


Powering the callipers with the Arduino:

To avoid needing a battery in the callipers the power circuit pictured can be used (remove the button cell). This method relies on using an LED to regulate the supply voltage for the callipers.

Resistor
About 200Ohm


Capacitor
I used a 10uF which worked well, but there would be no harm in using a larger capacitance. 2V or more rating.


LED
For the LED try to find one which has as close to a 1.6V drop across it as possible.
I used a red LED with a 1.8V drop across it. Red and IR LEDs tend to have low voltage drops across them.


Step 3: The Data Protocol

The data protocol used on my callipers was as follows:

Clock pulse as shown in the picture.

Reading the data on a falling clock edge gave a sensible output.

Example data output:

1,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,  (Screen shows 0.00 mm or 0.000 inches)
1,0,0,0, 1,0,1,1, 1,1,1,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,  (Screen shows 10.00mm)
1,0,0,1,  0,0,1,1,  0,0,0,0,  0,0,0,0,  0,0,0,0,  0,1,0,0, (Screen shows -1.00mm)
1,0,0,0,  1,1,0,0,  1,0,1,0,  1,1,1,0,  0,0,0,0,  0,0,0,0, (Screen shows 150.00mm)


Interpretation of data:

?,X,X,X, X,X,X,X, X,X,X,X, X,X,X,X, ?,?,?,?, ?,Y,?,?
? = Not sure
X's for a binary number with least significant bit at the start of the string. The binary number is the distance in mm times 100.
Y = Sign bit if Y = 1 number is negative if Y = 0 number is positive.

Note: make sure the callipers are set to mm the inches mode behaves very similarly except the least significant bit is used to show 1/2000ths of an inch.


Step 4: Arduino Code

This is a very basic Arduino code that should be compatible with several calliper data protocols.
There are commas in between each value to make it easy to use .CSV files to import the data into spreadsheets.

The main requirement of this code is that the data is read on the falling edge of a clock pulse.

Hopefully this code should mean when you connect your Arduino to the computer and use the serial monitor at 115200 Baud you will get sensible looking binary out.

Trouble shooting:
If the length of the binary strings changes a lot you may have the clock and data pins the wrong way around.

Code:

//Simple Digital Calliper Reader
//See http://j44industries.blogspot.com/

// Pin Declarations
int dataIn = 11;
int clockIn = 12;

// Variables
int clock = 1;
int lastClock = 1;
unsigned long time = 0;
unsigned long timeStart = 0;
int out = 0;


void setup() {
  // Pin Set Up
  pinMode(dataIn, INPUT);     
  pinMode(clockIn, INPUT);  


  Serial.begin(115200);
  Serial.println("Ready: ");
}


void loop(){

  lastClock = clock;
  clock = digitalRead(clockIn);

  if (lastClock == 1 && clock == 0){
    out = digitalRead(dataIn)+digitalRead(dataIn)+digitalRead(dataIn); // Tripple sampling to remove glitches
    if((micros() - time) > 800){
      Serial.println(" ");
    }
    else if((micros() - time) > 400){
      Serial.print("  ");
    }

    if (out > 1){
      Serial.print("1");
    }
    else{
      Serial.print("0");
    }
    Serial.print(",");
    time = micros();
  }
}




USB Contest

Participated in the
USB Contest

Be the First to Share

    Recommendations

    • Go Big Challenge

      Go Big Challenge
    • Digital Fabrication Student Design Challenge

      Digital Fabrication Student Design Challenge
    • Science Fair Challenge

      Science Fair Challenge

    47 Comments

    0
    JGerstenhaber
    JGerstenhaber

    4 months ago

    Thanks for this.
    I made a few edits:

    For the hardware, I used a 3.3V arduino. This simplifies the circuit because you only need 2 diodes. I added a diode between the V- and GND and a diode between V+ and 3.3V. Because the diodes drop 0.7V, this effectively runs it in 1.9V which didn't cause any issues for me, plus it allows the data and clock lines to be directly connected without any issues of level shifting (although I used a couple of resistors, just in case).

    In the code to get out decimal values:

    int dataIn = A0;
    int clockIn = A2;
    // Variables
    int clock = 1;
    int lastClock = 1;
    unsigned long time = 0;
    unsigned long timeStart = 0;
    int out = 0;
    long longout=0;
    float finalout;
    void setup() {
    // Pin Set Up
    pinMode(dataIn, INPUT);
    pinMode(clockIn, INPUT);
    Serial.begin(115200);
    Serial.println("Ready: ");
    }
    void loop(){
    lastClock = clock;
    clock = digitalRead(clockIn);
    if (lastClock == 1 && clock == 0){
    out = digitalRead(dataIn)+digitalRead(dataIn)+digitalRead(dataIn); // Tripple sampling to remove glitches
    if((micros() - time) > 1200){
    longout=longout>>8;
    %negative numbers switch to 2s complement
    if (longout & 0b00000000000010000000000000000000){
    longout=longout & 0b11111111111101111111111111111111;
    longout=~longout + 1;
    }
    finalout=(float(longout)-1)/100;
    Serial.print("data:");
    Serial.println(finalout);
    longout=0;
    }
    else if((micros() - time) > 400){
    }
    if (out > 1){
    longout=longout|0b01000000000000000000000000000000;
    longout=longout>>1;
    }
    else{
    longout=longout>>1;
    }
    time = micros();
    }
    }

    0
    ehzaz_ali20
    ehzaz_ali20

    Reply 4 months ago

    Could you please help me to resolve the error.

    Capture.PNG
    0
    StumpChunkman
    StumpChunkman

    Reply 4 months ago

    I always check for semi-colons at the end of the lines around the error first.

    0
    ehzaz_ali20
    ehzaz_ali20

    Question 4 months ago

    Hello. Hope you are doing great.
    The program you have provided helps me a lot. But I am facing a problem. Actually I need output in decimal form but the output was in Binary form. If you have a program for decimal output Please share it with me. If you don't have a program kindly guide me how I am able to convert binary output into decimal output. It will be a huge favor. Waiting for your response.
    Regards,
    Ehzaz Ali

    0
    Pfuufy
    Pfuufy

    1 year ago

    Hey guys, I'm a noobie so sorry for the stupid question. What is the point of the intermediary circuit with the capacitor and LED?

    0
    richardspandit
    richardspandit

    Question 2 years ago

    Can't get it to work. I used quite a large capacitor (33uF/25V) but neither analogRead nor digitalRead gives me anything but 0 on either pin (I modified the code to give me readings on each every second just to check). Calliper powers up fine and appears to work as it should (once I got the LCD connector lined up properly!). I wonder if my Nano clone doesn't sense the change in logic?

    0
    AuliaW1
    AuliaW1

    Question 3 years ago

    hi, thank you for this! it's very helpfull :)
    but i wonder by 'Reading the data on a falling clock edge ....'. does the data sent for every falling edges or just for the big one (0.4ms pulse)? thanks again anyway ;)

    0
    RafaelL112
    RafaelL112

    3 years ago

    Hi, I did make this project, but I would like to add a wireless component to send/receive data. It's possible? Tks

    0
    dobata
    dobata

    5 years ago

    Congratulations, the trick about connect the 1.5V and 3.3V positives and use the led as voltage divider is very smart!

    0
    MarcR15
    MarcR15

    5 years ago

    The example code doesn't perfectly correspond to the example data output.

    In the code, a 400 microsecond delay will print out a single space character. But in the example data output, you have commas.

    0
    dan3008
    dan3008

    5 years ago

    I got the exact same callipers yesterday from maplin for £9.99 on sale :D Looking at doing this now, so I can use the calipers with my computer :D

    0
    Raphango
    Raphango

    5 years ago

    Great! Congratulations!!

    0
    sspence
    sspence

    6 years ago on Introduction

    For the 52 bit Mitutoyo protocol, see https://www.instructables.com/id/Interfacing-a-Digital-Micrometer-to-a-Microcontrol/

    0
    sspence
    sspence

    6 years ago on Introduction

    I have a 5 pin Igaging Origin unit. Do you have any pinout data?

    0
    paulodrugos
    paulodrugos

    7 years ago on Introduction

    Thanks a lot for the example and the arduino code!

    I find out how to convert the binary output from the caliper to decimal value, the caliper sends a 24bits package.

    That package follows the pattern attached, so the value is in that 16 bits (from bit1 to bit16) reversed...

    Example: My caliper measure 59.0mm, the data output was: 1,0,1,0, 0,1,0,0, 0,1,1,1, 0,1,0,0, 0,0,0,0, 0,0,0,0.

    Reversing the 16 bits I got: 0001011100010010, wich, in decimal, is 5906

    bits.png
    0
    linux-works
    linux-works

    7 years ago on Introduction

    what is the purpose of the capacitor across the diode? I see the diode is a 'poor mans zener' and the series R is the current limit so the zener (I mean diode) won't burn out. but why do you need a cap across it? for extra filtering? you would be feeding clean dc to this, anyway, right?

    0
    j44
    j44

    Reply 7 years ago

    Your interpritation of the circuit is correct, I am probably being paranoid with the capacitor. It was to try to avoid any issues if the callipers briefly drew more power.

    hello sir, i am impressived by what you done for this project, but i have a problem, i try using different calliper(which is mitutoyo calliper) but i can't get any signal come out from the data or clock at all, is that because Mitutoyo Calliper have special way to send out the signal or its just my mistake on my process.