Skip to content

ESP32 Force Sensitive Resistor (FSR) pressure sensor project with multi-sensor support and auto-diagnostics

Notifications You must be signed in to change notification settings

indigo14/esp32-fsr-pressure-sensor

Repository files navigation

ESP32 FSR (Force Sensitive Resistor) Sensor Reader

Simple firmware for reading force/pressure data from an FSR sensor using ESP32 and Arduino IDE.

Features

  • Smooth readings with Exponential Moving Average (EMA) filter
  • Multi-sample averaging for noise reduction
  • Real-time data output via serial monitor
  • Automatic calculations for voltage, resistance, conductance, and relative force
  • Optimized for GPIO34 (ADC1 channel, works with WiFi enabled)

Hardware Requirements

Components

Component Specification Notes
ESP32 Dev Board Any ESP32 board ESP32-WROOM, DevKit V1, NodeMCU-32S, etc.
FSR Sensor Force Sensitive Resistor Interlink FSR402, FSR406, or similar
Fixed Resistor 10kΩ (±5%) Pull-down resistor for voltage divider
Breadboard Standard size For prototyping
Jumper Wires Male-to-male 3 wires minimum
USB Cable Data cable Must support data transfer (not charge-only)
Optional: Capacitor 0.1µF (100nF) For additional noise filtering

Circuit Diagram

Voltage Divider Configuration

       ESP32

      +3.3V ────┬──── FSR ────┬──── 10kΩ Resistor ──── GND
                │              │
                │              └──── GPIO34 (ADC1_CH6)
                │              │
                │         [Optional: 0.1µF capacitor to GND]

Breadboard Wiring

  1. Connect FSR:

    • One leg to ESP32 3.3V pin
    • Other leg to GPIO34 pin
  2. Connect 10kΩ resistor:

    • One leg to GPIO34 pin (same point as FSR)
    • Other leg to GND pin
  3. Optional - Add capacitor for filtering:

    • Connect 0.1µF capacitor between GPIO34 and GND

Pin Reference

ESP32 Pin Connection Purpose
3.3V FSR (one side) Power supply
GPIO34 FSR + 10kΩ junction Analog input (ADC1_CH6)
GND 10kΩ resistor Ground reference

Important Notes:

  • GPIO34 is input-only - perfect for analog sensors
  • GPIO34 is on ADC1, so it works even when WiFi is enabled
  • Do NOT exceed 3.3V on GPIO34 (ESP32 is not 5V tolerant!)

Visual Diagram

   ┌──────────────────┐
   │                  │
   │    ESP32 Board   │
   │                  │
   │  ┌────────────┐  │
   │  │   GPIO34   │◄─┼──┬─── [FSR] ─── 3.3V
   │  └────────────┘  │  │
   │                  │  │
   │  ┌────────────┐  │  │
   │  │    GND     │◄─┼──┴─── [10kΩ] ───┘
   │  └────────────┘  │
   │                  │
   │  ┌────────────┐  │
   │  │   USB Port │◄─┼─── USB Cable ─── Computer
   │  └────────────┘  │
   │                  │
   └──────────────────┘

Software Setup

Prerequisites

Before uploading the firmware, ensure you have:

  1. USB Driver installed (CP2102 or CH340)
  2. Arduino IDE installed (version 1.8.19+ or 2.x)
  3. ESP32 board support installed in Arduino IDE
  4. Correct board and port selected

Need help? See SETUP.md for detailed driver and Arduino IDE installation instructions.

Quick Setup Summary

  1. Install USB driver (see SETUP.md)
  2. Open Arduino IDE
  3. Add ESP32 board URL:
    • File → Preferences
    • Add: https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json
  4. Install ESP32 boards:
    • Tools → Board → Boards Manager
    • Search "esp32", install "esp32 by Espressif Systems"
  5. Select board:
    • Tools → Board → ESP32 Arduino → ESP32 Dev Module
  6. Select port:
    • Tools → Port → COM# (your port)

Installation & Usage

1. Upload Firmware

  1. Connect ESP32 to computer via USB
  2. Open fsr_reader.ino in Arduino IDE
  3. Select board: Tools → Board → ESP32 Dev Module
  4. Select port: Tools → Port → COM# (your port number)
  5. Set upload speed: Tools → Upload Speed → 115200
  6. Click Upload button (→ arrow icon)
  7. Wait for "Done uploading" message

Troubleshooting upload issues: See SETUP.md - Common Upload Issues section

2. Open Serial Monitor

  1. Open Serial Monitor: Tools → Serial Monitor (or Ctrl + Shift + M)
  2. Set baud rate to 115200 (dropdown at bottom-right)
  3. Set line ending to "Both NL & CR" or "Newline" (optional)

3. View Data

You should see output like this:

========================================
  ESP32 FSR Sensor Reader
========================================
Pin: GPIO34 (ADC1_CH6)
Fixed Resistor: 10kΩ
Filter: Exponential Moving Average
========================================

Raw ADC	Smoothed	Voltage(V)	FSR Res(Ω)	Conductance(µS)	Force(%)
-------	--------	----------	----------	--------------	--------
45	48.2		[No pressure detected]
52	49.8		[No pressure detected]
1203	845.3		0.687		3925		254.78		42.3
2156	1567.2		1.273		15890		62.93		18.5
3421	2894.7		2.351		38234		26.15		5.2

4. Interpret the Data

Column Description Usage
Raw ADC Instantaneous ADC reading (0-4095) Shows sensor noise/variation
Smoothed Filtered value using EMA Stable reading, use this for decisions
Voltage(V) Measured voltage at GPIO34 (0-3.3V) Useful for circuit verification
FSR Res(Ω) Calculated FSR resistance Lower = more pressure applied
Conductance(µS) Inverse of resistance Higher = more pressure (easier to interpret)
Force(%) Estimated relative force (0-100%) Simplified pressure indication

FSR Resistance Guide:

  • >100kΩ - No pressure / very light touch
  • 10kΩ - 100kΩ - Light pressure
  • 1kΩ - 10kΩ - Medium pressure
  • <1kΩ - Heavy pressure

Configuration & Customization

All configuration parameters are at the top of fsr_reader.ino:

Adjust Sensitivity

Change pressure detection threshold:

const int PRESSURE_THRESHOLD = 50;  // Increase to ignore light touches

Adjust smoothing (filter responsiveness):

const float ALPHA = 0.15;  // Range: 0.0 to 1.0
                           // Lower = smoother but slower response
                           // Higher = more responsive but noisier

Modify sampling:

const int NUM_SAMPLES = 15;  // More samples = smoother but slower
                             // Fewer samples = faster but noisier

Change Reading Speed

In the loop() function:

delay(100);  // Change this value
             // 100 = 10 readings/second
             // 50 = 20 readings/second
             // 1000 = 1 reading/second

Calibrate for Accuracy

Measure actual 3.3V rail:

const float V_REF = 3.3;  // Change to measured voltage (e.g., 3.28)

Verify fixed resistor value:

const int R_FIXED = 10000;  // Change if using different resistor
                            // e.g., 4700 for 4.7kΩ

Advanced Usage

Data Logging

Output can be easily parsed for data logging:

Python example to capture data:

import serial
import csv

ser = serial.Serial('COM3', 115200)  # Change COM port
with open('fsr_data.csv', 'w', newline='') as file:
    writer = csv.writer(file)
    while True:
        line = ser.readline().decode('utf-8').strip()
        print(line)
        # Parse and write to CSV

Trigger Actions Based on Force

Add code in loop() after force calculation:

// Example: Turn on LED when force exceeds 50%
const int LED_PIN = 2;

if (force > 50) {
    digitalWrite(LED_PIN, HIGH);
} else {
    digitalWrite(LED_PIN, LOW);
}

WiFi/Bluetooth Integration

The code uses ADC1 (GPIO34), so WiFi and Bluetooth work without conflicts:

#include <WiFi.h>

// Add to setup():
WiFi.begin("YourSSID", "YourPassword");

// Add to loop() to send data over WiFi
// ... your WiFi code here ...

Troubleshooting

No Data / Only Zeros

Causes & Solutions:

Problem Check Solution
Wiring error Verify connections Recheck circuit diagram
Wrong pin Using wrong GPIO Ensure using GPIO34, not D34 label
Bad FSR FSR might be damaged Test FSR with multimeter
No Serial Monitor Forgot to open monitor Tools → Serial Monitor
Wrong baud rate Serial mismatch Set to 115200 in Serial Monitor

Always Shows "No pressure detected"

Solutions:

  1. Lower threshold:
    const int PRESSURE_THRESHOLD = 20;  // Try lower value
  2. Check FSR orientation - FSR might be connected backwards (shouldn't matter, but try flipping)
  3. Verify FSR works - Measure resistance with multimeter while pressing

Noisy/Jumpy Readings

Solutions:

  1. Increase smoothing:
    const float ALPHA = 0.1;  // Lower = smoother (was 0.15)
  2. More samples:
    const int NUM_SAMPLES = 25;  // Increase from 15
  3. Add hardware filter - Install 0.1µF capacitor between GPIO34 and GND
  4. Check wiring - Loose connections cause noise
  5. Use shorter wires - Long wires act as antennas picking up interference

Readings Saturate (Always ~4095)

Causes:

  • FSR or resistor value mismatch
  • FSR always compressed

Solutions:

  1. Check resistor value - Verify it's 10kΩ, not 10Ω or 100kΩ
  2. Try different resistor - Use 4.7kΩ or 22kΩ instead
  3. Verify FSR is not stuck pressed

Upload Fails

See SETUP.md - "Common Upload Issues & Solutions"


Circuit Validation

Test with Multimeter

Verify voltage divider:

  1. No pressure applied:

    • Measure voltage at GPIO34: Should be close to 0V
    • Measure FSR resistance: Should be >100kΩ
  2. Light pressure applied:

    • Measure voltage at GPIO34: Should be 0.5V - 2.0V
    • Measure FSR resistance: Should be 1kΩ - 50kΩ
  3. Heavy pressure applied:

    • Measure voltage at GPIO34: Should be 2.0V - 3.1V
    • Measure FSR resistance: Should be <1kΩ

Voltage NOT in expected range?

  • Check resistor value (should be 10kΩ, color code: Brown-Black-Orange)
  • Verify 3.3V power supply is present
  • Check for short circuits or bad connections

Understanding the Code

Key Functions

setup()

  • Initializes serial communication (115200 baud)
  • Configures ADC for 0-3.3V range (11dB attenuation)
  • Sets 12-bit resolution (0-4095)
  • Prints startup information

loop()

  • Reads sensor with averaging
  • Applies exponential moving average filter
  • Calculates voltage, resistance, conductance, and force
  • Prints formatted data to serial monitor
  • Repeats every 100ms (10 Hz)

averageRead()

  • Takes multiple ADC samples (reduces noise)
  • Returns average value
  • Adds small delays between samples for stability

calculateFSRResistance()

  • Converts measured voltage to FSR resistance
  • Uses voltage divider formula
  • Handles edge cases (short/open circuit)

estimateForce()

  • Converts resistance to 0-100% force estimate
  • Uses logarithmic mapping (FSRs respond logarithmically)
  • Simplified model - calibrate for accurate force measurement

How the Filter Works

Exponential Moving Average (EMA):

smoothedValue = (ALPHA * rawValue) + ((1.0 - ALPHA) * smoothedValue);
  • ALPHA = 0.15 means 15% new data, 85% old data
  • Removes high-frequency noise while preserving trends
  • Fast and memory-efficient (no arrays needed)
  • Adjust ALPHA to tune responsiveness vs smoothness

Calibration for Accurate Force Measurement

The estimateForce() function provides a simplified estimate. For accurate force measurement:

Step 1: Collect Calibration Data

  1. Apply known weights to FSR (e.g., 100g, 200g, 500g, 1kg)
  2. Record resistance for each weight
  3. Create lookup table or fit curve

Step 2: Update Force Calculation

Replace the logarithmic approximation with your calibration data:

float estimateForce(float resistance) {
    // Example calibration data (replace with your measurements)
    if (resistance > 50000) return 0;      // 0g
    if (resistance > 10000) return 100;    // 100g
    if (resistance > 3000) return 250;     // 250g
    if (resistance > 1000) return 500;     // 500g
    if (resistance > 500) return 1000;     // 1kg
    return 2000;  // >2kg
}

Or use interpolation for smooth curve fitting.


Performance Notes

  • Reading rate: ~10 Hz (100ms delay)
  • Filter lag: ~500ms to stabilize (depends on ALPHA)
  • Memory usage: Minimal (~1KB)
  • CPU usage: <1% (plenty of resources for other tasks)

Can be used alongside:

  • WiFi communication
  • Bluetooth
  • Display updates
  • Motor control
  • Other sensors

Project Ideas

Beginner

  • Pressure-sensitive LED - Brightness changes with force
  • Door knock detector - Trigger when force exceeds threshold
  • Musical instrument - FSR controls pitch/volume

Intermediate

  • Smart mat - Detect when someone steps on surface
  • Grip strength meter - Measure and log hand strength
  • Pressure mapping - Multiple FSRs to create heatmap

Advanced

  • IoT weight scale - Send weight data to cloud
  • Game controller - Analog pressure-sensitive buttons
  • Prosthetic feedback - Pressure sensing for robotic hands

Additional Resources

ESP32 Documentation:

FSR Datasheets:

Arduino References:


License

This project is provided as-is for educational and hobbyist purposes. Feel free to modify and use in your projects!


Support

Issues with hardware setup? Check SETUP.md

Questions or problems?

  • Check the Troubleshooting section above
  • Review your wiring against the circuit diagram
  • Verify all configuration settings in the code
  • Test components individually with multimeter

Happy building! You now have a working pressure sensor system ready for integration into your projects.

About

ESP32 Force Sensitive Resistor (FSR) pressure sensor project with multi-sensor support and auto-diagnostics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 2

  •  
  •