Community project

Hydraulic Brake Telemetry Station

ESP32
Photo of Hydraulic Brake Telemetry Station
Generated with AI

Mohamed Gad

Published October 16, 2026

This hydraulic brake telemetry station monitors brake system health in real time using an ESP32 microcontroller. It measures brake force through a load cell and instrumentation amplifier, tracks hydraulic fluid level with a water level sensor, and detects brake pad wear using a Hall effect sensor. The system displays all readings on a 16x2 LCD screen, providing immediate feedback on brake performance and maintenance needs.

Builders will receive a complete wiring diagram showing power distribution from a 9V battery through a 24V buck converter, detailed schematics for the force and fluid sensing circuits with their respective voltage dividers, step-by-step assembly instructions, and ready-to-upload Arduino firmware. The guide includes a safe bench demonstrator setup for testing before integration into a vehicle system.

Wiring diagram

Wiring diagram for Hydraulic Brake Telemetry Station

Gather all the parts

QtyComponent
1

9V Battery

Standard PP3 9 V alkaline battery (~500 mAh). Convenient for short-lived Arduino Uno projects via VIN; very inefficient for high-current loads or 3.3 V boards.

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 small precision amplifier that raises the load cell's tiny force signal to a level the ESP32 can measure.

1

100 nF Ceramic Decoupling Capacitor

A small capacitor placed beside the AD620 supply pins to reduce electrical noise.

1

5 kΩ Rotary Potentiometer

An adjustable resistor used to set the load-cell amplifier gain during careful calibration.

1

Resistor

150 Ω, 1/4 W

Through-hole resistor (current-limiting in series with an LED)

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

Fluid ADC Divider Upper Resistor

10 kΩ, 1/4 W

The upper 10 kΩ resistor that scales the water-level sensor output to a safe ESP32 analog-input voltage.

1

Fluid ADC Divider Lower Resistor

20 kΩ, 1/4 W

The lower 20 kΩ resistor that completes the fluid-signal divider to ground.

1

Force ADC Divider Upper Resistor

10 kΩ, 1/4 W

The upper 10 kΩ resistor that scales the AD620 output down to a safe ESP32 analog-input voltage.

1

Force ADC Divider Lower Resistor

20 kΩ, 1/4 W

The lower 20 kΩ resistor that completes the force-signal divider to ground.

1

A3144E Hall-Effect Sensor (TO-92)

A magnetic on/off sensor that reports brake-pad wear target position without touching it.

1

Hall Output Pull-Up Resistor

10 kΩ, 1/4 W

A 10 kΩ resistor that holds the hall-sensor signal at a safe 3.3 V when no magnet is detected.

1

LCD 16x2 I2C

16x2 character LCD display with I2C backpack

1

BSS138 Logic Level Shifter

Common BSS138 MOSFET-based 4-channel bidirectional logic level converter module. Good for I2C, UART, and slow digital signals between 3.3V and 5V domains; not a strong high-speed SPI/LED data buffer.

1

Micro Switch - Premium Zippy 3-Terminal

Higher-quality 3-terminal bump-actuator microswitch for arcade controls and light mechatronics, rated 30 VDC / 250 mA max. Common, normally-open, and normally-closed contacts.

1

5 V Brushed DC Motor

A two-wire 5 V motor switched directly by the brake pedal limit switch.

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

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

Resistor

1 kΩ, 1/4 W

Through-hole resistor (current-limiting in series with an LED)

10

LED

Red, 5 mm

Standard 3mm/5mm through-hole LED. A current-limiting series resistor is added automatically.

10

Resistor

220 Ω, 1/4 W

Through-hole resistor (current-limiting in series with an LED)

Assemble it in 8 steps

1. Set the 5 V supply before connecting electronics

Connect battery_9v positive to buck_5v VIN+ and battery negative to buck_5v VIN-. With only the battery and buck converter connected, turn the small LM2596 adjustment screw until a meter reads 5.00 V between VOUT+ and VOUT-. This creates the 5 V rail (power) and VOUT- is the common ground rail (ground).

  • Measure the voltage again after each small adjustment; the screw is sensitive.
  • Do not connect the ESP32, LCD, sensors, or motor until the buck converter measures 5.00 V — a higher setting can damage 5 V parts and the ESP32 VIN input.

2. Connect the ESP32 power rails

Connect buck_5v VOUT+ to the ESP32 VIN pin (power) and buck_5v VOUT- to an ESP32 GND pin (ground). Use the ESP32 3V3 pin only as the 3.3 V logic rail for the hall pull-up and level shifter; do not connect 5 V to 3V3.

  • Never swap VIN and GND, and never put the 5 V rail on the ESP32 3V3 pin — either mistake can damage the board.

3. Wire the force sensor and protected force input

Connect load_cell_5kg red E+ to 5 V (power), black E- to GND (ground), green A+/S+ to ad620an Pin 3 +IN (signal), and white A-/S- to Pin 2 -IN (signal). Connect ad620an Pin 7 VS+ to 5 V (power), Pin 4 VS- and Pin 5 REF to GND (ground). Put ad620_decouple directly from Pin 7 to Pin 4 (noise filtering). Tie the gain_pot_5k wiper to End A; connect that pair to Pin 1 RG. Connect the other pot end through gain_limit_150r to Pin 8 RG. Connect Pin 6 OUT through force_divider_top 10 kΩ to the FORCE_ADC junction; connect that junction to force_divider_bottom 20 kΩ to GND and to ESP32 GPIO34 (signal).

  • Keep the load-cell signal wires short and away from the motor wires. Turn the gain control to its highest-resistance end before applying force, then increase gain slowly while watching the LCD.
  • The AD620 gain network can amplify a tiny load-cell signal strongly; do not turn the potentiometer to near-zero resistance, because that can make the amplifier saturate. The divider is required — GPIO34 must never see 5 V.

4. Wire the brake-fluid level input

Connect water_level + to 5 V (power) and - to GND (ground). Connect its S output through water_divider_top 10 kΩ to the FLUID_ADC junction. From that junction connect water_divider_bottom 20 kΩ to GND and a wire to ESP32 GPIO35 (signal).

  • GPIO35 must receive the divided signal only — connecting the 5 V sensor output directly can damage the ESP32. Keep the exposed water-sensor traces away from actual brake fluid; use this hobby sensor only as a level demonstrator, not in a hydraulic brake reservoir.

5. Wire the pad-wear hall sensor

With the flat face of a typical TO-92 A3144E toward you and its leads pointing down, verify the package marking for your exact part before wiring. Connect Pin 1 VCC to 5 V (power), Pin 2 GND to GND (ground), and Pin 3 OUT to ESP32 GPIO4 (signal). Connect hall_pullup 10 kΩ between the same OUT/GPIO4 signal and ESP32 3V3 (signal pull-up).

  • Bring the magnet close to the labeled face of the sensor and check that the LCD changes from WEAR! to PAD OK.
  • Do not connect the pull-up resistor to 5 V — GPIO4 is a 3.3 V-only ESP32 input. Pin order varies among look-alike TO-92 sensors, so confirm the A3144E data sheet marking before soldering.

6. Wire the LCD through the level shifter

Connect level_shifter HV to 5 V (power), LV to ESP32 3V3 (power), and GND to the common ground rail (ground). Connect ESP32 GPIO21 to LV1 (data), HV1 to lcd1602 SDA (data), ESP32 GPIO22 to LV2 (data), and HV2 to lcd1602 SCL (data). Connect lcd1602 VCC to 5 V (power) and GND to GND (ground).

  • Make sure VCC and GND are not swapped — swapped power can damage the LCD. The common PCF8574 LCD address is 0x27; if the screen stays blank but the backlight is on, your backpack may instead use 0x3F.

7. Build the independent pedal motor and brake-light wiring

Connect limit_switch COM to 5 V (power). Connect NC to motor_5v Motor + (power), and Motor - to GND (ground), so the motor runs when the pedal switch is released. Connect flyback_diode cathode, the end marked with a stripe, to Motor + and its anode to Motor - (protection). Connect NO only through base_resistor 1 kΩ to transistor_2n2222 BASE. Connect its EMITTER to GND and COLLECTOR to the joined LED cathodes. For each of the 10 brake LEDs, connect its anode through its own 220 Ω resistor to 5 V; join all cathodes at the transistor collector.

  • The stripe on the 1N4007 must face the motor positive terminal — reversing it removes the motor-spike protection. Every LED needs its own 220 Ω resistor; do not share one resistor across all ten LEDs. Verify the actual motor's running and stall current is below the switch, 1N4007, battery, and LM2596 ratings.

8. Test the safe bench demonstrator

Keep this circuit off any vehicle brake system. First test the pedal switch with the motor shaft clear and the LEDs visible: released should run the motor with LEDs off; pressed should stop the motor with LEDs on. Then power the ESP32 and check the LCD readings and hall-sensor response.

  • This is a low-voltage educational monitoring demonstrator, not a roadworthy or safety-certified hydraulic-brake controller. A rectangular 9 V PP3 battery is often too weak for a motor plus ten LEDs and may sag or heat; use a current-capable 9 V source for bench testing if it cannot hold the regulated 5 V rail.

Review all connections

1. Connections between "battery_9v" and "ESP32"

Functionbattery_9vESP32
power+9V → 24v Buck Converter VIN+EXT
groundGND → 24v Buck Converter VIN-EXT

2. Connections between "buck_5v" and "ESP32"

Functionbuck_5vESP32
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) Pin 3 +INEXT
analogA- → AD620AN Instrumentation Amplifier (DIP-8) Pin 2 -INEXT

4. Connections between "ad620an" and "ESP32"

Functionad620anESP32
powerPin 7 VS+5V
groundPin 4 VS-GND
groundPin 5 REFGND
analogPin 6 OUT → Force ADC Divider Upper Resistor P1EXT

5. Connections between "ad620_decouple" and "ESP32"

Functionad620_decoupleESP32
powerPin 1 → AD620AN Instrumentation Amplifier (DIP-8) Pin 7 VS+EXT
groundPin 2 → AD620AN Instrumentation Amplifier (DIP-8) Pin 4 VS-EXT

6. Connections between "gain_pot_5k" and "ESP32"

Functiongain_pot_5kESP32
analogEnd A → AD620AN Instrumentation Amplifier (DIP-8) Pin 1 RGEXT
analogWiper → AD620AN Instrumentation Amplifier (DIP-8) Pin 1 RGEXT
analogEnd B → Resistor P1EXT

7. Connections between "gain_limit_150r" and "ESP32"

Functiongain_limit_150rESP32
digitalP2 → AD620AN Instrumentation Amplifier (DIP-8) Pin 8 RGEXT

8. Connections between "force_divider_top" and "ESP32"

Functionforce_divider_topESP32
analogP2 → Force ADC Divider Lower Resistor P1EXT

9. Connections between "force_divider_bottom" and "ESP32"

Functionforce_divider_bottomESP32
analogP1GPIO 34
groundP2GND

10. Connections between "water_level" and "ESP32"

Functionwater_levelESP32
power+5V
ground-GND
analogS → Fluid ADC Divider Upper Resistor P1EXT

11. Connections between "water_divider_top" and "ESP32"

Functionwater_divider_topESP32
analogP2 → Fluid ADC Divider Lower Resistor P1EXT

12. Connections between "water_divider_bottom" and "ESP32"

Functionwater_divider_bottomESP32
analogP1GPIO 35
groundP2GND

13. Connections between "a3144e" and "ESP32"

Functiona3144eESP32
powerPin 1 VCC5V
groundPin 2 GNDGND
digitalPin 3 OUTGPIO 4

14. Connections between "hall_pullup" and "ESP32"

Functionhall_pullupESP32
powerP13V3
digitalP2 → A3144E Hall-Effect Sensor (TO-92) Pin 3 OUTEXT

15. Connections between "level_shifter" and "ESP32"

Functionlevel_shifterESP32
powerLV3V3
powerHV5V
groundGNDGND
digitalLV1GPIO 21
digitalHV1 → LCD 16x2 I2C SDAEXT
digitalLV2GPIO 22
digitalHV2 → LCD 16x2 I2C SCLEXT

16. Connections between "lcd1602" and "ESP32"

Functionlcd1602ESP32
powerVCC5V
groundGNDGND

17. Connections between "limit_switch" and "ESP32"

Functionlimit_switchESP32
powerCOM5V
digitalNC → 5 V Brushed DC Motor Motor +EXT
digitalNO → Resistor P1EXT

18. Connections between "motor_5v" and "ESP32"

Functionmotor_5vESP32
groundMotor -GND

19. Connections between "flyback_diode" and "ESP32"

Functionflyback_diodeESP32
powerCathode → 5 V Brushed DC Motor Motor +EXT
powerAnode → 5 V Brushed DC Motor Motor -EXT

20. Connections between "base_resistor" and "ESP32"

Functionbase_resistorESP32
digitalP2 → NPN Transistor (2N2222 / BC547) BASEEXT

21. Connections between "transistor_2n2222" and "ESP32"

Functiontransistor_2n2222ESP32
groundEMITTERGND
digitalCOLLECTOR → LED GNDEXT

22. Connections between "led_resistors" and "ESP32"

Functionled_resistorsESP32
powerP15V
digitalP2 → LED ANODEEXT

Deploy the firmware

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

// Wiring labels: GPIO34 = FORCE_ADC, GPIO35 = FLUID_ADC,
// GPIO4 = PAD_WEAR_HALL, GPIO21 = I2C_SDA, GPIO22 = I2C_SCL.
constexpr uint8_t FORCE_ADC_PIN = 34;
constexpr uint8_t FLUID_ADC_PIN = 35;
constexpr uint8_t HALL_PIN = 4;
constexpr uint8_t I2C_SDA_PIN = 21;
constexpr uint8_t I2C_SCL_PIN = 22;
constexpr uint8_t LCD_ADDRESS = 0x27;
constexpr uint32_t SCREEN_INTERVAL_MS = 250;

LiquidCrystal_I2C lcd(LCD_ADDRESS, 16, 2);

uint16_t readAverage(uint8_t pin) {
  uint32_t total = 0;
  for (uint8_t i = 0; i < 16; ++i) total += analogRead(pin);
  return total / 16;
}

void showStatus(uint16_t forceRaw, uint16_t fluidRaw, bool magnetDetected) {
  const uint8_t forcePercent = constrain(map(forceRaw, 0, 4095, 0, 100), 0, 100);
  const uint8_t fluidPercent = constrain(map(fluidRaw, 0, 4095, 0, 100), 0, 100);
  lcd.setCursor(0, 0);
  lcd.printf("Force:%3u%%     ", forcePercent);
  lcd.setCursor(0, 1);
  lcd.printf("Fluid:%3u%% %s", fluidPercent, magnetDetected ? "PAD OK" : "WEAR!");
}

void setup() {
  Serial.begin(115200);
  pinMode(HALL_PIN, INPUT);  // The external 10 kΩ resistor pulls this line to 3.3 V.
  analogReadResolution(12);
  analogSetPinAttenuation(FORCE_ADC_PIN, ADC_11db);
  analogSetPinAttenuation(FLUID_ADC_PIN, ADC_11db);
  Wire.begin(I2C_SDA_PIN, I2C_SCL_PIN);
  lcd.init();
  lcd.backlight();
  lcd.setCursor(0, 0);
  lcd.print("Brake Monitor");
  lcd.setCursor(0, 1);
  lcd.print("Starting...     ");
  delay(1000);
  lcd.clear();
}

void loop() {
  static uint32_t lastScreenUpdate = 0;
  const uint32_t now = millis();
  if (now - lastScreenUpdate < SCREEN_INTERVAL_MS) return;
  lastScreenUpdate = now;
  const uint16_t forceRaw = readAverage(FORCE_ADC_PIN);
  const uint16_t fluidRaw = readAverage(FLUID_ADC_PIN);
  const bool magnetDetected = digitalRead(HALL_PIN) == LOW;
  showStatus(forceRaw, fluidRaw, magnetDetected);
  Serial.printf("force=%u fluid=%u pad=%s\n", forceRaw, fluidRaw,
                magnetDetected ? "OK" : "WEAR");
}

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