Sensor Failure Handeling

@dkkelso, doing a little research on the interweb, there is no single technique for detecting an open or float condition between an analog sensor and the ADC input of the processor. It is very dependent on the sensor characteristics. A common approach is to discharge then pre-charge the ADC input capacitance to gauge if the input is being driven by the sensor or is floating. Using the built-in pull-up/down resistors with values of 40-50K ohms, this can work if the sensor has a larger output impedance but not so well when it is below 100K ohms. Can you share the model of pressure transducer you are using? Is it connected directly to the ADC input or through some conditioning circuit?

Hi. Thanks for the response.

I’m working on an abstract class that will take any sensor. The pressure transducer is just one example.

I don’t like having to write code over and over again, when I can just write it once.

So the transducer is an example. I have 25 more.

I don’t want to have to write code 26 times x n variations when I can just plug and play.

The common method you describe is what I showed from Stack, I believe.

But readAnalog on particle since like 0.53 doesn’t allow pull up or down, and I don’t believe can be overridden.

What I’m getting at is that I’m not certain that the common way is even possible using off the shelf particle firmware.

You are correct though it may be possible to force the pin into "analog" or "alternate function" INPUT mode which may allow the pull resistor to be applied, thus affecting the ADC input caps. Perhaps @rickkas7 has some hands-on knowledge he can chime in with.

I couldn’t get pull-up or pull-down on an analog input to work on a Photon. I’m not sure the STM32F2xx supports doing that. In any case, this code does not work:

// Non-working code, do not use
void setAdcPullDown(pin_t pin) {
	// Read once to initialize
	analogRead(pin);

    Hal_Pin_Info* PIN_MAP = HAL_Pin_Map();

    GPIO_TypeDef *gpio_port = PIN_MAP[pin].gpio_peripheral;
    pin_t gpio_pin = PIN_MAP[pin].gpio_pin;

    GPIO_InitTypeDef GPIO_InitStructure = {0};

    GPIO_InitStructure.GPIO_Pin = gpio_pin;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;

    // GPIO_PuPd_NOPULL, GPIO_PuPd_UP, or GPIO_PuPd_DOWN
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
    PIN_MAP[pin].pin_mode = AN_INPUT;

    GPIO_Init(gpio_port, &GPIO_InitStructure);
}

I ordered a debugger and an argon and a breakout adc so I’ll keep playing and see what I can come up with.

If I can pull it off on the breakout, then that’ll be good enough.

If it is that critical to determine that the sensor is functioning, maybe a voltage divider circuit can solve it? So it’s a simple and cheap hardware modification plus very little code to confirm. You’ll have to check my logic:

You’d have to sacrifice another input pin. And it will compress the range of values you can read from the sensor.
If the sensor is connected and working then the confirmation leg of the voltage divider will remain constant (say analog read of 2048), but as soon as the sensor fails and the 2nd leg is broken then the confirmation leg will shoot to 4095. Then you will know that the sensor leg must be floating.
Alternatively, depending on the circuit you may need to sum the confirmation leg and sensor leg which will be constant when working, Regardless, the confirmation leg reading will be near max when the sensor fails.

If you’d only consider software solutions this will not work for you.

This is interesting, thanks. I believe I would need one per sensor connected? So each sensor, of which there may be n sensors, would need n*2 input pins.

Not the end of the world, but limiting. If it becomes necessary, this would also be something I would be willing to do.

If you are certain that your failure mode is going to be open-circuit, you can use this method which leverages the parasitic capacitance of the pin when you suspect a problem:

Write digital HI
Set pin as input
Read digital state

Write digital LO
Set pin as input
Read digital state

Write digital HI
Set pin as input
Read digital state

If you get the values HI, LO, HI, then you have a pretty good idea that the pin is floating.

Please ensure the sensor can handle such an input, or protect it with a resistor or somesuch so you don’t damage it by back-driving it when you falsely suspect an error.

Thinking about this some more, there may be a range of mid-level values of sensor input that will interact badly with the hysteresis of the digital input, so you can substitute analog reads as long as they happen quickly enough and do not pull off too much charge.

I like the simplicity of this methodology a lot. If I damage a sensor or three, it isn’t the end of the world. I’ll just research a replacement thoroughly. And I can weed them out on the bench pretty quickly, most like.

Where this might give me trouble is some of the sensors are 5V. And because of that, I think the breakout ADC is necessary. I’m not sure how writing back to the breakout and then to the sensor is going to go. But I’m going to try it.

And if it fails, I can have two classes, a 3V3 analog and a breakout, and use this for the 3V3, and try something else for the breakout.

Thanks.