FSR - the best bed occupancy sensor

Once you have a sensor that can detect you are in bed you will wonder how you automated without it. I use it to turn everything off, turn on my bedside lamp, arm the alarm in perimeter mode, and put my announcements in “do not disturb mode”. When I get up it disarms the alarm and plays my morning announcements.

Unfortunately finding a reliable sensor has not been easy.

I have tried:

  1. A strain gauge glued to a bed slat. It had a reliable detection range and was fast but required re-tuning of the trigger level occasionally as the wooden slat it was glued to changed shape with temperature and humidity. Some others who tried it reported sensor noise issues.

  2. A pressure mat. This was very fast and worked reliably for months but eventually compressed and started false triggering. It was also expensive for the larger mats ($80 AUD) and they could be damaged by folding for postage (I had to return two).

And now this. A force sensitive resistor (FSR) Force Sensitive Resistor - Long - SEN-09674 - SparkFun Electronics

I have been extremely happy with the response and reliability. It does not drift like a strain gauge and can not be crushed like a pressure mat.

Don’t bother purchasing the recommended clips. I had absolutely no luck getting them to connect to the FSR (maybe I was doing it wrong?) and if you are quick with a soldering iron you can make a more reliable connection. Just be fast as possible when soldering and use the absolute minimum heat required for heatshrinking.

Tin your wires and the connections with solder first and if possible use something to stop the heat spreading up the connections. See where I have placed the helping hands alligator clip:

A bit of heatshrink helps with making the connection more robust

The FSR comes with adhesive backing but I used painter’s tape to secure it to a bed slat lightly so as not to be affected by the wood expanding and contracting with temperature or humidity.

Connect it to an ESP board analogue input like this:

Screenshot 2021-12-11 at 15-53-11 Resistance Sensor

The choice of R1 is very important for the largest possible detection range.

To determine its value, measure the resistance of the FSR with a multimeter when you are in and out of bed. R1 can then be found using this formula:

R1 = SQRT( Rin_bed * Rout_of_bed)

Make the measurements a few times and take averages for each of the two values.

The result will depend on the thickness, weight and resilience of your mattress. For one bed I used 300 Ohms, for another 3K Ohms!. Do calculate this value properly.

You will need an input number in Home Assistant for each FSR:

master_bed_trigger_level:
  name: Master Bed Trigger Level
  min: 0
  max: 3.5
  step: 0.05
  unit_of_measurement: V
  icon: mdi:arrow-collapse-down

Then you can add the following to your ESP configuration:

For ESP32 boards:

binary_sensor:
  - platform: template
    name: "Master Bed Occupied"
    id: mb_o
    lambda: |-
      if (id(master_bed_sensor).state < id(trigger_level).state) {
        return true;
      } else {
        return false;
      }

sensor:
  - platform: adc
    pin: GPIO34
    attenuation: 11db
    name: "Master Bed Sensor"
    id: "master_bed_sensor"
    icon: mdi:bed
    update_interval: 0.5s
    filters:
      - sliding_window_moving_average:
          window_size: 10
          send_every: 1
      - or:
          - throttle: 180s
          - delta: 0.02

  - platform: homeassistant
    name: "Trigger Level"
    id: "trigger_level"
    entity_id: input_number.master_bed_trigger_level

Note: for ESP8266 boards, change the sensor definition to:

sensor:
  - platform: adc
    pin: A0
    name: "Master Bed Sensor"
    id: "master_bed_sensor"
    icon: mdi:bed
    update_interval: 0.5s
    filters:
      - multiply: 3.3
      - sliding_window_moving_average:
          window_size: 10
          send_every: 1
      - or:
          - throttle: 180s
          - delta: 0.02

  - platform: homeassistant
    name: "Trigger Level"
    id: "trigger_level"
    entity_id: input_number.master_bed_trigger_level

As the ADC voltage is 0 to 1V instead of 0 to 3.3V and the attenuation option is not used.

Results have been outstandingly repeatable and reliable:

Bonus Lovelace card, requires mini-graph-card and hui-element

Screenshot 2021-12-12 at 10-47-31 Administration - Home Assistant

entities:
  - color_thresholds_transition: hard
    entities:
      - entity: sensor.master_bed_sensor
        color: '#0da035'
        show_fill: false
      - entity: input_number.master_bed_trigger_level
        color: '#e45e65'
        show_fill: false
      - color: rgb(255,128,0)
        entity: binary_sensor.master_bed_occupied
        show_line: false
        y_axis: secondary
    group: false
    hour24: true
    hours_to_show: 48
    line_width: 2
    points_per_hour: 12
    show:
      icon: false
      name: false
      extrema: false
      average: false
      fill: fade
      labels: false
      state: true
    state_map:
      - label: Out
        value: 'off'
      - label: In
        value: 'on'
    type: custom:hui-element
    card_type: custom:mini-graph-card
    card_mod:
      class: inline-card-no-border
  - entity: input_number.master_bed_trigger_level
show_header_toggle: false
state_color: true
title: Master Bed Sensor
type: entities
28 Likes

Thanks a lot for that great share and an easy solution :wink: I was thinking at using weight sensors but was more tricky to install and setup ! sensors ordered at Sparkfun to build that asp :sunglasses:

1 Like

Yeah the legs of my bed don’t lend themselves well to weight sensors.

Nice thanks for sharing, will give it a try parts are ordered🤗

1 Like

he sorry for bothering you, but could you please elaborate on your wiring, do you have a picture so its easier to rebuild =)

you dont leave bed at night i assume? :slight_smile:

whats the power supply you use here? if battery, possiblilty to report battery level would almost be a ‘must’ (i hate things dying from battery outage)

Yes occasionally why?

USB 5V 1A supplied from a wall outlet. Battery power is no good for this project.

morning announcements for 2am peeing is not what i would like :slight_smile:

I have conditions for that. Only after 6am.

3 Likes

So unlike the other techniques, where several sensors are connected in a Wheatstone bridge configuration, this works equally well with with just one FSR? Or did I misunderstand and there’s more than one used to detect separate occupants?

BTW, great guide!

Correct. Just the one sensor. I sleep on one side of the bed. If you want to detect two sides of a double or larger bed you will need two sensors.

1 Like

If I wanted to detect the presence of left/right occupants would two FSRs be required for accurate detection or would one centrally located FSR be sufficient?

It’s a king-size mattress (width: 76"/1.9m) so I figure two FSRs might be preferable?

Duh, you already answered while I was typing (and measuring the mattress) …

1 Like

Yeah definitely two for that.

Also position the FSR(s) on the slat that is under the heaviest part of your body. In my case that’s my posterior.

Results from a lighter person on a heavier and thicker mattress:

Not as wide a range as my other sensor and there is a little variability when unoccupied, but still very clear states.

1 Like

Here is my configuration for a single ESP32 with two FSR sensors for detecting both sides of the bed.


binary_sensor:
  - platform: template
    name: "Guest Bed Left Occupancy"
    device_class: occupancy
    id: gb_l
    lambda: |-
      if (id(guest_bed_left_sensor).state < id(guest_bed_left_trigger_level).state) {
        return true;
      } else {
        return false;
      }

  - platform: template
    name: "Guest Bed Right Occupancy"
    device_class: occupancy
    id: gb_r
    lambda: |-
      if (id(guest_bed_right_sensor).state < id(guest_bed_right_trigger_level).state) {
        return true;
      } else {
        return false;
      }

sensor:

  - platform: adc
    pin: GPIO34
    attenuation: 11db
    name: "Guest Bed Left Sensor"
    id: "guest_bed_left_sensor"
    icon: mdi:bed
    update_interval: 0.5s
    filters:
      - sliding_window_moving_average:
          window_size: 10
          send_every: 1
      - or:
          - throttle: 180s
          - delta: 0.02

  - platform: adc
    pin: GPIO35
    attenuation: 11db
    name: "Guest Bed Right Sensor"
    id: "guest_bed_right_sensor"
    icon: mdi:bed
    update_interval: 0.5s
    filters:
      - sliding_window_moving_average:
          window_size: 10
          send_every: 1
      - or:
          - throttle: 180s
          - delta: 0.02

  - platform: homeassistant
    name: "Guest Bed Left Trigger Level"
    id: "guest_bed_left_trigger_level"
    entity_id: input_number.guest_bed_left_trigger_level
  - platform: homeassistant
    name: "Guest Bed Right Trigger Level"
    id: "guest_bed_right_trigger_level"
    entity_id: input_number.guest_bed_right_trigger_level
1 Like

This is such a cool project that I’m definitely wanting to build! Question, though, if the strips are under each side of the bed, what happens if you roll off of the strip? Let’s say on a queen or king mattress, you roll over and end up in the center of the bed, does the strip think you are no longer occupying it? The obvious thing would be to add a third strip to the center, but just curious - especially when my wife travels for a week or two for work and I have free reign to monopolize the entire bed :slight_smile: .

I also wonder if a foam mattress would be less effective.

The strips are 600mm long, if you think you will need three then use three.

Hi Tom,
So this is hooked up to the ESP8266 ? Do you place it in a housing? And how is that powered ? I see 3.3V so do you use a usb cable or ?

Would love to see it in full with pictures.

Very interested in this.

ESP32. Powered from a 240V wall plate that also has 5V USB outlets. I used to just use a 5V 1A plug pack.

Pictures wont be much use to you. The ESP is mounted in a vented enclosure that also houses a temperature and humidity sensor and an RGB push button. Also it is a dog breakfast inside as I have been through a number of iterations of this circuit. I’ll clean it up… one day.

Light goes dim red when the bed sensor is active. The button controls my bedside lamp smart bulb.

3 Likes