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; }