Arduino MKR WiFi 1010 - Force Sensor

Detect pressure, touches, and squeezes with force sensors! Force-sensitive resistors (FSR) enable your Arduino MKR WiFi 1010 to measure physical pressure for touch interfaces, grip sensors, weight detection, and interactive projects. This tutorial teaches you how to connect a force sensor to your Arduino MKR WiFi 1010 and program it to read pressure levels.

What You'll Learn:

Real-World Applications:

Arduino MKR WiFi 1010 FSR402 Force Sensor

Interactive Applications:

You can extend this Arduino MKR WiFi 1010 force sensor project by adding displays to show pressure levels, or servos that respond to squeeze strength, creating fully interactive pressure-sensitive systems.

Hardware Preparation

1×Arduino MKR WiFi 1010
1×Micro USB Cable
1×Force Sensor
1×10 kΩ Resistor
1×Breadboard
1×Jumper Wires
1×Optionally, DC Power Jack

Or you can buy the following kits:

1×DIYables Sensor Kit (30 sensors/displays)
1×DIYables Sensor Kit (18 sensors/displays)
Disclosure: Some of the links provided in this section are Amazon affiliate links. We may receive a commission for any purchases made through these links at no additional cost to you.
Additionally, some of these links are for products from our own brand, DIYables .

Overview of Force Sensor

What is a Force Sensor?

A force sensor (also called Force-Sensitive Resistor or FSR) is a piezoresistive sensor that changes its electrical resistance when mechanical force is applied.

How Force Sensors Work:

  • Made of two thin polymer films with conductive material
  • When force applied, conductive particles come closer together
  • More pressure = Lower resistance = Higher voltage reading
  • Less pressure = Higher resistance = Lower voltage reading
  • Resistance can range from >10MΩ (no pressure) to <1kΩ (maximum pressure)

Popular FSR Models:

  • FSR402: Round 12.7mm sensing area (most common)
  • FSR406: Round 38.1mm sensing area (larger contact)
  • Interlink FSR: Various sizes and shapes available

Key Characteristics:

Advantages:

  • Simple interface: Acts like variable resistor
  • Thin and flexible: Can bend and conform to surfaces
  • Low cost: Inexpensive pressure sensing solution
  • Fast response: Responds in milliseconds
  • Wide force range: Typically 0.1N to 10N
  • Easy integration: Works directly with Arduino analog inputs

Limitations:

  • Not accurate for absolute measurements: ±5-25% variation
  • Not suitable for precise weight: Use load cells for precision
  • Best for relative measurements: Good for detecting pressure changes
  • Contact area matters: Different pressures give same reading if area changes
  • Temperature sensitive: Readings affected by temperature changes
  • Hysteresis: Slight difference between increasing/decreasing pressure

Perfect For:

  • Detecting presence (someone sitting, standing, touching)
  • Relative pressure measurement (light, medium, strong squeeze)
  • Touch-sensitive interfaces and buttons
  • Grip strength detection
  • Contact detection in robotics
  • Interactive art installations

Not Suitable For:

  • Precise weight measurement (use load cell instead)
  • Long-term force monitoring (sensor drifts over time)
  • Safety-critical applications requiring calibration
  • Scientific measurements needing high accuracy

Force Sensor Pinout

Force sensor pinout

A force sensor has two terminals (pins/leads):

  • Terminal 1: Either end of the FSR
  • Terminal 2: Other end of the FSR

Important Notes:

  • No polarity: FSR is like a resistor - orientation doesn't matter
  • Both pins are identical: You can connect either way
  • Two wires: Some FSRs have pre-attached wires, others have bare terminals

Voltage Divider Circuit Required

Unlike digital sensors, FSRs need a voltage divider circuit to work with Arduino:

Why Voltage Divider?

  • Arduino reads voltage, not resistance
  • FSR changes resistance, not voltage directly
  • Voltage divider converts resistance change to voltage change

Circuit Configuration:

Voltage Divider Circuit: 5V | | FSR (variable resistor) | ├──────→ To Arduino Analog Pin (A0) | 10kΩ (fixed resistor) | GND

How It Works:

No Pressure:

  • FSR resistance: Very high (>10MΩ)
  • Most voltage drops across FSR
  • Analog pin reads LOW voltage (~0V)
  • Arduino reads low value (~0-50)

Light Pressure:

  • FSR resistance: Moderate (10-100kΩ)
  • Voltage divides between FSR and resistor
  • Analog pin reads MEDIUM voltage (~1-2V)
  • Arduino reads medium value (~200-400)

Strong Pressure:

  • FSR resistance: Low (<5kΩ)
  • Most voltage drops across 10kΩ resistor
  • Analog pin reads HIGH voltage (~3-5V)
  • Arduino reads high value (600-1023)

Why 10kΩ Resistor?

  • Good balance between sensitivity and range
  • Works well with typical FSR resistance range
  • Can use 5kΩ-47kΩ depending on application:
    • Lower resistance (5kΩ): More sensitive to light touch
    • Higher resistance (47kΩ): Better for strong pressure

    Mathematical Formula:

    Vout = Vcc × (R / (RFSR + R)) Where: Vout = Voltage at analog pin Vcc = Supply voltage (5V) R = Fixed resistor (10kΩ) RFSR = Force sensor resistance (variable)

Wiring Diagram between Force Sensor and Arduino MKR WiFi 1010

The wiring diagram between Arduino MKR WiFi 1010 Force

This image is created using Fritzing. Click to enlarge image

Detailed Connection Guide:

Force Sensor Connections:

  • FSR Terminal 1Arduino 5V
    • Provides reference voltage for voltage divider
  • FSR Terminal 2Two connections:
    • Connection 1: Arduino A0 (analog input pin)
    • Connection 2: Through 10kΩ resistor to GND

    Circuit Explanation:

    This creates a voltage divider circuit where:

    1. Force sensor acts as variable resistor (top of divider)
    2. 10kΩ resistor acts as fixed resistor (bottom of divider)
    3. Arduino A0 measures voltage at the junction point
    4. As FSR resistance decreases (more pressure), voltage increases

    Wiring Steps:

    1. Insert components into breadboard:

    - Place FSR leads in separate rows

    - Place 10kΩ resistor nearby

    1. Connect FSR first terminal:

    - Wire from FSR Terminal 1 to Arduino 5V

    1. Connect FSR second terminal:

    - Wire from FSR Terminal 2 to breadboard row

    - Wire from same row to Arduino A0

    1. Connect 10kΩ resistor:

    - One end to same row as FSR Terminal 2 and A0

    - Other end to GND rail on breadboard

    1. Complete ground connection:

    - Wire from breadboard GND rail to Arduino GND

    Power Supply:

    For This Project: Simply plug your Arduino MKR WiFi 1010 into your computer's USB port. The force sensor circuit draws negligible current (<1mA).

    Important Notes:

    • Always use a pull-down resistor (10kΩ to GND) - never connect FSR directly between 5V and analog pin
    • Keep wires short to minimize noise
    • FSR has no polarity - either orientation works
    • Secure FSR to flat surface for consistent readings

How To Program Force Sensor

Understanding FSR Programming

Programming a force sensor with Arduino MKR WiFi 1010 involves reading analog voltage from the voltage divider circuit.

The Process:

Step 1: Read Analog Value

int analogValue = analogRead(A0);

Returns a value from 0 to 1023 (10-bit ADC).

Step 2: Interpret the Value

Typical FSR Reading Ranges: Analog Value Pressure Level ────────────────────────────────────────── 0-10 No pressure 10-200 Light touch 200-500 Light squeeze 500-800 Medium squeeze 800-1023 Strong squeeze

Step 3: Apply Thresholds

if (analogValue < 10) { Serial.println("No pressure"); } else if (analogValue < 200) { Serial.println("Light touch"); } else if (analogValue < 500) { Serial.println("Light squeeze"); } else if (analogValue < 800) { Serial.println("Medium squeeze"); } else { Serial.println("Strong squeeze"); }

Optional: Convert to Voltage

float voltage = analogValue * (5.0 / 1023.0); Serial.print("Voltage: "); Serial.println(voltage);

Optional: Estimate Resistance

float resistance = 10000.0 * (1023.0 / analogValue - 1.0); Serial.print("FSR Resistance: "); Serial.print(resistance); Serial.println(" Ω");

Key Programming Concepts:

  • Relative measurement: FSR readings are relative, not absolute
  • Calibration: Determine your own thresholds through testing
  • Smoothing: Average multiple readings to reduce noise
  • Baseline: Store no-pressure reading and subtract from all measurements

Arduino MKR WiFi 1010 Code

This example reads the force sensor and categorizes pressure into five levels: no pressure, light touch, light squeeze, medium squeeze, and strong squeeze.

What the Code Does:

  • Configures analog pin A0 as input for force sensor reading
  • Continuously reads analog value from voltage divider circuit
  • Maps readings to pressure categories using threshold values
  • Displays both raw value and pressure interpretation
  • Updates readings every 100ms for real-time feedback
  • Perfect for touch detection and pressure-sensitive interfaces
/* * This Arduino MKR WiFi 1010 code was developed by newbiely.com * * This Arduino MKR WiFi 1010 code is made available for public use without any restriction * * For comprehensive instructions and wiring diagrams, please visit: * https://newbiely.com/tutorials/arduino-mkr/arduino-mkr-wifi-1010-force-sensor */ #define FORCE_SENSOR_PIN A0 // the FSR and 10K pulldown are connected to A0 void setup() { Serial.begin(9600); } void loop() { int analogReading = analogRead(FORCE_SENSOR_PIN); Serial.print("Force sensor reading = "); Serial.print(analogReading); // print the raw analog reading if (analogReading < 10) // from 0 to 9 Serial.println(" -> no pressure"); else if (analogReading < 200) // from 10 to 199 Serial.println(" -> light touch"); else if (analogReading < 500) // from 200 to 499 Serial.println(" -> light squeeze"); else if (analogReading < 800) // from 500 to 799 Serial.println(" -> medium squeeze"); else // from 800 to 1023 Serial.println(" -> big squeeze"); delay(1000); }

Code Explanation - Force Sensor Reading

Pin Configuration:

const int FORCE_SENSOR_PIN = A0;

Defines A0 as the analog input for reading voltage from the voltage divider.

Reading Analog Value:

int analogValue = analogRead(FORCE_SENSOR_PIN);

Reads 10-bit value (0-1023) representing voltage at analog pin.

Threshold-Based Categorization:

if (analogValue < 10) Serial.println(" -> no pressure"); else if (analogValue < 200) Serial.println(" -> light touch"); else if (analogValue < 500) Serial.println(" -> light squeeze"); else if (analogValue < 800) Serial.println(" -> medium squeeze"); else Serial.println(" -> big squeeze");

Classifies pressure into five categories based on analog value ranges.

Understanding Thresholds:

  • <10: Essentially no pressure (noise level)
  • 10-200: Finger barely touching
  • 200-500: Light finger pressure
  • 500-800: Firm finger squeeze
  • 800-1023: Maximum pressure

Calibration Note: These thresholds work well for FSR402 with 10kΩ resistor. Adjust based on your specific FSR model and resistor value.

Detailed Instructions

New to Arduino MKR WiFi 1010? Complete our Getting Started with Arduino MKR WiFi 1010 tutorial first to set up your development environment.

Step 1: Build Voltage Divider Circuit

  • Connect FSR Terminal 1 to Arduino 5V
  • Connect FSR Terminal 2 to breadboard row
  • Connect same row to Arduino A0
  • Connect 10kΩ resistor from same row to GND
  • Connect Arduino GND to breadboard GND rail

Step 2: Upload Code

  • Use USB cable to connect Arduino MKR WiFi 1010 to your computer
  • Launch Arduino IDE
  • Select Arduino MKR WiFi 1010 board and COM port
  • Copy the code above into Arduino IDE
  • Click Upload button

Step 3: Test Force Sensor

  • Open Serial Monitor (baud rate: 9600)
  • Place finger on FSR sensing area
  • Gradually increase pressure
  • Watch values and categories change
  • Release pressure and watch values return to zero

Expected Serial Monitor Output:

COM6
Send
The force sensor value = 0 -> no pressure The force sensor value = 0 -> no pressure The force sensor value = 132 -> light touch The force sensor value = 147 -> light touch The force sensor value = 394 -> light squeeze The force sensor value = 421 -> light squeeze The force sensor value = 607 -> medium squeeze The force sensor value = 791 -> medium squeeze The force sensor value = 921 -> big squeeze The force sensor value = 987 -> big squeeze The force sensor value = 0 -> no pressure The force sensor value = 0 -> no pressure
Autoscroll Show timestamp
Clear output
9600 baud  
Newline  

Testing Tips:

  • No reading: Check wiring, ensure 10kΩ resistor connected to GND
  • Always high values: FSR might be damaged or always pressed
  • Always ~512: Check that FSR Terminal 2 connects to both A0 and resistor
  • Noisy readings: Add small capacitor (0.1µF) across 10kΩ resistor
  • Inconsistent: FSR needs flat, stable mounting surface

Troubleshooting Common Issues

Problem: Always Reads 0 or Very Low Values

Possible Causes:

  • Wiring error in voltage divider
  • FSR not connected properly
  • Wrong resistor value
  • FSR damaged

Solutions:

  1. Verify FSR Terminal 1 connects to 5V
  2. Confirm FSR Terminal 2 connects to BOTH A0 and resistor
  3. Check resistor connects to GND (not 5V)
  4. Verify 10kΩ resistor (brown-black-orange bands)
  5. Test FSR with multimeter - resistance should change when pressed

Problem: Always Reads High Values (~1023)

Possible Causes:

  • No pull-down resistor
  • Resistor disconnected from GND
  • Short circuit

Solutions:

  1. Verify 10kΩ resistor present in circuit
  2. Check resistor connects to GND, not floating
  3. Ensure no short between A0 and 5V
  4. Try different analog pin

Problem: Reads Around 512 Constantly

Cause: A0 pin floating (not properly connected).

Solutions:

  1. Check connection from FSR Terminal 2 to A0
  2. Ensure breadboard contacts are good
  3. Try different breadboard row
  4. Check jumper wire continuity

Problem: Noisy or Erratic Readings

Possible Causes:

  • Electrical interference
  • Poor connections
  • Long wires
  • Unstable FSR mounting

Solutions:

  1. Add 0.1µF capacitor parallel to 10kΩ resistor
  2. Use shorter wires
  3. Secure FSR to flat surface
  4. Average multiple readings in code:
int sum = 0; for (int i = 0; i < 10; i++) { sum += analogRead(A0); delay(5); } int average = sum / 10;

Problem: Inconsistent Readings at Same Pressure

Causes:

  • FSR characteristic - they have inherent variation
  • Contact area changing
  • Temperature effects
  • FSR mounting not stable

Solutions:

  1. Accept ±10-20% variation as normal
  2. Use thresholds with hysteresis
  3. Mount FSR firmly to rigid surface
  4. Ensure consistent contact area (same finger position)
  5. Calibrate for specific application

Problem: FSR Stops Responding After Some Time

Causes:

  • FSR overheated (continuous high pressure)
  • Adhesive layer delaminating
  • Physical damage

Solutions:

  1. Avoid continuous high pressure for extended periods
  2. Let FSR rest between tests
  3. Don't exceed 10N force specification
  4. Replace if permanently damaged

Challenge Yourself - Creative Extensions

Once you have the basic force sensor working, try these enhancements:

1. Visual Pressure Indicator

Show pressure level on LED bar graph:

const int LED_PINS[] = {D2, D3, D4, D5, D6, D7, D8, D9}; const int NUM_LEDS = 8; int analogValue = analogRead(A0); int numLEDsToLight = map(analogValue, 0, 1023, 0, NUM_LEDS); for (int i = 0; i < NUM_LEDS; i++) { digitalWrite(LED_PINS[i], i < numLEDsToLight ? HIGH : LOW); }

2. Pressure-Controlled Servo

Move servo based on squeeze strength:

#include <Servo.h> Servo myServo; int analogValue = analogRead(A0); int angle = map(analogValue, 0, 1023, 0, 180); myServo.write(angle);

3. Musical Instrument

Create pressure-sensitive tones:

const int BUZZER_PIN = D6; int analogValue = analogRead(A0); if (analogValue > 50) { int frequency = map(analogValue, 50, 1023, 200, 2000); tone(BUZZER_PIN, frequency); } else { noTone(BUZZER_PIN); }

4. Pressure-Activated Lock

Unlock when specific pressure applied:

const int LOCK_PIN = D7; const int TARGET_PRESSURE = 500; // Target value const int TOLERANCE = 50; int analogValue = analogRead(A0); if (abs(analogValue - TARGET_PRESSURE) < TOLERANCE) { digitalWrite(LOCK_PIN, HIGH); // Unlock Serial.println("Unlocked!"); } else { digitalWrite(LOCK_PIN, LOW); // Keep locked }

5. Grip Strength Tester

Record and display maximum grip:

int maxGrip = 0; int analogValue = analogRead(A0); if (analogValue > maxGrip) { maxGrip = analogValue; Serial.print("New record: "); Serial.println(maxGrip); } // Reset on button press if (digitalRead(BUTTON_PIN) == LOW) { maxGrip = 0; Serial.println("Reset!"); }

6. Multi-Point Pressure Mat

Monitor multiple FSRs for position detection:

const int FSR_PINS[] = {A0, A1, A2, A3}; const int NUM_SENSORS = 4; for (int i = 0; i < NUM_SENSORS; i++) { int value = analogRead(FSR_PINS[i]); if (value > 200) { Serial.print("Pressure at position "); Serial.println(i); } }

7. Pressure-Modulated LED Brightness

Control LED brightness with squeeze:

const int LED_PIN = D9; // PWM pin int analogValue = analogRead(A0); int brightness = map(analogValue, 0, 1023, 0, 255); analogWrite(LED_PIN, brightness);

8. Touch-Sensitive Game Controller

Create pressure-sensitive game inputs:

int analogValue = analogRead(A0); if (analogValue > 800) { // Strong press - jump high jumpHeight = 10; } else if (analogValue > 400) { // Medium press - jump normal jumpHeight = 5; } else if (analogValue > 100) { // Light touch - walk moveSpeed = 1; }

9. Data Logging

Record pressure events over time:

#include <SD.h> unsigned long timestamp = millis(); int analogValue = analogRead(A0); File dataFile = SD.open("pressure.csv", FILE_WRITE); dataFile.print(timestamp); dataFile.print(","); dataFile.println(analogValue); dataFile.close();

10. Smart Seat Occupancy Detector

Detect presence and sitting duration:

unsigned long sitStartTime = 0; const int OCCUPIED_THRESHOLD = 300; int analogValue = analogRead(A0); if (analogValue > OCCUPIED_THRESHOLD) { if (sitStartTime == 0) { sitStartTime = millis(); Serial.println("Seat occupied"); } unsigned long sitDuration = (millis() - sitStartTime) / 1000; Serial.print("Sitting for: "); Serial.print(sitDuration); Serial.println(" seconds"); } else { if (sitStartTime != 0) { Serial.println("Seat vacant"); sitStartTime = 0; } }

Experiment and create pressure-sensitive interactions!

Video Tutorial

Learn More

※ OUR MESSAGES

  • As freelancers, We are AVAILABLE for HIRE. See how to outsource your project to us
  • Please feel free to share the link of this tutorial. However, Please do not use our content on any other websites. We invested a lot of effort and time to create the content, please respect our work!