# Detect where pressure is being applied by using force resistors

I have 3 force resistors in a row, on top of which I have placed a board. I read values from the resistors through analogue ports. My goal is to be able to detect whether someone is pressing on the top, middle, or bottom of the board.

So far I can easily detect the left and right, like this: I first calibrate the 3 sensors for 2 seconds. Then I detect if pressure is applied on any of the calibrated sensors. If yes, I sum for all of them the values that they return on each round of the loop, until force has stopped being applied. I finally compare the 3 values against each other and I find which received higher pressure in total. This works perfectly fine for the left and right. However, when the board is pressed in the middle, pressure is applied on all 3, since the board is flat. Sorting the values does not help, because very often the left and right sensors have recorded a higher value than the middle.

I noticed that when the board is pressed on the left, the right sensor records very few values, and the same for the other way around. So, I get a high success rate in detecting middle presses like this:

``````int threshold = 80;
if (left_sum > threshold && middle_sum > 80 && right_sum >80)
return middle_pressed;
``````

However, when someone presses hard enough on the left or right, the if statement is satisfied.

Is there a more accurate way to detect where force is being applied?

(Following is a quick schematic I made - I am not at all an expert so please excuse me for my mistakes, I just hope it illustrates more or less what it is supposed to) simulate this circuit – Schematic created using CircuitLab

Please ignore the double arrows right on top of the resistors.

• Is there something between the board and the FSR ? To spread the pressing force over the FSR ? For example a sheet of 1mm silicone. I don't know a smart mathematical solution, because the board does not bend. A resistive touch screen detects the middle of the force, but the top layer bends. I would use a threshold at the end of a calculation. First I would calculate which one is most likely to be pressed (using all three sensors for each calculation), and after that I would apply a threshold to check if it will be accepted. Do you really need the middle FSR ? It does not give more information. – Jot Jul 8 '17 at 4:07
• Thank you for your answer! To clarify, the board on top is too thick to bend, so I cannot do much about it. You are right that the middle one does not do much, so I will consider removing it. Another thought I had is if both left and right detect pressure to return the middle if `left/right < threshold`. This will probably minimise the risk of getting the middle if you pressing too hard. – jackgu1988 Jul 8 '17 at 9:39
• Okay, removing the middle FSR is a good idea, it is only confusing. Be sure that the FSR are attached to a flat surface. There must be something (1 mm silicone sheet) between the FSR and the board. This is really important to get consistant values. Now you can do math. Calculate with two sensors where the force is pressed, determine the position and the total force (if possible in Newton). Use the threshold at the end of the calculation when the position and total force is known. In the code you might need to check two position limits and one threshold limit for each virtual button. – Jot Jul 8 '17 at 14:22
• Yes you are right about the silicone, I had already put on the sensors these silicone "legs" that you stick on things that you don't want to slide. Here is my code if anyone is interested. At the moment the results are almost perfect (it fails to detect ~1/20 trials) and I am looking into how I can improve it further gist.github.com/jackgu1988/085fb432b1d0005083cbd5570a55d6ab – jackgu1988 Jul 8 '17 at 18:28
• the position and the total force. I have made a (very long) answer. – Jot Jul 9 '17 at 6:04

Let's assume that you have only two FSR sensors. With those you can make three virtual buttons (above the left sensor, above the right sensor and in the middle).

To measure someone's weight, it is allowed to have a scale under each foot and add both weights. We can use that to calculate the total force pressing to the board, by just adding the two forces.

The FSR sensors have a curve to calculate the force in newtons. It is very inaccurate, but works more or less. That can be added later. For now let's assume that it is linear to the ADC value of the Arduino.

Are the FSR sensors connected to an analog input and GND ? Do you have a resistor between the analog input and 5V ? I assume you do. You need the resistors so that a nice pressing force to the board results somewhere in the middle of the ADC range.

Pseudo code:

``````setup()

Measure both ADC values (or a number of values and use the average)
Store them as offsets in a global variable.

loop()

Measure both ADC values, substract the offset.

Translate the ADC values into force.
The more force the higher the number should get.
Any range is okay for now.
They can be translated into Newton later.

The total force is by adding the two forces.

The position in percentage is the force of the right sensor
divided by total force times 100.
Then the position will be 0 for left sensor, 50 for middle
and 100 for right sensor.

If the total force is above threshold, then check the position.

for example position -50 to 20 for left virtual button.
for example position 30 to 70 for middle virtual button.
for example positition 80 to 150 for right virtual button.
``````

You can start by printing the forces to the serial monitor. Press the board and check if the numbers increase when pressing more.

Don't get confused when you print the position. It will be very noisy when no force to the board is applied. It should be valid when the total force is above the threshold.

For the position I allow a large error of 50 percent left of the left sensor and right of the right sensor. It depends on the mechanical construction and the rest of the code if that makes sense.

Print the results to the serial monitor.
If that is working well, then you have to detect a single press.

Let's assume that as soon as the threshold is reached, a press to a virtual button is accepted. Let's not wait until the peak of the force is reached.
The State Change Detection example can be used to create a single event for pressing the virtual button.

Any jitter or noise (for example a single press to the board results into two events for the virtual button) can be solved by averaging or filtering in software. I think that it will be needed.

I'm not sure if all of this is okay. I hope that someone else will look into it as well.

• Thank you very much! This makes sense to me and I agree that this is the best way that it should be done. I will both waiting for the peak of the force (and take the decision after state change) and calculating on each round of the loop and see what works faster. I do not mind taking the decision afterwards, as I am more interested in the system being as fast as possible in detecting state changes. – jackgu1988 Jul 9 '17 at 10:38
• If you make a variable active when a virtual key is pressed (as long as it is being pressed), then that variable is the same as the digitalRead of the State-Change-Detection example. I see no advantage to wait for the peak. The virtual key press is already accepted when it was above the threshold, it does not matter what follows (small peak or big peak). It has to drop below the threshold to be able to accept a new virtual key press. The State-Change-Detection is for one key, you have three virtual buttons and only one button can be pressed at a time, so there is a little difference. – Jot Jul 9 '17 at 10:46
• My assumption is that force will only be applied on one spot at a time and then released (no sliding or whatsoever). So, I am treating as a change of state when any of the FSRs is measuring something (above the calibration threshold). By checking on every round if some threshold is exceeded, I have to sum two numbers and then run an if statement. If I check afterwards, I just store two numbers on each loop and afterwards run the if statement once. – jackgu1988 Jul 9 '17 at 11:21
• I prefer clean programming above getting into troubles. It's no problem to check everything thousands times per second. You might need to slow the sampling down to about 100 times per second with millis. That's just optimizations for later. – Jot Jul 9 '17 at 11:43
• I totally agree in general, but in this case I am trying to get accuracy as close to the millisecond as possible, because I also care about exactly for how long a button was pressed. Based on your help (especially from this answer) I have managed to significantly reduce the complexity of the code already. – jackgu1988 Jul 9 '17 at 11:55

Is there a more accurate way to detect where force is being applied?

normalize your measurements vs. the static values of those strain gauge readings obtained during calibration.