This guide is intended for developers who want to integrate the Bed Distance Sensor into platforms other than those officially supported.
The communication protocol used by this sensor is not standard I2C. Unlike standard I2C, there is no address transfer phase in the timing diagram. This design decision was made to achieve the fastest possible response time during Z-axis homing on 3D printers.
A dedicated SoftwareI2C library is available for this sensor, allowing it to be connected to any two GPIO pins on any MCU.

DATA DO — Data output from the sensor.
46 represents a measured distance of 0.46 mm#define CMD_READ_VERSION 1016 // read sensor version
#define CMD_START_READ_CALIBRATE_DATA 1017 // start reading raw calibration data
#define CMD_DISTANCE_MODE 1018 // finish reading raw calibration data
#define CMD_START_CALIBRATE 1019 // start calibration
#define CMD_DISTANCD_RAWDATA_TYPE 1020 // switch output distance data type to raw data, default is mm (1 represent 0.01mm)
#define CMD_END_CALIBRATE 1021 // finish calibration
#define CMD_REBOOT_SENSOR 1022 // BDsensor will reboot itself
#define CMD_SWITCH_SENSOR 1023 // BDsensor will work as normal inductive probe like a switch sensor.
To trigger this via G-code, send: M102 S-6
Sequence:
CMD_READ_VERSION → BD_i2c_write(CMD_READ_VERSION);BD_i2c_read() & 0x3ff;BD_i2c_read() & 0x3ff;BD_i2c_read() & 0x3ff;BD_i2c_read() & 0x3ff;CMD_END_READ_CALIBRATE_DATA → BD_i2c_write(CMD_END_READ_CALIBRATE_DATA);Sequence:
CMD_START_CALIBRATE → BD_i2c_write(CMD_START_CALIBRATE);G1 Z0 and wait for the move to complete), then send BD_i2c_write(0); — the sensor stores this as its zero reference.BD_i2c_write(1);BD_i2c_write(2);BD_i2c_write(3);BD_i2c_write(39);CMD_END_CALIBRATE → BD_i2c_write(CMD_END_CALIBRATE); — the sensor saves all 40 calibration points to non-volatile storage.To trigger this via G-code, send: M102 S-5
Sequence:
CMD_START_READ_CALIBRATE_DATA → BD_i2c_write(CMD_START_READ_CALIBRATE_DATA);BD_i2c_read() & 0x3ff;BD_i2c_read() & 0x3ff;BD_i2c_read() & 0x3ff;CMD_END_READ_CALIBRATE_DATA → BD_i2c_write(CMD_END_READ_CALIBRATE_DATA);G-code command:
M102 Sx // Set the active adjustment Z height threshold.
// x = 0 to 39 (units of 0.1 mm).
// Example: M102 S4 enables adjustment when Z ≤ 0.4 mm.
// Send M102 S0 to disable.
How it works:
The firmware continuously reads the current Z distance from the sensor, compares it against the configured threshold, and applies fine corrections using the Baby Step (BABYSTEPPING) function.
Reference implementation (Marlin firmware):
https://github.com/MarlinFirmware/Marlin/blob/bugfix-2.1.x/Marlin/src/feature/bedlevel/bdl/bdl.cpp#L99
How it works:
If the distance reading from the sensor falls below 0.01 mm, the endstop pin is set high; otherwise it is set low.
Reference implementation (Marlin firmware):
// bdl.cpp — triggers endstop state update
endstops.bdp_state_update(z_sensor <= 0.01f);
// endstops.h — stores the virtual endstop state
static void bdp_state_update(const bool z_state) { bdp_state = z_state; }
// endstops.cpp — intercepts Z_MIN_PIN reads and returns sensor state
#define READ_ENDSTOP(P) ((P == Z_MIN_PIN) ? bdp_state : READ(P))
The following sketch initialises the communication interface and continuously reads distance data from the sensor.
void setup() {
delay(500);
// init the communication port.
BD_SENSOR_I2C.i2c_init(I2C_BED_SDA,I2C_BED_SCL,0x3C,10);
Serial.begin(115200);
}
void loop() {
unsigned short read_data=0;
//read distance from BDsensor
read_data=BD_SENSOR_I2C.BD_i2c_read();
if(BD_SENSOR_I2C.BD_Check_OddEven(read_data)==0)
printf("Data Check error!\n");
else
{
Distance=(read_data&0x3ff)/100.0;
//display the Distance
sprintf(tmp_1,"Distance:%.2f mm\n",Distance);
printf(tmp_1);
}
delay(100);
}