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

Was it no problem to solder it? Looks really good and I am not sure to which extent they are right online that it is “dangerous” and could potentially destroy the sensor. I assume that wasn’t a large problem for you?

That’s a good question. I did ruin one of them actually.

My advice would be to go as quickly as you can. If you keep the iron on it for too long it will melt the sensor.

1 Like

Instead of working with jumper wires only for my test setup I have now ordered some breadboards. Which meant a more stable connection especially where some y-connections were required (i.e. for the voltage divider).
I can confirm now that the setup itself is working. Also found out, that I needed to adapt the update rate to see some quick responses in case of the voltage divider.
However the FSR seems to be very sensitive (i.e. little pressure is enough to go from 0V to 1.1V - More pressure did not result in higher voltage). With sentiment also values inbetween could be achieved.
The same is valid for the touch input. It provides a readout of about 70 if untouched, and little pressure brings it down to zero. This results in the behaviour observed. If put underneath the topper mattress, the FSR already gets enough pressure for the ESP to output 0 (Touch), or maximum voltage (ADC). I connectected the 10K Ohm resistor in line with the FSR, but this did only change the results slightly. Any idea how to decrease the sensitivity?

Ok so here is my best yet but not perfect solution for bed occupancy:

Sorry for the long post, hope it helps someone here.

Parts

Wemos D1 Mini
330K Resistor
2x 1N4007 Zener Diodes - Link
4x 2-pin JST connectors (2x Male / 2x Female) - Link
2x Force Sensitive Resistors - Link

Wiring:

I’m not even remotely an expert but here is how i think it works.

Basically each sensor is connected to a digital pin (D1 / D2) and the analog pin (A0).

The analog connection is via a diode, these only allow electricity to flow in one direction. It completely solves the issue I was having in a previous version where the values from one sensor would be effected by input from the other.

A resistor is added between A0 pin and ground, the specific explanation currently eludes my tiny brain but values are constantly recorded (even when no pressure is applied) without it.

I’m sure someone smarter and more qualified will be able to better explain exactly what’s going on!

The code:

Before I share my code I must point out that my devices server two purposes. On top of being a bed occupancy sensor they’re also acting as an MQTT bridge for other devices in my house. As a consequence I did not write any code for this, instead I used ESP MQTT project and implemented the following script on it:

There is a lot going on here so let me explain.

Essentially the script implements a timer where by the D1 pin is set to high and the resulting value is sent to HA, D1 is then set to low and D2 is high, reporting that value. This continues in an endless loop.

As an MQTT bridge this will forward any payload on specified topic to HA. I use this due to my master bedroom being in the loft and the router being on the ground floor. Using this with a D1 mini pro w/ external aerial has solved all connection issues i had. But i digress.

config speed		160

on init
do

	setvar $bed1_prev_adc = 0
	setvar $bed2_prev_adc = 0
	settimer 1 1000

	setvar $forwardTopic="+/topFloor/#"
	setvar $configTopic="homeassistant/+/topFloor/#"

	setvar $local_pub = ""
	setvar $threshold = 25
	subscribe local $forwardTopic
	subscribe local $configTopic

on mqttconnect
do
	settimer 1 500
	subscribe remote $forwardTopic
	subscribe remote $configTopic

	publish local "stat/topFloor/masterBedroom/bed1" $bed1_prev_adc
	publish local "stat/topFloor/masterBedroom/bed2" $bed2_prev_adc

	publish local "homeassistant/sensor/topFloor/masterBed1/config" "{\"name\":\"Master Bedroom Bed Sensor 1\",\"stat_t\":\"stat/topFloor/masterBedroom/bed1\",\"unit_of_meas\":\"hPa\",\"dev_cla\":\"pressure\",\"ic\":\"mdi:bed\",\"uniq_id\":\"MQTT_Bridge_MB1\",\"dev\":{\"ids\":[\"MQTT_Bridge_MB1\", \"MQTT_Bridge_MB2\"],\"name\":\"Master Bedroom\",\"mdl\":\"Bed Sensor\",\"sw\":\"v0.2-alpha\",\"mf\":\"Martin Ger\"}}"
	publish local "homeassistant/sensor/topFloor/masterBed2/config" "{\"name\":\"Master Bedroom Bed Sensor 2\",\"stat_t\":\"stat/topFloor/masterBedroom/bed2\",\"unit_of_meas\":\"hPa\",\"dev_cla\":\"pressure\",\"ic\":\"mdi:bed\",\"uniq_id\":\"MQTT_Bridge_MB2\",\"dev\":{\"ids\":[\"MQTT_Bridge_MB1\", \"MQTT_Bridge_MB2\"],\"name\":\"Master Bedroom\",\"mdl\":\"Bed Sensor\",\"sw\":\"v0.2-alpha\",\"mf\":\"Martin Ger\"}}"


on topic local $forwardTopic
do
	println "Receiving " | $this_topic | " " | $this_data
	if not ($local_pub = $this_topic) then
		publish remote $this_topic $this_data retained
	else
		setvar $local_pub = ""
	endif

on topic local $configTopic
do
	if not ($local_pub = $this_topic) then
		publish remote $this_topic $this_data retained
	else
		setvar $local_pub = ""
	endif

on topic remote $forwardTopic
do
	setvar $local_pub = $this_topic
	publish local $this_topic $this_data

on topic remote $configTopic
do
	% Publish this locally
	setvar $local_pub = $this_topic
	publish local $this_topic $this_data

on timer 1
do
  %D1 = gpio 5
	%D2 = gpio 4

	gpio_out 4 0
	gpio_out 5 1

	setvar $bed1_adc = $adc
	println "Bed 1 " | "raw value:" | " " | $bed1_adc
	if ($bed1_adc > $threshold) then
		if($bed1_adc > ($bed1_prev_adc + $threshold)) then
			publish local "stat/topFloor/masterBedroom/bed1" $bed1_adc
			setvar $bed1_prev_adc = $bed1_adc
		else
			if(($bed1_prev_adc - $threshold) > $bed1_adc) then
				publish local "stat/topFloor/masterBedroom/bed1" $bed1_adc
				setvar $bed1_prev_adc = $bed1_adc
			endif
		endif
	else
		if($bed1_prev_adc = 0) then

		else
			publish local "stat/topFloor/masterBedroom/bed1" 0
			setvar $bed1_prev_adc = 0
		endif
	endif

	settimer 2 500

on timer 2
do

	gpio_out 5 0
	gpio_out 4 0

	settimer 3 500

on timer 3
do

	gpio_out 5 0
	gpio_out 4 1

	setvar $bed2_adc = $adc
	println "Bed 2 " | "raw value:" | " " | $bed1_adc
	if ($bed2_adc > $threshold) then
		if($bed2_adc > ($bed2_prev_adc + $threshold)) then
			publish local "stat/topFloor/masterBedroom/bed2" $bed2_adc
			setvar $bed2_prev_adc = $bed2_adc
		else
			if(($bed2_prev_adc - $threshold) > $bed2_adc) then
				publish local "stat/topFloor/masterBedroom/bed2" $bed2_adc
				setvar $bed2_prev_adc = $bed2_adc
			endif
		endif
	else
		if($bed2_prev_adc = 0) then

		else
			publish local "stat/topFloor/masterBedroom/bed2" 0
			setvar $bed2_prev_adc = 0
		endif
	endif

	settimer 4 500

on timer 4
do
	gpio_out 5 0
	gpio_out 4 0

	settimer 1 500

Finished product

I will share my Fritzing file for anyone who is interested or would like to do what I did and order a printed PCB from Aisler. Use this link to order it as a PCB: https://aisler.net/p/KJALSWGM

Additionally I designed and printed a clip so it can be secured to the underside of my bed without the need for a roll of duct tape:

2 Likes