Categories
TUTORIALS

Force Sensor Peak Detection

This tutorial gives an overview for how to determine the peak force read by a force sensor on an Arduino Uno board. There are many applications for this type of setup, but my particular one is for reading the weights of train cars as they roll over a single sensor. The algorithms shown here can be used for gathering the peaks of any set of discrete impulses to a system (assuming the system returns to a rest state between them).

This tutorial will build up the code to do peak detection for a train car and show how it can be scaled to handle a full train. The tutorial will cover the following four areas:

  1. Setting up the Arduino Uno board
  2. Reading weight values continuously
  3. Peak Detection
  4. Detecting and Storing Multiple Peaks

Components:

The Circuit:

The circuit set up is relatively simple, requiring just the force sensor and a 10K Ohm Resisitor. One side of the force sensor is connected to +5V and the other side is connected to 10K Ohm resistor, which then is tied to Ground. The Analog Probe is connected to the junction of the force sensor and the 10K resistor. For my purposes, I chose to use Analog Pin 0, though any pin will work assuming the code is adjusted accordingly.

How It Works:

This circuit is a classic voltage divider set up. In this case, the force sensor has a high resistance when no contact is detected. As more pressure is applied, the resistance lowers to about 1000 Ohms at its maximum sensing capability. The resistance curve from the spec sheet for the sensor is shown below.

Using the below chart from the spec sheet, I was able to determine that a 10K resistor had the most linear response and varied output voltage over the weight ranges I plan to use. For different applications, it may be necessary to use a different resistor.

The general principle at work in this circuit is a “voltage divider.” As the resistance of the force sensor falls, more current flows through it. The analog pin on the Arduino reads in the voltage from the circuit board and interprets it as a number between 0 and 1023. That number can then be interpreted as a weight value using the above chart.

Note: For my application, I am only using values relative to each other in this application. Tuning these sensors to accurately display weight information is not within the scope of this tutorial.

 Weight Detection Code:

Simply reading the weight from the force sensor can be done with the following code. I made the above graphic by taking the output from this code and pasting it into Excel.

To help limit the number of readings from the weight sensor, I added a delay of 50ms to the code.

Peak Detection Code:

Although finding the highest point of a peak is relatively easy for people, it can be a challenging prospect for a computer. Noise as well as other factors can cause inaccurate readings, which, in turn, can generate false positives on peaks. Perhaps the best way to demonstrate this is by looking at actual data output from the above code:

As can be seen here, although a person can easily determine the peak value in each of the impulses, simply looking at any values that are greater than the two around them would result in multiple false positives. Therefore, the code will need to be able to determine when the impulse has started (the wheel hits the sensor) and stopped (the wheel finished rolling over the sensor) and store the highest value between those two times.

Given the application of this code, we can make the following assumptions:

  1. The weight detector will return to a “zero” state between hits (as in the above graph)
  2. The actual weight of the object rolling over the sensor is proportional to the maximum reading
  3. Once the weight returns to the zero state, the wheel has finished passing over

Breaking the data down in this way yields the following states:

  1. The weight sensor is reading no force (zero state)
  2. The weight sensor was reading zero, but now it has a non-zero value (weight has started to be applied – check to see if it is a peak)
  3. The weight sensor continues to read a force (check to see if it is a peak)
  4. The weight sensor had weight on it, but now does not (return to zero state)

The following code outputs the peak value of each impulse:

The output to the Serial Monitor from the above code should look like the following:

To see this graphically, copy and paste the output values into Excel (the tabs between the values should make Excel default to importing them as separate columns. If not, you will need to go to “Data > Text to Columns” and choose “tab delimited.”)  Add a time column to the left of the output. Select all three columns and then go to “Insert > Scatter Plot with Smooth Lines and Markers”

As can be seen in the above image, the peak value is retained until the next wheel hit is detected. At that time, the peak immediately is reset to the highest value in that impulse.

Scaling the Code

Now that we have successfully detected peaks, we need to scale the code in a way that it can retain the peak values and assign them to values in an array. This code is similar to the last code, but now instead of having one simple output, it will yield a series of outputs. Scaling the code in this way will give us the ability to adjust for different lengths of train, different number of axles per car, or just different types of applications.

 

The output of this code looks like this:

When plotted in Excel, this produces the following graph. It is possible to see in this chart that the peak detection is not only working properly, but it is able to differentiate between a new hit and “noise” in a particularly long hit.

Also notice that when Axle[0] goes high again, all of values stored in the Peak[] array are reset to 0. This is critical because it takes us to a state where another train has started going over the sensor.

From this point, all of the data we need to determine the relative weight of each train car rolling over the sensor has been recorded. Post-processing the data will vary depending on the specific application.

I hope this tutorial was useful. If you have any questions about how this algorithm can be expanded or used for different applications, please feel free to ask below in the comments!

Leave a Reply

Your email address will not be published. Required fields are marked *