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:
- Setting up the Arduino Uno board
- Reading weight values continuously
- Peak Detection
- 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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
const int WeightPin = 0; // as in the diagram above this corresponds to ANALOG input pin 0 double weight; // a variable to store the reading from the sensor void setup() { Serial.begin(9600); // set up the serial monitor } void loop() { weight = analogRead(WeightPin); //read in the analog value from the weight pin Serial.println(weight); // prints the weight to the monitor delay(50); // add some delay in the sample time } |
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:
- The weight detector will return to a “zero” state between hits (as in the above graph)
- The actual weight of the object rolling over the sensor is proportional to the maximum reading
- 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:
- The weight sensor is reading no force (zero state)
- 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)
- The weight sensor continues to read a force (check to see if it is a peak)
- 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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
const int WeightPin = 0; // Analog pin to read in value from force sensor double weight[] = {0,0}; // An array to store the last weight value and the most recent one double Peak; // The peak weight of each impulse void setup() { Peaks = 0; // initialize the peak value to 0 Serial.begin(9600); // Start the Serial Monitor // Print a header line for the output on the Serial Monitor // SERIAL MONITOR OUTPUT: // Current Weight ::tab:: Peak Weight (for each hit) Serial.println("Current Weight\t Peak Weight"); } void loop() { weight[0] = weight[1]; // Shift the weight reading array down by 1 in the array weight[1] = analogRead(WeightPin); // Read in the current value delay(50); // Write a small delay (50ms) into the sample time // Write out the weights and peak values to the serial monitor Serial.print(weight[1]); Serial.print("\t"); Serial.println(Peak]); // Using 5 as the "zero" value helps to filter out noise that might act as a false positive for a wheel hit if (weight[1] > 5 && weight[0] <= 5) //start of a wheel hit { Peak = weight[1]; // the first hit value sets the Peak baseline for that axle } else if (weight[1] > 5 && weight[0] > 5) // the wheel is still rolling over the sensor { if(weight[1] > Peak) //if the recorded weight is higher than any other in the same axle hit - record it as a peak { //Every time a new weight is read in - check to see if it is a new maximum Peak = weight[1]; } } else if (weight[1] <= 5 && weight[0] > 5) // end of wheel hit { // This condition is left in for debugging purposes // DO NOTHING } else{ // This is left in for debugging purposes // This is the 0 state - when both weight[1] and weight[0] are < 5. // DO NOTHING } } |
The output to the Serial Monitor from the above code should look like the following:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
Current Weight Peak Weight 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 116.00 0.00 437.00 116.00 684.00 437.00 835.00 684.00 887.00 835.00 908.00 887.00 922.00 908.00 931.00 922.00 937.00 931.00 938.00 937.00 933.00 938.00 905.00 938.00 862.00 938.00 805.00 938.00 695.00 938.00 450.00 938.00 0.00 938.00 0.00 938.00 0.00 938.00 0.00 938.00 0.00 938.00 0.00 938.00 0.00 938.00 0.00 938.00 0.00 938.00 0.00 938.00 0.00 938.00 0.00 938.00 0.00 938.00 0.00 938.00 0.00 938.00 0.00 938.00 0.00 938.00 0.00 938.00 0.00 938.00 81.00 938.00 625.00 81.00 751.00 625.00 807.00 751.00 835.00 807.00 856.00 835.00 868.00 856.00 876.00 868.00 880.00 876.00 883.00 880.00 887.00 883.00 892.00 887.00 896.00 892.00 902.00 896.00 906.00 902.00 912.00 906.00 915.00 912.00 917.00 915.00 920.00 917.00 920.00 920.00 920.00 920.00 920.00 920.00 919.00 920.00 919.00 920.00 919.00 920.00 918.00 920.00 915.00 920.00 912.00 920.00 909.00 920.00 905.00 920.00 905.00 920.00 899.00 920.00 897.00 920.00 897.00 920.00 896.00 920.00 897.00 920.00 897.00 920.00 898.00 920.00 896.00 920.00 893.00 920.00 887.00 920.00 873.00 920.00 855.00 920.00 826.00 920.00 720.00 920.00 0.00 920.00 0.00 920.00 0.00 920.00 0.00 920.00 0.00 920.00 |
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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
const int WeightPin = 0; // Analog pin to read in value from force sensor double weight[] = {0,0}; // A variable to store the last weight value and the most recent one const int consist = 3; // The number of cars that make up the train const int axles = consist * 2; // The number of axles per car (this code assumes 2) double Peaks[axles]; // The peak weight of each axle for each car - note this is now an array int axlecount = -1; // The count of each axle (the code later requires that we start the count at -1) void setup() { // initialize all of the peak values to 0 for (int i = 0; i<axles; i++) { Peaks[i] = 0; } Serial.begin(9600); // Start the Serial Monitor // Print a header line for the output on the Serial Monitor // SERIAL MONITOR OUTPUT: // Current Weight :tab: Axle[0] :tab: Axle[1] ...:tab:... Axle[j] Serial.print("Current Weight\t"); for (int j = 0; j < axles; j++) { Serial.print("Axle["); Serial.print(j); Serial.print("]\t"); } Serial.println(""); } void loop() { weight[0] = weight[1]; // Shift the weight reading array down by 1 in the array weight[1] = analogRead(WeightPin); // Read in the current value delay(50); // Write a small delay (50ms) into the sample time // print the current weight reading to the Serial Monitor Serial.print(weight[1]); Serial.print("\t"); //print the peak values stored for each axle to the Serial Monitor for(int j = 0; j < axles; j++) { Serial.print(Peaks[j]); Serial.print("\t"); } Serial.println(""); // ends the line // Using 5 as the "zero" value helps to filter out noise that might act as a false positive for a wheel hit if (weight[1] > 5 && weight[0] <= 5) //start of a wheel hit { if (axlecount == axles-1) // check to see if we need to reset the axles for the next train { // resets all of the variables to their initial state axlecount = -1; for (int i = 0; i<axles; i++) { Peaks[i] = 0; } } else // the same train is still present - no action required { // DO NOTHING } axlecount++; // increment the count for the next axle (this is why the intial axlecount was -1) Peaks[axlecount] = weight[1]; // the first hit value sets the Peak baseline for that axle } else if (weight[1] > 5 && weight[0] > 5) // the wheel is still rolling over the sensor { if(weight[1] > Peaks[axlecount]) //if the recorded weight is higher than any other in the same axle hit - record it as a peak { //Every time a new weight is read in - check to see if it is a new maximum Peaks[axlecount] = weight[1]; } } else if (weight[1] <= 5 && weight[0] > 5) // end of wheel hit { // This test case is here for debugging purposes // DO NOTHING } else{ // Zero values are being read in - do nothing. // This test case is here for debugging purposes // DO NOTHING } } |
The output of this code looks like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 |
Current Weight Axle[0] Axle[1] Axle[2] Axle[3] Axle[4] Axle[5] 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 79.00 0.00 0.00 0.00 0.00 0.00 0.00 113.00 79.00 0.00 0.00 0.00 0.00 0.00 67.00 113.00 0.00 0.00 0.00 0.00 0.00 36.00 113.00 0.00 0.00 0.00 0.00 0.00 88.00 113.00 0.00 0.00 0.00 0.00 0.00 340.00 113.00 0.00 0.00 0.00 0.00 0.00 861.00 340.00 0.00 0.00 0.00 0.00 0.00 919.00 861.00 0.00 0.00 0.00 0.00 0.00 933.00 919.00 0.00 0.00 0.00 0.00 0.00 939.00 933.00 0.00 0.00 0.00 0.00 0.00 948.00 939.00 0.00 0.00 0.00 0.00 0.00 943.00 948.00 0.00 0.00 0.00 0.00 0.00 937.00 948.00 0.00 0.00 0.00 0.00 0.00 943.00 948.00 0.00 0.00 0.00 0.00 0.00 946.00 948.00 0.00 0.00 0.00 0.00 0.00 943.00 948.00 0.00 0.00 0.00 0.00 0.00 932.00 948.00 0.00 0.00 0.00 0.00 0.00 933.00 948.00 0.00 0.00 0.00 0.00 0.00 927.00 948.00 0.00 0.00 0.00 0.00 0.00 925.00 948.00 0.00 0.00 0.00 0.00 0.00 930.00 948.00 0.00 0.00 0.00 0.00 0.00 922.00 948.00 0.00 0.00 0.00 0.00 0.00 919.00 948.00 0.00 0.00 0.00 0.00 0.00 926.00 948.00 0.00 0.00 0.00 0.00 0.00 921.00 948.00 0.00 0.00 0.00 0.00 0.00 922.00 948.00 0.00 0.00 0.00 0.00 0.00 924.00 948.00 0.00 0.00 0.00 0.00 0.00 918.00 948.00 0.00 0.00 0.00 0.00 0.00 919.00 948.00 0.00 0.00 0.00 0.00 0.00 922.00 948.00 0.00 0.00 0.00 0.00 0.00 769.00 948.00 0.00 0.00 0.00 0.00 0.00 0.00 948.00 0.00 0.00 0.00 0.00 0.00 0.00 948.00 0.00 0.00 0.00 0.00 0.00 0.00 948.00 0.00 0.00 0.00 0.00 0.00 0.00 948.00 0.00 0.00 0.00 0.00 0.00 0.00 948.00 0.00 0.00 0.00 0.00 0.00 0.00 948.00 0.00 0.00 0.00 0.00 0.00 0.00 948.00 0.00 0.00 0.00 0.00 0.00 0.00 948.00 0.00 0.00 0.00 0.00 0.00 0.00 948.00 0.00 0.00 0.00 0.00 0.00 508.00 948.00 0.00 0.00 0.00 0.00 0.00 706.00 948.00 508.00 0.00 0.00 0.00 0.00 684.00 948.00 706.00 0.00 0.00 0.00 0.00 757.00 948.00 706.00 0.00 0.00 0.00 0.00 300.00 948.00 757.00 0.00 0.00 0.00 0.00 0.00 948.00 757.00 0.00 0.00 0.00 0.00 0.00 948.00 757.00 0.00 0.00 0.00 0.00 0.00 948.00 757.00 0.00 0.00 0.00 0.00 0.00 948.00 757.00 0.00 0.00 0.00 0.00 0.00 948.00 757.00 0.00 0.00 0.00 0.00 0.00 948.00 757.00 0.00 0.00 0.00 0.00 0.00 948.00 757.00 0.00 0.00 0.00 0.00 0.00 948.00 757.00 0.00 0.00 0.00 0.00 0.00 948.00 757.00 0.00 0.00 0.00 0.00 0.00 948.00 757.00 0.00 0.00 0.00 0.00 0.00 948.00 757.00 0.00 0.00 0.00 0.00 360.00 948.00 757.00 0.00 0.00 0.00 0.00 215.00 948.00 757.00 360.00 0.00 0.00 0.00 354.00 948.00 757.00 360.00 0.00 0.00 0.00 69.00 948.00 757.00 360.00 0.00 0.00 0.00 0.00 948.00 757.00 360.00 0.00 0.00 0.00 0.00 948.00 757.00 360.00 0.00 0.00 0.00 0.00 948.00 757.00 360.00 0.00 0.00 0.00 0.00 948.00 757.00 360.00 0.00 0.00 0.00 0.00 948.00 757.00 360.00 0.00 0.00 0.00 0.00 948.00 757.00 360.00 0.00 0.00 0.00 0.00 948.00 757.00 360.00 0.00 0.00 0.00 0.00 948.00 757.00 360.00 0.00 0.00 0.00 0.00 948.00 757.00 360.00 0.00 0.00 0.00 0.00 948.00 757.00 360.00 0.00 0.00 0.00 0.00 948.00 757.00 360.00 0.00 0.00 0.00 0.00 948.00 757.00 360.00 0.00 0.00 0.00 0.00 948.00 757.00 360.00 0.00 0.00 0.00 0.00 948.00 757.00 360.00 0.00 0.00 0.00 0.00 948.00 757.00 360.00 0.00 0.00 0.00 0.00 948.00 757.00 360.00 0.00 0.00 0.00 0.00 948.00 757.00 360.00 0.00 0.00 0.00 0.00 948.00 757.00 360.00 0.00 0.00 0.00 10.00 948.00 757.00 360.00 0.00 0.00 0.00 107.00 948.00 757.00 360.00 10.00 0.00 0.00 86.00 948.00 757.00 360.00 107.00 0.00 0.00 55.00 948.00 757.00 360.00 107.00 0.00 0.00 793.00 948.00 757.00 360.00 107.00 0.00 0.00 900.00 948.00 757.00 360.00 793.00 0.00 0.00 899.00 948.00 757.00 360.00 900.00 0.00 0.00 900.00 948.00 757.00 360.00 900.00 0.00 0.00 934.00 948.00 757.00 360.00 900.00 0.00 0.00 948.00 948.00 757.00 360.00 934.00 0.00 0.00 938.00 948.00 757.00 360.00 948.00 0.00 0.00 938.00 948.00 757.00 360.00 948.00 0.00 0.00 937.00 948.00 757.00 360.00 948.00 0.00 0.00 940.00 948.00 757.00 360.00 948.00 0.00 0.00 942.00 948.00 757.00 360.00 948.00 0.00 0.00 931.00 948.00 757.00 360.00 948.00 0.00 0.00 939.00 948.00 757.00 360.00 948.00 0.00 0.00 935.00 948.00 757.00 360.00 948.00 0.00 0.00 917.00 948.00 757.00 360.00 948.00 0.00 0.00 910.00 948.00 757.00 360.00 948.00 0.00 0.00 910.00 948.00 757.00 360.00 948.00 0.00 0.00 911.00 948.00 757.00 360.00 948.00 0.00 0.00 909.00 948.00 757.00 360.00 948.00 0.00 0.00 900.00 948.00 757.00 360.00 948.00 0.00 0.00 889.00 948.00 757.00 360.00 948.00 0.00 0.00 872.00 948.00 757.00 360.00 948.00 0.00 0.00 862.00 948.00 757.00 360.00 948.00 0.00 0.00 857.00 948.00 757.00 360.00 948.00 0.00 0.00 861.00 948.00 757.00 360.00 948.00 0.00 0.00 853.00 948.00 757.00 360.00 948.00 0.00 0.00 824.00 948.00 757.00 360.00 948.00 0.00 0.00 825.00 948.00 757.00 360.00 948.00 0.00 0.00 825.00 948.00 757.00 360.00 948.00 0.00 0.00 835.00 948.00 757.00 360.00 948.00 0.00 0.00 836.00 948.00 757.00 360.00 948.00 0.00 0.00 832.00 948.00 757.00 360.00 948.00 0.00 0.00 847.00 948.00 757.00 360.00 948.00 0.00 0.00 848.00 948.00 757.00 360.00 948.00 0.00 0.00 845.00 948.00 757.00 360.00 948.00 0.00 0.00 857.00 948.00 757.00 360.00 948.00 0.00 0.00 891.00 948.00 757.00 360.00 948.00 0.00 0.00 911.00 948.00 757.00 360.00 948.00 0.00 0.00 921.00 948.00 757.00 360.00 948.00 0.00 0.00 939.00 948.00 757.00 360.00 948.00 0.00 0.00 942.00 948.00 757.00 360.00 948.00 0.00 0.00 946.00 948.00 757.00 360.00 948.00 0.00 0.00 940.00 948.00 757.00 360.00 948.00 0.00 0.00 944.00 948.00 757.00 360.00 948.00 0.00 0.00 941.00 948.00 757.00 360.00 948.00 0.00 0.00 935.00 948.00 757.00 360.00 948.00 0.00 0.00 876.00 948.00 757.00 360.00 948.00 0.00 0.00 737.00 948.00 757.00 360.00 948.00 0.00 0.00 558.00 948.00 757.00 360.00 948.00 0.00 0.00 0.00 948.00 757.00 360.00 948.00 0.00 0.00 0.00 948.00 757.00 360.00 948.00 0.00 0.00 0.00 948.00 757.00 360.00 948.00 0.00 0.00 0.00 948.00 757.00 360.00 948.00 0.00 0.00 0.00 948.00 757.00 360.00 948.00 0.00 0.00 0.00 948.00 757.00 360.00 948.00 0.00 0.00 0.00 948.00 757.00 360.00 948.00 0.00 0.00 0.00 948.00 757.00 360.00 948.00 0.00 0.00 0.00 948.00 757.00 360.00 948.00 0.00 0.00 0.00 948.00 757.00 360.00 948.00 0.00 0.00 0.00 948.00 757.00 360.00 948.00 0.00 0.00 0.00 948.00 757.00 360.00 948.00 0.00 0.00 0.00 948.00 757.00 360.00 948.00 0.00 0.00 0.00 948.00 757.00 360.00 948.00 0.00 0.00 0.00 948.00 757.00 360.00 948.00 0.00 0.00 0.00 948.00 757.00 360.00 948.00 0.00 0.00 0.00 948.00 757.00 360.00 948.00 0.00 0.00 0.00 948.00 757.00 360.00 948.00 0.00 0.00 0.00 948.00 757.00 360.00 948.00 0.00 0.00 347.00 948.00 757.00 360.00 948.00 0.00 0.00 932.00 948.00 757.00 360.00 948.00 347.00 0.00 947.00 948.00 757.00 360.00 948.00 932.00 0.00 945.00 948.00 757.00 360.00 948.00 947.00 0.00 939.00 948.00 757.00 360.00 948.00 947.00 0.00 923.00 948.00 757.00 360.00 948.00 947.00 0.00 896.00 948.00 757.00 360.00 948.00 947.00 0.00 816.00 948.00 757.00 360.00 948.00 947.00 0.00 684.00 948.00 757.00 360.00 948.00 947.00 0.00 463.00 948.00 757.00 360.00 948.00 947.00 0.00 0.00 948.00 757.00 360.00 948.00 947.00 0.00 0.00 948.00 757.00 360.00 948.00 947.00 0.00 0.00 948.00 757.00 360.00 948.00 947.00 0.00 0.00 948.00 757.00 360.00 948.00 947.00 0.00 0.00 948.00 757.00 360.00 948.00 947.00 0.00 0.00 948.00 757.00 360.00 948.00 947.00 0.00 0.00 948.00 757.00 360.00 948.00 947.00 0.00 0.00 948.00 757.00 360.00 948.00 947.00 0.00 0.00 948.00 757.00 360.00 948.00 947.00 0.00 0.00 948.00 757.00 360.00 948.00 947.00 0.00 0.00 948.00 757.00 360.00 948.00 947.00 0.00 0.00 948.00 757.00 360.00 948.00 947.00 0.00 0.00 948.00 757.00 360.00 948.00 947.00 0.00 0.00 948.00 757.00 360.00 948.00 947.00 0.00 343.00 948.00 757.00 360.00 948.00 947.00 0.00 759.00 948.00 757.00 360.00 948.00 947.00 343.00 636.00 948.00 757.00 360.00 948.00 947.00 759.00 763.00 948.00 757.00 360.00 948.00 947.00 759.00 770.00 948.00 757.00 360.00 948.00 947.00 763.00 631.00 948.00 757.00 360.00 948.00 947.00 770.00 0.00 948.00 757.00 360.00 948.00 947.00 770.00 0.00 948.00 757.00 360.00 948.00 947.00 770.00 0.00 948.00 757.00 360.00 948.00 947.00 770.00 0.00 948.00 757.00 360.00 948.00 947.00 770.00 0.00 948.00 757.00 360.00 948.00 947.00 770.00 0.00 948.00 757.00 360.00 948.00 947.00 770.00 0.00 948.00 757.00 360.00 948.00 947.00 770.00 0.00 948.00 757.00 360.00 948.00 947.00 770.00 0.00 948.00 757.00 360.00 948.00 947.00 770.00 0.00 948.00 757.00 360.00 948.00 947.00 770.00 0.00 948.00 757.00 360.00 948.00 947.00 770.00 0.00 948.00 757.00 360.00 948.00 947.00 770.00 0.00 948.00 757.00 360.00 948.00 947.00 770.00 0.00 948.00 757.00 360.00 948.00 947.00 770.00 0.00 948.00 757.00 360.00 948.00 947.00 770.00 0.00 948.00 757.00 360.00 948.00 947.00 770.00 0.00 948.00 757.00 360.00 948.00 947.00 770.00 0.00 948.00 757.00 360.00 948.00 947.00 770.00 0.00 948.00 757.00 360.00 948.00 947.00 770.00 0.00 948.00 757.00 360.00 948.00 947.00 770.00 0.00 948.00 757.00 360.00 948.00 947.00 770.00 0.00 948.00 757.00 360.00 948.00 947.00 770.00 0.00 948.00 757.00 360.00 948.00 947.00 770.00 0.00 948.00 757.00 360.00 948.00 947.00 770.00 0.00 948.00 757.00 360.00 948.00 947.00 770.00 0.00 948.00 757.00 360.00 948.00 947.00 770.00 0.00 948.00 757.00 360.00 948.00 947.00 770.00 0.00 948.00 757.00 360.00 948.00 947.00 770.00 127.00 948.00 757.00 360.00 948.00 947.00 770.00 147.00 127.00 0.00 0.00 0.00 0.00 0.00 137.00 147.00 0.00 0.00 0.00 0.00 0.00 112.00 147.00 0.00 0.00 0.00 0.00 0.00 103.00 147.00 0.00 0.00 0.00 0.00 0.00 538.00 147.00 0.00 0.00 0.00 0.00 0.00 850.00 538.00 0.00 0.00 0.00 0.00 0.00 816.00 850.00 0.00 0.00 0.00 0.00 0.00 784.00 850.00 0.00 0.00 0.00 0.00 0.00 777.00 850.00 0.00 0.00 0.00 0.00 0.00 560.00 850.00 0.00 0.00 0.00 0.00 0.00 323.00 850.00 0.00 0.00 0.00 0.00 0.00 0.00 850.00 0.00 0.00 0.00 0.00 0.00 |
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!