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;
}
Leave a Reply