====== Force sensor ======
//Necessary knowledge: [HW] [[en:hardware:homelab:sensor]], [HW] [[en:hardware:homelab:digi]], [AVR] [[en:avr:adc]], [LIB] [[en:software:homelab:library:adc]], [LIB] [[en:software:homelab:library:module:lcd_graphic]], [LIB] [[en:software:homelab:library:module:sensor]]//
===== Theory =====
[{{ :examples:sensor:force:09375-1.jpg?250|Force-sensing resistor}}]
[{{ :en:examples:sensor:forse_sensing_resistor.png?250|Force-sensing resistor layers}}]
FSR (force-sensing resistor) sensor allow you to detect physical pressure, squeezing and weight. FSR is basically a resistor that changes its resistive value (in ohms Ω) depending on how much it’s pressed. These sensors are fairly low cost and easy to use but they're rarely accurate. They also vary some from sensor to sensor perhaps 10%. It means when you use FSR's you should only expect to get ranges of response. As with all resistive based sensors force-sensing resistors require a relatively simple interface and can operate satisfactorily in moderately hostile environments. Compared to other force sensors, the advantages of FSR are their size and good shock resistance. However FSR will be damaged if pressure is applied for a longer time period (hours).
FSR consists of a conductive polymer, which changes resistance in a predictable manner following application of force to its surface. They are normally supplied as a polymer sheet or ink that can be applied by screen printing. The sensing film consists of both electrically conducting and non-conducting particles suspended in matrix. The particles are sub-micrometre sizes, and are formulated to reduce the temperature dependence, improve mechanical properties and increase surface durability. Applying a force to the surface of a sensing film causes particles to touch the conducting electrodes changing the resistance of the film.
Force-sensing resistors are commonly used to create pressure-sensing "buttons" and have applications in many fields, including musical instruments, car occupancy sensors, and robotics.
===== Practice =====
[{{ :en:examples:sensor:force_conductance_graph.png?250|Force conductance graph}}]
[{{ :en:examples:sensor:force_chematic.png?250|Voltage divider schematics for the sensor}}]
Pololu FSR with 12.7 mm diameter circular active area are exhibits a decrease in resistance with an increase in the force applied to the active surface. Its force sensitivity is optimized for use in human touch control of electronic devices. The force vs. resistance characteristic provides an overview of FSR typical response behavior. For interpretational convenience the force vs. resistance data is plotted on a log/log format. In general, FSR response approximately follows an inverse power-law characteristic (roughly 1/R).
The easiest way to measure a resistance of FSR is to connect one terminal to power and the other to a pull-down resistor to ground. Then the point between the fixed pull-down resistor and the variable FSR resistor is connected to the analogue input of a Controller board. In this configuration the analogue voltage reading ranges from 0V (ground) to about 5V (or about the same as the power supply voltage). As the resistance of the FSR decreases the total resistance of the FSR and the pull-down resistor decreases from about 100Kohm to 10Kohm. That means the current flowing through both resistors increases which in turn causes the voltage across the fixed 10K resistor to increase.
Measuring the Newton force by the FSR it is good idea to map analogue voltage reading ranges to 0 V to supply voltage. After that you can calculate the FSR resistance using following formula:
RFSR = ( (Vcc - U) * R1) / U
Where:
RFSR - FSR Resistance
Vcc – supply voltage. Usually 5 V
U – The measured voltage. The ADC reading must be converted to 0 V - Vcc
R1 – resistor. 10 k
Then you can calculate the conductivity CFSR in S/m [Siemens per meter]. The conductance is plotted vs. force (the inverse of resistance: 1/r). This format allows interpretation on a linear scale.
CFSR = 1 / RFSR
Use the FSR guide graphs on the datasheet to approximate the force. It depends on the measurable range. For example (0-1 Kg) low force range can be use formula:
FFSR = CFSR / 80
The example program of the force sensor shows the measured force (Newtons) and weight (kg) on the LCD.
#include
#include
#include
#include
#include
// Map a value from one range to another.
long map(long x, long in_min, long in_max, long out_min, long out_max)
{
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
// Main program
int main(void)
{
signed short value; // The analog reading.
char text[16];
int voltage; // The analog reading converted to voltage.
unsigned long resistance; // The voltage converted to resistance.
unsigned long conductance;
long force; // The resistance converted to force.
long weight; // The force converted to weight.
// Set the external sensors pins.
pin ex_sensors = PIN(G, 0);
pin_setup_output(ex_sensors);
pin_set(ex_sensors);
// LCD initialization.
lcd_gfx_init();
// Display clearing.
lcd_gfx_clear();
// Move the cursor to the right of the screen.
lcd_gfx_goto_char_xy(1,1);
// Print the name of the program.
lcd_gfx_write_string("Force sensor");
// Set the ADC.
adc_init(ADC_REF_AVCC, ADC_PRESCALE_8);
// An endless loop.
while (true)
{
// Converting and averaging channel 0 value.
value = adc_get_average_value(0, 4);
// Analog voltage reading ranges from about 0 to 1023
// which maps to 0V to 5V (= 5000mV)
voltage = map(value, 0, 1023, 0, 5000);
// The voltage = Vcc * R / (R + FSR) where R = 10K and Vcc = 5V
// so FSR = ( (Vcc - V) * R) / V
// fsrVoltage is in millivolts so 5V = 5000mV
resistance = 5000 - voltage;
resistance *= 10000; // 10K resistor
resistance /= voltage; // FSR resistance in ohms.
conductance = 1000000; //We measure in micromhos.
conductance /= resistance; //Conductance in microMhos.
// Move the cursor to the right of the screen.
lcd_gfx_goto_char_xy(1,3);
// Calculate the force.
force = conductance / 80;
sprintf(text, "%lu Newtons ", force);
// Printing of the force.
lcd_gfx_goto_char_xy(1,3);
lcd_gfx_write_string(text);
// Printing and calculating of the weight.
lcd_gfx_goto_char_xy(1,4);
weight = force / 9,8;
sprintf(text, "%lu kg ", weight);
lcd_gfx_write_string(text);
// Delay.
sw_delay_ms(500);
}
}