Community project

Brake Telemetry Monitor

ESP32
Photo of Brake Telemetry Monitor
Generated with AI

Mohamed Gad

Published October 16, 2026

This brake telemetry monitor uses an ESP32 to track braking force, fluid level, and pad wear in real time. The load cell with instrumentation amplifier measures brake pressure, while a Hall-effect sensor and water level sensor monitor pad condition and fluid status. The system displays readings on a 16x2 LCD and triggers visual alerts when braking force exceeds safe thresholds or fluid drops below minimum levels.

The guide provides a complete wiring diagram, parts list, and step-by-step assembly instructions for integrating the 24V buck converter, logic-level shifter, and sensor conditioning circuits. Included firmware handles analog sampling, threshold detection, and display updates, giving makers a foundation for vehicle brake monitoring or test-stand applications.

Wiring diagram

Wiring diagram for Brake Telemetry Monitor

Gather all the parts

QtyComponent
1

9 V DC battery pack

The 9 V source that supplies the buck converter; use a pack rated for at least 1 A rather than a small rectangular PP3 battery.

1

24v Buck Converter

LM2596-based adjustable step-down buck converter module. Commonly used to regulate a higher battery rail, such as a 2S 18650 pack, down to 5V for Arduino logic. It is a regulator, not a charger or battery protection board.

1

Load Cell

Four-wire strain-gauge straight-bar load cell, common 5 kg hobby scale sensor. It produces a small bridge signal and should be read through a load-cell ADC/amplifier such as HX711 or NAU7802 rather than directly by a microcontroller GPIO.

1

AD620AN instrumentation amplifier (DIP-8)

The precision amplifier that increases the tiny difference from the load cell to a readable voltage.

1

5 kΩ rotary potentiometer

The adjustable gain control for the load-cell amplifier.

1

20 kΩ resistor

20 kΩ

Upper half of the divider that reduces the amplifier output to a safe ESP32 input voltage.

1

10 kΩ resistor

10 kΩ

Lower half of the divider that makes the amplifier-output divider safe for the ESP32.

1

Water Level Sensor

An analog water level sensor module that outputs a voltage proportional to the water level. It uses ten interleaved copper traces and an S8050 NPN transistor to convert water conductivity into an analog voltage signal. The higher the water level, the higher the output voltage. Operates on 3.3V to 5V. To extend sensor lifespan, it is recommended to power the sensor only during readings by controlling the VCC pin via a digital output pin rather than connecting it permanently to 5V.

1

20 kΩ resistor

20 kΩ

Upper half of the divider that reduces the 5 V level-sensor output to a safe ESP32 input voltage.

1

10 kΩ resistor

10 kΩ

Lower half of the divider that makes the water-level output safe for the ESP32.

1

A3144E Hall-effect sensor (TO-92)

The magnetic switch that changes state as the brake-pad wear target reaches it.

1

10 kΩ resistor

10 kΩ

The pull-up that makes the Hall sensor output a safe 3.3 V digital signal.

1

LCD 16x2 I2C

16x2 character LCD display with I2C backpack

1

4-channel bidirectional logic-level converter

The board that safely translates the ESP32 3.3 V I2C signals to the LCD's 5 V signals.

1

NPN Transistor (2N2222 / BC547)

General-purpose NPN bipolar junction transistor (BJT) in TO-92 package. Used as a low-side switch to drive loads (e.g. buzzers) whose current exceeds ESP32 GPIO source capability (~12 mA). A ~1 kΩ base resistor is placed between the ESP32 GPIO and the transistor base. The collector connects to the load negative terminal (buzzer –), and the emitter connects to GND. When the GPIO goes HIGH (3.3 V), the transistor saturates and switches the load on. Compatible with both 2N2222/2N2222A and BC547/BC547B variants. Add a flyback diode (e.g. 1N4148) across inductive load terminals.

1

1 kΩ resistor

1 kΩ

The resistor that limits current from the ESP32 output into the transistor base.

1

3–12 V DC motor

The independent 5 V motor load that runs only while the limit switch is closed.

1

SPDT micro limit switch

The mechanical switch that connects motor power only when its normally-open contacts close.

1

1N4007 Diode

General-purpose silicon rectifier diode in DO-204AL (DO-41) axial through-hole package. Rated 1A average forward current and 1000V peak reverse voltage (VRRM). Forward voltage drop ~0.7V at typical load (up to 1.1V at full 1A). Used here in series with LM7805 Vout for reverse polarity protection: anode to LM7805 output, cathode to 5V rail, resulting in ~4.3V on the output rail. Not suitable for high-frequency switching (reverse recovery ~2µs–30µs); intended for DC or 50/60Hz rectification only.

1

100 nF ceramic capacitor

100 nF

A small bypass capacitor placed close to the AD620 power pins to reduce electrical noise.

1

100 nF ceramic capacitor

100 nF

A small bypass capacitor placed close to the Hall sensor power pins to reduce electrical noise.

1

100 nF ceramic capacitor

100 nF

A small bypass capacitor placed close to the level-sensor power pins to reduce electrical noise.

1

100 nF ceramic capacitor

100 nF

A small bypass capacitor placed close to the LCD power pins to reduce electrical noise.

1

Red LED

red

One of ten red brake-warning lights.

1

Red LED

red

One of ten red brake-warning lights.

1

Red LED

red

One of ten red brake-warning lights.

1

Red LED

red

One of ten red brake-warning lights.

1

Red LED

red

One of ten red brake-warning lights.

1

Red LED

red

One of ten red brake-warning lights.

1

Red LED

red

One of ten red brake-warning lights.

1

Red LED

red

One of ten red brake-warning lights.

1

Red LED

red

One of ten red brake-warning lights.

1

Red LED

red

One of ten red brake-warning lights.

1

220 Ω resistor

220 Ω

Current limiter for one red brake-warning LED.

1

220 Ω resistor

220 Ω

Current limiter for one red brake-warning LED.

1

220 Ω resistor

220 Ω

Current limiter for one red brake-warning LED.

1

220 Ω resistor

220 Ω

Current limiter for one red brake-warning LED.

1

220 Ω resistor

220 Ω

Current limiter for one red brake-warning LED.

1

220 Ω resistor

220 Ω

Current limiter for one red brake-warning LED.

1

220 Ω resistor

220 Ω

Current limiter for one red brake-warning LED.

1

220 Ω resistor

220 Ω

Current limiter for one red brake-warning LED.

1

220 Ω resistor

220 Ω

Current limiter for one red brake-warning LED.

1

220 Ω resistor

220 Ω

Current limiter for one red brake-warning LED.

1

1 kΩ resistor

1 kΩ

The fixed resistor that prevents the load-cell amplifier gain control from reaching a damaging near-zero resistance.

Assemble it in 8 steps

1. Set the power converter first

With the 9 V battery disconnected, connect battery_9v + to lm2596_5v VIN+ and battery_9v - to VIN-. Use a multimeter to adjust the LM2596 output to exactly 5.0 V before connecting anything else. Connect VOUT+ to the 5V rail and VOUT- to the GND rail.

  • Use a battery pack that can supply at least 1 A; a small rectangular PP3 9 V battery is not suitable for the motor and LED array.
  • Do not connect the ESP32 until the buck output measures 5.0 V — a higher setting can damage the board and sensors.

2. Connect the ESP32 and low-voltage rails

Connect the 5V rail to the ESP32 VIN pin and the GND rail to an ESP32 GND pin. The ESP32 3V3 pin is the 3.3V rail for the Hall-sensor pull-up and the low-voltage side of the level converter.

  • Do not put 5 V on an ESP32 GPIO pin; every ESP32 signal pin uses 3.3 V only.

3. Wire the load-cell measurement path

Connect load_cell_5kg Red/E+ to 5V and Black/E- to GND. Connect Green/S+ to ad620an pin 3 and White/S- to pin 2. Connect AD620 pin 7 to 5V, pins 4 and 5 to GND, and place c_ad620 directly between pins 7 and 4. Connect the gain control as AD620 pin 1 through gain_limit_1k to the gain_pot_5k wiper, then its CCW end to AD620 pin 8. Connect AD620 pin 6 through load_adc_top (20 kΩ) to GPIO34; connect load_adc_bottom (10 kΩ) from that GPIO34 junction to GND.

  • Start with the gain knob turned to its lowest-gain end, then increase it only while watching the displayed force reading.
  • The 20 kΩ and 10 kΩ parts are a required safety divider; removing them can put more than 3.3 V into GPIO34 and damage the ESP32.

4. Wire the fluid and pad-wear sensors

Connect water_sensor + to 5V and - to GND, with c_water across those same two power pins. Connect its S pin through level_adc_top (20 kΩ) to GPIO35, and connect level_adc_bottom (10 kΩ) from the GPIO35 junction to GND. Connect hall_a3144e pin 1 to 5V, pin 2 to GND, and pin 3 to GPIO4. Connect hall_pullup_10k from Hall pin 3 to 3V3, and place c_hall between Hall VCC and GND.

  • Keep the 10 kΩ Hall pull-up connected to 3.3V, not 5V — otherwise the Hall output can damage GPIO4.

5. Wire the LCD through its translator board

Connect i2c_level_shifter HV to 5V, LV to 3V3, and GND to GND. Connect ESP32 GPIO21 to LV1 and GPIO22 to LV2. Connect HV1 to lcd_1602 SDA and HV2 to lcd_1602 SCL. Connect LCD VCC to 5V, LCD GND to GND, and place c_lcd across LCD VCC and GND.

  • If the LCD backlight works but no letters appear, turn the small contrast screw on its backpack slowly.
  • Make sure VCC and GND are not swapped — swapped power can damage the LCD backpack.

6. Build the ten-light brake warning array

For each branch, connect the 5V rail to one led_r1 through led_r10 220 Ω resistor, then to that matching led_1 through led_10 long LED leg. Join all short LED legs to driver_2n2222 collector. Connect its emitter to GND. Connect GPIO16 through base_resistor_1k to the transistor base.

  • Every LED needs its own 220 Ω resistor — sharing one resistor can overheat an LED and makes brightness uneven.
  • Check the 2N2222 lead order from its specific datasheet; TO-92 lead order differs between manufacturers.

7. Build the independent motor circuit

Connect the 5V rail to limit_switch COM, its NO terminal to motor_5v +, and motor_5v - to GND. Put motor_diode_1n4007 directly across the motor: its striped cathode end goes to motor + and its unstriped anode end goes to motor -.

  • The striped diode end must go to the motor's 5V side — reversing it creates a short circuit when the switch closes.
  • The motor is independent of the ESP32: it runs whenever the limit switch closes.

8. Perform the first safe power-up

Inspect every 5V and GND connection, then connect the 9 V battery pack. Confirm the LCD starts, keep hands clear of the motor, and only then connect the ESP32 USB cable for programming.

  • Do not simultaneously feed the ESP32 VIN from the LM2596 and from USB unless your particular DevKit board explicitly supports this; disconnect the battery supply while programming over USB.

Review all connections

1. Connections between "battery_9v" and "ESP32"

Functionbattery_9vESP32
power+ → 24v Buck Converter VIN+EXT
ground- → 24v Buck Converter VIN-EXT

2. Connections between "lm2596_5v" and "ESP32"

Functionlm2596_5vESP32
groundVIN-GND
powerVOUT+5V
groundVOUT-GND

3. Connections between "load_cell_5kg" and "ESP32"

Functionload_cell_5kgESP32
powerE+5V
groundE-GND
analogA+ → AD620AN instrumentation amplifier (DIP-8) 3 +INEXT
analogA- → AD620AN instrumentation amplifier (DIP-8) 2 -INEXT

4. Connections between "ad620an" and "ESP32"

Functionad620anESP32
power7 VS+5V
ground4 VS-GND
ground5 REFGND
data8 RG → 5 kΩ rotary potentiometer CCWEXT
analog6 OUT → 20 kΩ resistor AEXT
data1 RG → 1 kΩ resistor AEXT

5. Connections between "load_adc_bottom" and "ESP32"

Functionload_adc_bottomESP32
groundBGND
analogA → 20 kΩ resistor BEXT

6. Connections between "water_sensor" and "ESP32"

Functionwater_sensorESP32
power+5V
ground-GND
analogS → 20 kΩ resistor AEXT

7. Connections between "level_adc_bottom" and "ESP32"

Functionlevel_adc_bottomESP32
groundBGND
analogA → 20 kΩ resistor BEXT

8. Connections between "hall_a3144e" and "ESP32"

Functionhall_a3144eESP32
power1 VCC5V
ground2 GNDGND
digital3 OUTGPIO 4

9. Connections between "hall_pullup_10k" and "ESP32"

Functionhall_pullup_10kESP32
powerB3V3
dataA → A3144E Hall-effect sensor (TO-92) 3 OUTEXT

10. Connections between "lcd_1602" and "ESP32"

Functionlcd_1602ESP32
powerVCC5V
groundGNDGND
i2cSDA → 4-channel bidirectional logic-level converter HV1EXT
i2cSCL → 4-channel bidirectional logic-level converter HV2EXT

11. Connections between "i2c_level_shifter" and "ESP32"

Functioni2c_level_shifterESP32
powerHV5V
powerLV3V3
groundGNDGND
i2cLV1GPIO 21
i2cLV2GPIO 22

12. Connections between "base_resistor_1k" and "ESP32"

Functionbase_resistor_1kESP32
dataAGPIO 16
dataB → NPN Transistor (2N2222 / BC547) BASEEXT

13. Connections between "driver_2n2222" and "ESP32"

Functiondriver_2n2222ESP32
groundEMITTERGND

14. Connections between "limit_switch" and "ESP32"

Functionlimit_switchESP32
powerCOM5V
dataNO → 3–12 V DC motor +EXT

15. Connections between "motor_5v" and "ESP32"

Functionmotor_5vESP32
ground-GND

16. Connections between "motor_diode_1n4007" and "ESP32"

Functionmotor_diode_1n4007ESP32
powerCathode → 3–12 V DC motor +EXT
powerAnode → 3–12 V DC motor -EXT

17. Connections between "c_ad620" and "ESP32"

Functionc_ad620ESP32
power15V
ground2GND

18. Connections between "c_hall" and "ESP32"

Functionc_hallESP32
power15V
ground2GND

19. Connections between "c_water" and "ESP32"

Functionc_waterESP32
power15V
ground2GND

20. Connections between "c_lcd" and "ESP32"

Functionc_lcdESP32
power15V
ground2GND

21. Connections between "led_r1" and "ESP32"

Functionled_r1ESP32
powerA5V
dataB → Red LED ANODEEXT

22. Connections between "led_1" and "ESP32"

Functionled_1ESP32
groundCATHODE → NPN Transistor (2N2222 / BC547) COLLECTOREXT

23. Connections between "led_r2" and "ESP32"

Functionled_r2ESP32
powerA5V
dataB → Red LED ANODEEXT

24. Connections between "led_2" and "ESP32"

Functionled_2ESP32
groundCATHODE → NPN Transistor (2N2222 / BC547) COLLECTOREXT

25. Connections between "led_r3" and "ESP32"

Functionled_r3ESP32
powerA5V
dataB → Red LED ANODEEXT

26. Connections between "led_3" and "ESP32"

Functionled_3ESP32
groundCATHODE → NPN Transistor (2N2222 / BC547) COLLECTOREXT

27. Connections between "led_r4" and "ESP32"

Functionled_r4ESP32
powerA5V
dataB → Red LED ANODEEXT

28. Connections between "led_4" and "ESP32"

Functionled_4ESP32
groundCATHODE → NPN Transistor (2N2222 / BC547) COLLECTOREXT

29. Connections between "led_r5" and "ESP32"

Functionled_r5ESP32
powerA5V
dataB → Red LED ANODEEXT

30. Connections between "led_5" and "ESP32"

Functionled_5ESP32
groundCATHODE → NPN Transistor (2N2222 / BC547) COLLECTOREXT

31. Connections between "led_r6" and "ESP32"

Functionled_r6ESP32
powerA5V
dataB → Red LED ANODEEXT

32. Connections between "led_6" and "ESP32"

Functionled_6ESP32
groundCATHODE → NPN Transistor (2N2222 / BC547) COLLECTOREXT

33. Connections between "led_r7" and "ESP32"

Functionled_r7ESP32
powerA5V
dataB → Red LED ANODEEXT

34. Connections between "led_7" and "ESP32"

Functionled_7ESP32
groundCATHODE → NPN Transistor (2N2222 / BC547) COLLECTOREXT

35. Connections between "led_r8" and "ESP32"

Functionled_r8ESP32
powerA5V
dataB → Red LED ANODEEXT

36. Connections between "led_8" and "ESP32"

Functionled_8ESP32
groundCATHODE → NPN Transistor (2N2222 / BC547) COLLECTOREXT

37. Connections between "led_r9" and "ESP32"

Functionled_r9ESP32
powerA5V
dataB → Red LED ANODEEXT

38. Connections between "led_9" and "ESP32"

Functionled_9ESP32
groundCATHODE → NPN Transistor (2N2222 / BC547) COLLECTOREXT

39. Connections between "led_r10" and "ESP32"

Functionled_r10ESP32
powerA5V
dataB → Red LED ANODEEXT

40. Connections between "led_10" and "ESP32"

Functionled_10ESP32
groundCATHODE → NPN Transistor (2N2222 / BC547) COLLECTOREXT

41. Connections between "load_adc_top" and "ESP32"

Functionload_adc_topESP32
analogBGPIO 34

42. Connections between "level_adc_top" and "ESP32"

Functionlevel_adc_topESP32
analogBGPIO 35

43. Connections between "gain_limit_1k" and "ESP32"

Functiongain_limit_1kESP32
dataB → 5 kΩ rotary potentiometer WIPEREXT

Deploy the firmware

#include <Arduino.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

constexpr int LOAD_ADC_PIN = 34;
constexpr int LEVEL_ADC_PIN = 35;
constexpr int HALL_PIN = 4;
constexpr int BRAKE_LED_PIN = 16;
constexpr int I2C_SDA_PIN = 21;
constexpr int I2C_SCL_PIN = 22;
constexpr uint8_t LCD_ADDRESS = 0x27;
constexpr uint32_t SAMPLE_INTERVAL_MS = 250;
constexpr int BRAKE_FORCE_ALERT_RAW = 1800;
constexpr int LOW_FLUID_PERCENT = 25;

LiquidCrystal_I2C lcd(LCD_ADDRESS, 16, 2);
uint32_t lastSampleMs = 0;
char previousLine1[17] = "";
char previousLine2[17] = "";

int readAverage(int pin) {
  constexpr int samples = 8;
  uint32_t total = 0;
  for (int i = 0; i < samples; ++i) {
    total += analogRead(pin);
  }
  return total / samples;
}

void updateDisplay(const char *line1, const char *line2) {
  if (strcmp(line1, previousLine1) != 0) {
    lcd.setCursor(0, 0);
    lcd.print("                ");
    lcd.setCursor(0, 0);
    lcd.print(line1);
    strncpy(previousLine1, line1, 16);
    previousLine1[16] = '\0';
  }
  if (strcmp(line2, previousLine2) != 0) {
    lcd.setCursor(0, 1);
    lcd.print("                ");
    lcd.setCursor(0, 1);
    lcd.print(line2);
    strncpy(previousLine2, line2, 16);
    previousLine2[16] = '\0';
  }
}

void setup() {
  Serial.begin(115200);
  pinMode(HALL_PIN, INPUT);
  pinMode(BRAKE_LED_PIN, OUTPUT);
  digitalWrite(BRAKE_LED_PIN, LOW);

  analogReadResolution(12);
  analogSetPinAttenuation(LOAD_ADC_PIN, ADC_11db);
  analogSetPinAttenuation(LEVEL_ADC_PIN, ADC_11db);

  Wire.begin(I2C_SDA_PIN, I2C_SCL_PIN);
  lcd.init();
  lcd.backlight();
  updateDisplay("Brake telemetry", "Starting...");
}

void loop() {
  const uint32_t now = millis();
  if (now - lastSampleMs < SAMPLE_INTERVAL_MS) {
    return;
  }
  lastSampleMs = now;

  const int forceRaw = readAverage(LOAD_ADC_PIN);
  const int levelRaw = readAverage(LEVEL_ADC_PIN);
  const int fluidPercent = constrain(map(levelRaw, 0, 4095, 0, 100), 0, 100);
  const bool padWearAlert = digitalRead(HALL_PIN) == LOW;
  const bool forceAlert = forceRaw >= BRAKE_FORCE_ALERT_RAW;
  const bool fluidAlert = fluidPercent <= LOW_FLUID_PERCENT;
  const bool brakeAlert = forceAlert || fluidAlert || padWearAlert;

  digitalWrite(BRAKE_LED_PIN, brakeAlert ? HIGH : LOW);

  char line1[17];
  char line2[17];
  snprintf(line1, sizeof(line1), "Force:%4d %s", forceRaw, forceAlert ? "!" : " ");
  if (fluidAlert) {
    snprintf(line2, sizeof(line2), "FLUID LOW %3d%%", fluidPercent);
  } else if (padWearAlert) {
    snprintf(line2, sizeof(line2), "PAD WEAR ALERT ");
  } else {
    snprintf(line2, sizeof(line2), "Fluid:%3d%% OK", fluidPercent);
  }
  updateDisplay(line1, line2);

  Serial.printf("force_raw=%d, fluid=%d%%, pad_wear=%s, alert=%s\n",
                forceRaw, fluidPercent, padWearAlert ? "YES" : "NO",
                brakeAlert ? "YES" : "NO");
}

Remix this project

Make it yours in one click

Open a full copy of this project in your own Schematik workspace — diagram, code, parts, and assembly steps included. Swap the sensor, add features, or redesign the whole thing with AI. The author's original stays untouched.

Open in Schematik