Tag Archives: Interfacing

Using Ohmite Force sensitive potentiometers.

Force sensing potentiometers offer an alternative to mechanical potentiometers and rotary encoders. These devices do away the mechanical action of the switch and instead offer a touch sensitive alternative. After looking around the web I was not able to find a suitable library for implementing these devices so I ended up creating my own for Arduino.

The libraries implement functionality for Ohmite’s FSP series of devices. The devices include one round sensor (FPS03CE), and two linear devices (FSP01CE and FSP02CE). The linear devices come in two lengths.

All devices are single touch. This means that you can only detect one touch location on the device at a time. If we tried to detect a finger on each end of a linear device it would register as being in the middle.

For all devices the force is reported as voltage. Generally 3.2 volts is the highest we will see on a 3.3 volt system. The position is reported as an integer. For the FPS03CE the integer represents 0 to 360 degrees from the tail (connector) of the device. For the linear devices it is 0 to 100 mm for the FSP01CE and 0 to 55 mm for the FSP02CE. Default for the two linear devices is for zero at the tail, but the call to position command can take a parameter to return with 0 at the head end of the device.

Integration Guide:

I was only able to find one source for the integration guide — this pdf at Mouser. It is pretty comprehensive, but contains a couple of errors that an integrator should be aware of.

First: In the section for FSP0(1/2)CE on page 4

This section from the integration guide specifies V2 as an analog input. It does not need to be.

The document specifies that V2 should be an ADC pin. In measuring the force and position I have not read an Analog value from there. Not a show stopper, but there is no need to tie up an analog input unnecessarily. I changed this to a digital input and these sensors work correctly.

Second: In the section for FSP03CE on page 7:

This table for the FSP03CE pinout is not correct.

Using Figure 10: Pin 4 is actually the wiper pin, while pin 1 is the third drive electrode. Plus the Pin name for pin 2 is incorrect. Luckily this diagram makes it clear where the connections go.

From the integration guide.

Hook up:

Refer to this diagram when hooking up one the FSP devices.

Use this schematic when wiring up one of the FSP devices. VRef will use a digital I/O

Each device requires one analog input and multiple digital I/O lines. I used 22K for the FSP03CE voltage divider and 18K for both the linear variants. All are 1/4 watt 5%. VRef will use a digital I/O line. These resistor values worked for my application. The sensitivity of response to touch is affected by these values. This is detailed in the integration guide.

Arduino:
#include "M2aglabs_Ohmite.h"

//Set this to the one the Arduino uses
#define ANALOG_RESOLUTION 12
#define LINEAR_THRESHOLD  0.3
#define ROUND_THRESHOLD  0.3

/*
     Round sensor
     WIPER, VREF, D0, D120, D240
     Linear Sensor
     WIPER, VREF, V1, V2, true/false (Short or Long)
    WIPER and VREF are on two sides of a resistor. VREF floats for position measurements,
     PULLS low for force.

*/

M2aglabs_Ohmite roundSensor(A5, 0, 2, 1, 3);
M2aglabs_Ohmite lLinear(A2, 7, 6, 10, true);  //true means short
M2aglabs_Ohmite sLinear(A4, 5, 4, 9, false);  //false is long sensor

void setup() {
     Serial.begin(115200);
     /*
          The lib is set for a default of 10 for analog resolution and     3.3. for voltage. If the voltage is 5.0 set it here.

     */

     analogReadResolution(ANALOG_RESOLUTION);
     roundSensor.begin(ANALOG_RESOLUTION);
     sLinear.begin(ANALOG_RESOLUTION);
     lLinear.begin(ANALOG_RESOLUTION);

     //Set options --
     /*
     Serial.println(roundSensor.readRange());
     Serial.println(roundSensor.readRange(1500));
     Serial.println(roundSensor.zeroOffset());
     Serial.println(roundSensor.zeroOffset(500));
     */

}

void loop() {
     roundSensorActions();
     linearSensorActions();
}

void linearSensorActions() {

     int spos, lpos; //Position is an integer
     float fsp, flp; //Force is a float
     fsp = sLinear.getForce();
     if (fsp > LINEAR_THRESHOLD) {
          //False reads from tail to tip.
          spos = sLinear.getPosition(false);
          Serial.print("s: ");
          Serial.print(fsp);
          Serial.print(" : ");
          Serial.println(spos);
     }

     flp = lLinear.getForce();

     if (flp > LINEAR_THRESHOLD) {
          lpos = lLinear.getPosition(false);
          Serial.print("l: ");
          Serial.print(flp);
          Serial.print(" : ");
          Serial.println(lpos);

     }

}

void roundSensorActions() {

     //Get the force from the round sensor
     float force = roundSensor.getForce();
     //If it looks like we are touching it, calculate the position.

     if (force > ROUND_THRESHOLD) {
          Serial.print("force: ");
          Serial.print(force);
          int angle = roundSensor.getPosition();
          Serial.print(" raw angle: ");
          Serial.print(angle);
          angle = constrain(angle, 0, 360);
          Serial.print(" adjusted: ");
          Serial.println(angle);

     }

     return;

}

The function calls are documented in the header for the library.

Using the library:

Usage is fairly straightforward. The general steps are:

  • Instantiate the object
  • Call begin
  • Poll for force
  • If there is force applied read the position

The library has only been tested on a Metro M4, ItsyBitsy M4 and Raspberry Pi Pico to date. There is nothing that is SAMD specific so the Arduino library should work on other devices.

Two settings to be aware of are the _ZERO_OFFSET and _READ_RANGE. These affect each sensor’s overall range. The _ZERO_OFFSET specifies the normal zero reading of the ADC. With a finger at the 0 position of the sensor there is still a voltage present. Depending on the sensor, the voltage will be in the 200 to 800 millivolt range. If the sensor will not go to zero try adjusting this. For round sensors the 0’s are at 0 degrees (at the tail) then clockwise to 120 degrees, then 240. This is detailed in the integration guide.

Read range sets the maximum value of the voltage at the max end of the sensor. So if the lengths come out short, or max is hit before the end reached try adjusting this setting.

The library is available on github.

https://github.com/m2ag-labs/m2aglabs_ohmite

PI running indicator and shutdown button

Aug 2021

One of the things I want for my IoT devices is a smart power button. When off or in low power I would like to be able to press the button and have the device power on. If the device is on I want to press the power button and have the device shutdown safely and either power off or indicate that power can be shut off.

The PI has built in support for the seed of my solution in the form of device tree overlays  (dto) that can activate kernel support for a shut down signal and a powered down signal. I will be using these two features to implement a simple shutdown button and running indicator led. Not quite the feature set I am looking for, but this may be useful to pull out for some circumstances. Besides, if I can control an led at shut down I could send a signal to put the PI in low power or have it’s UPS shutdown.

There are many sources on the web that detail these two dto’s . The two I found most helpful were:

For shutdown signal:

https://www.raspberrypi.org/forums/viewtopic.php?t=217442

For toggling GPIO at shutdown:

https://www.raspberrypi.org/forums/viewtopic.php?t=223157

It should be noted that specifying the gpio pin to use is different in these two overlays. My implementation looks like this (in /boot/config.txt):

dtoverlay=gpio-shutdown,gpio_pin=17,active_low=1,gpio_pull=up

dtoverlay=gpio-poweroff,gpiopin=19,active_low=1

With this configuration I am monitoring pin 17 for a low signal to initiate system shut down. When the system has halted, pin 19 will go low. Pin 19 will go from low to high on startup.

When pin 19 signals shut down there are two low to high transitions that look like this:

So — using this line to control a running led would have the led on while running. When the system shuts down the led will blink once and then go out indicating it is safe to power off. Keeping the led lit adds 10 ma to the measured current draw of the PI. If this is a concern the logic could be reversed and the led could be made to illuminate at system shutdown. I’m going to be using the led as a running indicator, so it will be on while running.

This simple circuit is all that we need to implement our running indicator and shutdown switch.