Calipers angle measurement

Hello!

I'm looking for a way to measure the distance between the tips of such calipers, or basically the angle between the arms. For the size of calipers and distance measurement I calculated the accuracy of the angle measurement to be at least .11 rad or .64 deg. (Lower is welcome)
I need to have it installed on the caliper obviously so looking for a relatively small form factor.
I assume an encoder would be large for the is application? So maybe some potentiometer or variable capacitor I can read with such accuracy
Any suggestions for such a sensor?
Better if I can get a digital reading directly so I don't need to account for voltage variance etc
Thanks!

Do you know that you can purchase calipers with a digital output?

1 Like

Yes, I updated added a picture, those angular onesare more hard to find with digital interface I can connect to some Arduino and do some processing
The are some really expensive ones but looks like overkill for what I need - if you know of something like that please let me know

Hi, @gadile
Welcome to the forum.

What are you measuring with the calipers?

Is that the precision of the reading?

Tom.... :smiley: :+1: :coffee: :australia:

Thanks, glad to be here :folded_hands:

And yes, that's a calculation of the precision I need in distance converted to angle at the axis.
Arm length is 800mm and precision needed is +/- 2.5mm - the translates to the minimal precision I mentioned in degrees

I would use the potentiometer idea, and this display... (and a small mcu)

1 Like

Are you trying to measure offline or online, so to speak? If off-line, a high-accuracy tape glued to something dense that has very low thermal expansion, but if on-line, that will be very difficult, and that calliper is way too inaccurate.

How about this one:-
Electronic outside Calipers

Not too expensive.

The handles cross at different points as the arms open or close. They overlap inside of the crossing point. You could measure at the back end, add an arc to a handle to measure how far apart the ends of the handle and leverage a mechanical advantage in the process.

Doesn't look like they allow external read, I need to do real time processing on the data, and also I need to get to about 800mm measurement size, I should have mentioned that earlier

Yes you should.

I'm looking for a continuous read that can process and store as the calipers moves

I did mention I want to read and process the data though.. :slightly_smiling_face:

Yes working out the math is ok, at the end it's a triangle between the points of measurement and the axis. But I need to be able to read the angle

Angles measure radians along arcs. Scale must be curved and attached to one arm. Otherwise like before you do some trig with the triangles, it's up to you.

Is that the range of the one in your photo? It looks extended to about 9 cm. How accessible is an 80 cm target? If you tell us what you're measuring there may be other options. Otherwise +1 to the post #6 idea.

You can use an AS5600 rotation sensor

Has 4096 points per rotation = 360/4096 ~ 0.09° ~ 0.00153 rad accuracy.
Can do hundreds samples per second, might be real time enough, you did not specify how much you need.

Close the caliper
Make a sample (average multiple readings) to set the zero point.
open it
measure (average multiple readings)
close it
check if zero still is zero ==> or time to (re)calibrate.

2 Likes

Here is this idea in a simulation...

ezgif-5d3bed699340cc

sketch.ino
// https://forum.arduino.cc/t/calipers-angle-measurement/1393255/4

// #include <TinyDebug.h> // for serial monitor output
// tdPrintln("Not using SRAM"); // example Serial.println();

// #include <avr/pgmspace.h> // for memory

#include "SSD1306_minimal.h"
SSD1306_Mini oled; // 0.42" display 72x40

byte buttonpin = PB3, potpin = A2;
int potval, potvalold, minval, maxval;
char vals[6];

#define CHARWIDTH 6 // pixel width of a character and kern

void setup() {
  oled.init(0x3C); // Initialize display with address
  oled.clear(); // Clears the display
  pinMode(buttonpin, INPUT_PULLUP);
  pinMode(potpin, OUTPUT);

  calibrate_pot();
  show_min_max();
}

void loop() {
  read_pot();
}

int read_pot() {
  potval = analogRead(potpin);
  if (potval != potvalold) {
    oled.cursorTo(1, 1);
    oled.printString("          "); // clear display

    if (potval < minval) {
      oled.cursorTo(1, 1);
      oled.printString("< MINVAL  ");
    }
    if (potval > maxval) {
      oled.cursorTo(1, 1);
      oled.printString("> MAXVAL  ");
    }
    if ((potval >= minval) && (potval <= maxval)) {
      int_to_char_array(potval, 1);
    }
  }
  potvalold = potval;
}

void calibrate_pot() {
  for (byte i = 0; i < 2; i++) {
    oled.cursorTo(0, 0); // col 0 to 7, row 0 to 3

    if (i == 0)
      oled.printString("SET MIN.");
    else
      oled.printString("SET MAX.");
    press_to_continue();

    if (i == 0)
      // minval = read_pot();
      minval = analogRead(potpin);
    else
      // maxval = read_pot();
      maxval = analogRead(potpin);

    oled.cursorTo(0, 1);
    if (i == 0)
      oled.printString("min set.");
    else
      oled.printString("max set.");
    press_to_continue();

    oled.clear();
  }
}

void show_min_max() {
  oled.cursorTo(2, 0);
  oled.printString("MIN");
  int_to_char_array(minval, 0);

  oled.cursorTo(2, 1);
  oled.printString("MAX");
  int_to_char_array(maxval, 1);

  press_to_continue();
  oled.clear();
}

void int_to_char_array(int val, int row) {
  int tens = val / 1000;
  int ones = (val - (tens * 1000)) / 100;
  int tnts = (val - (tens * 1000) - (ones * 100)) / 10;
  int hnds = (val - (tens * 1000) - (ones * 100) - (tnts * 10)) / 1;

  vals[0] = tens + '0';
  vals[1] = ones + '0';
  vals[2] = '.';
  vals[3] = tnts + '0';
  vals[4] = hnds + '0';

  for (byte i = 0; i < 5; i++) {
    oled.cursorTo((5 * CHARWIDTH) + (i * CHARWIDTH), row);
    oled.printChar(vals[i]);
  }
}

void press_to_continue() {
  oled.cursorTo(0, 3);
  oled.printString(">button<");
  while (digitalRead(buttonpin) == HIGH);
  delay(250); // fast readings need delay
}
diagram.json for wokwi
{
  "version": 1,
  "author": "Anonymous maker",
  "editor": "wokwi",
  "parts": [
    {
      "type": "wokwi-attiny85",
      "id": "tiny",
      "top": -12.1,
      "left": -22.7,
      "rotate": 90,
      "attrs": {}
    },
    {
      "type": "board-ssd1306",
      "id": "oled1",
      "top": 31.94,
      "left": -18.97,
      "attrs": { "i2cAddress": "0x3c" }
    },
    { "type": "wokwi-potentiometer", "id": "pot1", "top": -116.5, "left": -19.4, "attrs": {} },
    {
      "type": "wokwi-text",
      "id": "text1",
      "top": -9.6,
      "left": 38.4,
      "attrs": { "text": "<------ SDA" }
    },
    {
      "type": "wokwi-text",
      "id": "text2",
      "top": 9.6,
      "left": 48,
      "attrs": { "text": "<---- SCL" }
    },
    { "type": "wokwi-vcc", "id": "vcc1", "top": -76.04, "left": 67.2, "attrs": {} },
    { "type": "wokwi-gnd", "id": "gnd1", "top": 28.8, "left": -39, "attrs": {} },
    {
      "type": "wokwi-pushbutton",
      "id": "btn1",
      "top": -13,
      "left": -115.2,
      "attrs": { "color": "green", "xray": "1" }
    },
    {
      "type": "wokwi-text",
      "id": "text3",
      "top": -144,
      "left": -48,
      "rotate": 45,
      "attrs": { "text": "MIN --->" }
    },
    {
      "type": "wokwi-text",
      "id": "text4",
      "top": -144,
      "left": 28.8,
      "rotate": 315,
      "attrs": { "text": "<--- MAX" }
    },
    {
      "type": "wokwi-text",
      "id": "text5",
      "top": -144,
      "left": -9.6,
      "attrs": { "text": "CALIPER" }
    }
  ],
  "connections": [
    [ "oled1:SCL", "tiny:PB2", "green", [ "h0.3", "v-38.4", "h-18.5" ] ],
    [ "oled1:SDA", "tiny:PB0", "green", [ "v-19.2", "h-37.13" ] ],
    [ "oled1:VCC", "tiny:VCC", "red", [ "v-48", "h-8.75" ] ],
    [ "oled1:GND", "tiny:GND", "black", [ "v-9.6", "h-28.8" ] ],
    [ "gnd1:GND", "tiny:GND", "black", [ "h9.6", "v-8.4" ] ],
    [ "gnd1:GND", "pot1:GND", "black", [ "v-48", "h86.4" ] ],
    [ "tiny:VCC", "pot1:VCC", "red", [ "h0" ] ],
    [ "vcc1:VCC", "pot1:VCC", "red", [ "v9.6", "h115.2" ] ],
    [ "gnd1:GND", "btn1:2.r", "black", [ "v0" ] ],
    [ "btn1:1.r", "tiny:PB3", "green", [ "v0" ] ],
    [ "tiny:PB4", "pot1:SIG", "green", [ "h-19.2", "v-39.2", "h86.8" ] ]
  ],
  "dependencies": {}
}

Instructions are:

  • mount potentiometer
  • start tiny85
  • at "SET MIN" close calipers to zero
  • press button to set min
  • at "SET MAX" open calipers to max
  • press button to set max
  • OLED will display current reading

*** oops... forgot to map "min..max" to 00.00 to 100.00

1 Like

Excellent! thank you

will look into that, thank you!