Hacked digital caliper writes measurements in Excel sheet

For my bachelor thesis I needed to take a lot of manual measurements with a caliper. As a side project I decided to spend some time on interfacing the caliper via a connection bus that basically every cheap caliper has. Most of the time they are just hidden and a hole needs to be drilled in the housing.

As a microcontroller I used an ESP32 because it also has a bluetooth module and can act as a bluetooth keyboard. When you press a button it reads the current value from the caliper and types it into whatever program you have open at the moment.

Initially I planned with one day of work… But I had to modify two different calipers because I found out that there are two known protocols that the cheap calipers use and I found working code for only one of them. Additionally I had trouble getting the level shifters to work because the ESP32 works on 3.3V and the first caliper with 1.5V. The “Parkside” Caliper from Lidl that I ended up using also uses 3.3V. In the end it took me four days to get everything working…

For the code I adapted a tutorial by electronoobs: https://www.electronoobs.com/eng_arduino_tut93.php

/* Read the caliper data with Arduino and display mm or inch on serial monitor and LCD
 * Tutorial on: https://www.electronoobs.com/eng_arduino_tut93.php
 * Schematic: https://www.electronoobs.com/eng_arduino_tut93_sch1.php
 * 
 * Adapted by aldabro
 * Code is now written for an ESP32, that acts as a bluetooth keyboard and types the current value, when a button is pressed.
 * It is necessary the switch Excel to use a dot as the decimal seperator and configure the keyboard as English.

GND (black)             GND + 200 ohm 
CLK                     D17
DAT                     D16
BUTTON                  D15
VCC 3.3V (red)          3.3V
 */
 
#include <BleKeyboard.h>

#define CLOCK_PIN 17
#define DATA_PIN  16
#define BUTTON_PIN 15

unsigned volatile int buttonFlag = 0;
BleKeyboard bleKeyboard;

void setup() 
{
  Serial.begin(115200);  
  pinMode(CLOCK_PIN, INPUT);
  pinMode(DATA_PIN, INPUT);
  pinMode(BUTTON_PIN, INPUT_PULLUP); 
  attachInterrupt(digitalPinToInterrupt(BUTTON_PIN), buttonISR, RISING);  

  Serial.println("Starting BLE work!");
  bleKeyboard.begin();
}

char buf[20];
unsigned long tmpTime;
int sign;

int inches;
long value;
float result;
bool mm = true; //define mm to false if you want inces values

void loop()
{
  while(digitalRead(CLOCK_PIN)==LOW) {}
  tmpTime=micros();
  while(digitalRead(CLOCK_PIN)==HIGH) {}
  if((micros()-tmpTime)<500) return;
  readCaliper(); 
  buf[0]=' ';
  dtostrf(result,6,3,buf+1); strcat(buf," in ");
  dtostrf(result*2.54,6,3,buf+1); strcat(buf," cm "); 

  if(buttonFlag == 1) {
    if(bleKeyboard.isConnected()) {
      Serial.println("Sending caliper result via Bluetooth Keyboard and pressing Enter");
      bleKeyboard.print(result); // prints with dot as decimal seperator
      bleKeyboard.write(KEY_RETURN);
      //bleKeyboard.write(KEY_RIGHT_ARROW); //can be used inestead of pressing enter to switch to the next cell on the right
    }
    if(mm)
    {
      Serial.print(result); Serial.println(" mm");    
    }
    else
    {
      Serial.print(result); Serial.println(" in");    
    }
    delay(200);
    buttonFlag = 0;
  }
}

void readCaliper()
{
  sign=1;
  value=0;
  inches=0;
  for(int i=0;i<24;i++) {
    while(digitalRead(CLOCK_PIN)==LOW) {}
    while(digitalRead(CLOCK_PIN)==HIGH) {}
    if(digitalRead(DATA_PIN)==HIGH) {
      if(i<20) value|=(1<<i);
      if(i==20) sign=-1;
      if(i==23) inches=1; 
    }
  }
  if(mm)
  {
    result=(value*sign)/100.0;
  }
  else
  {
  result=(value*sign)/(inches?2000.0:100.0); //We map the values for inches, define mm to false if you want inces values
  }
}

void buttonISR() {
  buttonFlag = 1;
}

Posted

in

by