Bed occupancy sensor = Force sensing resistor (FSR) + Raspberry Pi Zero WH + AnalogZero pHAT

Hi all,

After reading about someone else that just published his DIY bed occupancy sensor, I thought why not share it myself and the trouble I’ve had. I am not done yet as I am missing the MQTT integration.

The ingredients:

The reason why I went for the more expensive option of Pi0WH + pHAT was the fact that I had already ordered it before knowing more about the esp8266 or similar options. The advantages to me as it is now:

  • Python: I can use Python to code the sensor readings and publishing
  • Pre-existing library: I could leverage the library that already existed for the readings
  • Familiar environment: I am familiar with the Pi and have zero experience with the Arduino IDE and what it would take to flash the esp8266. This will hopefully change in the future, but this is my first DIY project and in the past I had problems finishing projects.

The problems as they currently stand and what I’ve encountered:

  • Faulty wire connections for some of the dupont cables that I’ve used
  • Attaching the FSR to a female header is very difficult given the fact that it’s rather thin and doesn’t really attach itself inside the header
  • A faulty sensor by Adafruit from what it seems. I’ve ordered eight FSRs and one of them is not working properly. I am getting a non-zero value whereas the others consistently report 0. I’ve tried everything to fix it and have now isolated the problem to the sensor. Nonetheless, I’ve installed the sensor and figured I could work by changes in the value rather than the value itself in order to determine the current state.

I’ve installed four of the sensors on the slatted frame. Two on each side. The reason behind it is that I want to determine the position of someone and if my girlfriend is using too much of my side of the bed. I wanted to know over time how the values develop and maybe draw a few insights from it. I figured that if it wasn’t necessary, I could re-purpose the FSRs.

What I haven’t done:

  • MQTT integration
  • HA integration
  • Sensor based automation
  • Create a 3D-printed closure

Currently, I am only reading the values from the sensors every second and store them in a text file. I am doing this to determine the changes over time and get a better understanding of what is going on.
As a next step, I want to collect the values per second over a period of a minute and do the following calculations:

  • Determine 20th and 80th percentile
  • Get the average of all the values between those two percentiles
  • Get the median
  • Get the biggest change in for the 1-minute interval
  • Standard deviation of the value changes

Based on that, I want to determine if someone is still in bed or not. Over time, I want to be able to determine several states:

  • In bed
  • Sleeping (probably unrealistic to differentiate between “in bed” and “asleep”)
  • Nightly bathroom break
  • Just out of bed
  • Out of bed

The difference between “nightly bathroom break”, “just out of bed” and “out of bed” should be determined by time. A bathroom break shouldn’t take longer than 5 minutes, just out of bed is the first fifteen minutes and out of bed is anything after that. My problem is a bit that I would need to retrospectively change the state for the various states, i.e. the first five minutes of someone getting out of bed should not be nightly bathroom break, but should always be out of bed (does that make sense?).

The automations/states that I plan on getting out of this:

  • In bed state: who is still in bed? If one person is in bed then some things should work, some don’t and that should depend on which person.
  • Automatically turn stuff off
  • Automatically turn stuff on
  • Allow some Google Home devices to be eligible to speak to again (not even sure if this is possible to do to be honest), at least turn up volume again

I think the in bed/out of bed sensor is central to automation and whenever I’ve tried to do some automations with lighting in the past based on time, it fell short of the variety of states that an apartment can be in.

The HA integration otherwise should be fairly straight-forward using the MQTT broker. I hope I’ll be able to change the state retrospectively, maybe someone has an idea about that?

The last aspect is the enclosure, I live in Zurich, Switzerland, and the last time I had something printed, I paid $40 for a small item. So, this time I might go a different route and order from another place in the world, if feasible.

So, here is the interesting part now and I want to show a few pictures (asorted):

Given that I am currently on vacation, my sensor is pulling data, but nothing meaningful for the time being. Looking forward to analyzing the results when I return back home.

Any feedback is welcomed!

1 Like

It is a bit tedious, given that I am a newbie poster, I cannot post more than one image per post, I have to add them here:

Is there a way around this? Maybe an admin can add those in? I don’t want to spam posts, but also post those pictures to get better feedback.

Here are sanitized links (replace imgur-link with https://i.imgur.com):
imgur-link/1yKHeEJ.jpg
imgur-link/3yswqdo.jpg
imgur-link/nJhvbzh.jpg
imgur-link/Bp08Fib.jpg
imgur-link/mAY8iIr.jpg
imgur-link/NM9Yo83.jpg
imgur-link/5oDnh6l.jpg
imgur-link/IKXZVHE.jpg
imgur-link/OQo8wc6.png
(First try with a voltage sensor that failed due to the voltage sensor working differently than expected)

1 Like

Post the photos in an imgur album and put a link to the album here.

I looked at these sensors but discounted them due to them maxing out at a kg or two. I thought the weight of the mattress would have them always at the upper end of their weight measuring range.

they work on flex so the resistance value changes as the strip bends, rather than just downward force

Nah, you’re confusing these with strain gauges. These work on pressure applied to the surface.

First paragraph of the datasheet: https://cdn-shop.adafruit.com/datasheets/FSR400Series_PD.pdf

this is the short version… they show it bending… same thing, different length

DESCRIPTION

This sensor can detect flexing or bending in one direction. They were popularized by being used in the Nintendo PowerGlove as a gaming interface.

Nope. Different device. That is a flex sensor not an FSR.

sorry, my bad. I got my links mixed up. :persevere: I was looking at the short flex sensor and thought this project had just used the long version…that’s what I’d use anyway.

I’m using a tiny strain gauge (~7mm long). I’m getting nearly enough change in resistance for a usable sensor. If I cant get rid of the measurement noise I might try that long flex sensor.

The resistance is not a problem, I actually get 0 values (or close to) with the heavy mattress on them. They work on pressure more than they work on weight if that makes sense. A mattress has hardly any pressure that it applies and the bit of pressure it does is spread over the entire sensor.

I was looking at the flex ones as well and want to use it in the future.

I am considering reducing the 1k Ohm resistance to something lower to see more fluctuations in the measurements. I did the initial setup with a 100 Ohm resistor, but only had one at hand.

The imgur album would be easy to setup, but it discourages people from looking at the photos and as such giving feedback.

1 Like

Here’s your photos (I think I got them all):

1 Like

Thanks a lot!

I’ve been tinkering a bit and have started to get this to work. The sensor is actually only showing a value > 0 now, when someone is actually in bed. I’ve added new resistors and that was an effect of it. Previously, I had problems with the values being inconsistent across the four FSRs.

I have now started the coding. My sensor is actually already publishing to MQTT, but I want to properly integrate the sensor in my setup and I cannot get it to work. I am using HASS.io and using the mosquitto addon for the MQTT broker. I am seeing the messages in MQTTLens, so I am effing up somewhere.

I publish the following JSON to the relevant topic:

{
  "time": {
    "end": "20190223135134",
    "start": "20190223135033",
    "timestamp": "20190223135137",
    "date": "2019-02-23",
    "timePeriodParameter": 60
  },
  "sensorType": "bedOccupancySensor",
  "id": "20190223135137sensor4",
  "values": {
    "max": 0,
    "median": 0,
    "percUpperValue": 0,
    "stdev": 0,
    "observations": 60,
    "min": 0,
    "percLowerValue": 0,
    "percUpperParameter": 80,
    "average": 0,
    "percLowerParameter": 20
  },
  "name": "kla"
}

I am publishing to the following topics in MQTT:

  • homeassistant/bedsensor/{name}
  • homeassistant/bedsensor/status

{name} is one of the four sensors and equivalent to name in the JSON. I report the status to the MQTT topic /status with the values online and offline (based on a last will setting.

From the JSON above, I want to get the attribute values.average.

I have setup the sensors the following way in the Home Assistant config:

sensor:
  [...]
  - platform: mqtt
    state_topic: "homeassistant/bedsensor/kla"
    name: "Bettsensor: Links Aussen"
    qos: 2
    value_template: "{{ value_json.values.average }}"
    availability_topic: "homeassistant/bedsensor/status"
    payload_available: "online"
    payload_not_available: "offline"

Despite consistent publications to the topic, I don’t receive any state.

Assuming you have the correct state topic, try this:

    value_template: "{{ value_json["values"]["average"] }}"
1 Like

Thanks a lot, that almost did the trick, tiny correction to remove the " and replace them with ':

value_template: '{{ value_json["values"]["average"] }}'

I’ve done this and it works pretty well - one of my sensors though it sometimes giving falsely low readings which I’ve attributed it to the connection to the FSR - how did you end up getting a good connection? Ive kinda put the connection into female headers and taped them to it - which has worked fine for the other sensor, so I might just have to redo it - but did you have a better solution?

This is a way too late reply, apologies.

My sensor is up and running, but it basically only shows really low values and I attribute it to the thickness of my mattress. I can’t really measure large differences between the readings and it’s pretty binary for me (which is fine for a bed occupancy sensor).

It sometimes shows 0 readings despite someone being in the bed which is a bit annoying. It was a first project for me and I would give it a 4/10. If I had to do it again, I’d use load cells. It’s not only cheaper, but presumably a lot more accurate.

I did tape connections as well, but I have the feeling that this causes some of the misreadings as well. Another reason why I think load cells are the way to go for this.

I’ve (touch wood) fixed my low reading problem, I’ve used cable ties and tied the connection to the FSR really rightly. Since then it’s been rock solid, giving me accurate readings since.

Load sensors would be the ideal solution, but wasn’t practical in my case as my bed has 6 legs and is very heavy so I’d have to buy more robust load sensors, seriously upping the cost. The only issue I have is that if only one person is in the bed, if they have rolled over to the wrong side of the bed, the sensors report the wrong person is in bed, but this rarely happens.

I’m really pleased with my sensors, I’d rate them 9/10

2 Likes

Thanks for quickly responding, very interesting. Do you have a link to cable ties where I can buy them? And also a picture so I can have a look how the setup should look like?

Thanks

Edit: to clarify, I am more interested in what kind of cable ties you’ve used and why they are holding up so well.

Maybe another question: how thick is your mattress? Mine is quite thick making it even more difficult to detect changes.