Basic emergency switch circuit

I have a “safety edge” which is used as a bumper on a robotic rover. If the robot runs into something the edge compresses and I need my arduino to cut the motor.

The safety edge is basically a 8k ohm resistor in normal position and then goes to 0 ohm when compressed. The specs on it say 24v and 10mA which I believe are the maximum values.

I believe this is super easy but I’m always confused about pulling pins low and not sure if this should be driven directly from the pin etc.

I can figure out the software interrupt side of this but what’s the right hardware circuit for this?

The standard way to read a resistance is to place it in a resistive divider circuit, and connect the divider voltage output to an ADC input. The divider can be powered by Vcc on your processor board. If you want to make it a digital input, you have to calculate divider values that place the output voltage in the correct input ranges for a HIGH and a LOW indication. Those are detailed in the processor data sheet. A good ball park guess at the companion resistor would be 1.0k.

Try with the following resistor divider circuit (Fig-1); where, R2 is the sensor that will be compressed.

vdiv
Figure-1:

When R2 is not compressed, the voltage at A0-pin is : 0.5V.
When R2 is compressed, the voltage at A0-pin is: 2.5V

You can execute the following codes:

void setup() 
{
  Serial.begin(9600);//// put your setup code here, to run once:
  unsigned int y = analogRead(A0);
  //Serial.println((5/1023.0)*y);
  if((5/1023.0)*y > 2.0)
  {
    Serial.println("Sensor is pressed.");
    //--take actions as needed
  }
  else
  {
    Serial.println("Sensor is not pressed.");
    //--take actions as needed
  }
}

void loop() {}

I guess you have something like this, but a link to your actual safety edge product and proposed wiring diagram would be great.

You should not use an interrupt for this. If you are convinced that you need to use an interrupt, you have some serious problems with your code, for example using "blocking" style code which relies on delay() for timing. You need to evolve beyond that style of coding if you want to make a robot.

It is good idea to use interrupt for this. It is a safety switch. If the program get stuck in an endless loop there is still chance interrupts are enabled and will save the day.
If more safety is needed disconnecting the motors by a HW may be considered.

Arguably safety cutoffs should be hardware only, directly wired, and in such a way that a connection failing triggers the cutoff. Then you only have to prove the hardware is correct, not both the hardware and the software....

Yep it’s exactly like that. It’s super simple…it’s 2 wires with a 8k ohm resistor between it. If it gets pressed the 2 wires get connected directly so the resistance goes to zero.

Really? :roll_eyes:

And just what will this interrupt do if the code has crashed? :thinking:

An "endless loop" would means the code itself is faulty. A processor crash means it is no longer initialised.

Why would you connect the sensor between two floating points in the circuit. Why not between the input and ground, and why a resistor in series with it?

And why use an analog read (which of course, does prevent the use of interrupts, not that it matters :grin:)?

These are not floating points:
When R2 is not pressed:

Va = 4.5V
Va0 = 0.5V

When R2 is pressed:

Va = 2.5V
Va0 = 2.5V

With the above arrangement, show me a circuit to inject bias current through the sensor that will be modulated when the sensor is pressed.

In your setup simply short out R1 or R3 and you have sensor that can be read by a digital input?

You mean the following:

If not, please, transform your above text into a circuit.

Just remove R1. i.e. make R1 zero ohms. No jumper across R3.

I would rather see it as a pull down, A0 connected to junction "A", R2 connected to ground on the other end, R1 between 5V and the sensor.

Can not prepare circuit based on above description.

1. Just remove R1. i.e. make R1 zero ohms. No jumper across R3.
ddivx

2. I would rather see it as a pull down,
Which one R2 or R3 that you want to see as pull-down?

3. A0 connected to junction "A"
ddivY

4. R2 connected to ground on the other end,
ddivC

5. R1 between 5V and the sensor.
R1 has gone in Step-1!

You really seem to be having some difficulty here, not sure why. :face_with_raised_eyebrow:

"Sensor" between Arduino input and ground.

Single pull-up resistor - 2k2 would be just fine - between Arduino input and 5 V.

Given that the sensor resistance is indeed 8k when not pressed, a digital input will read 3.7 V as a firm HIGH.

@anon57585045's description is different from that of you.

Now good!
ddivS

R2 is not pressed:
Voltage at A0-pin is: 3.9V (HIGH)

R2 is pessed:
Voltage at A0-pin = 0V (LOW)

Congratulation!

From the datasheet, the 8.2K is shown connected across the switch contacts. If INPUT_PULLUP for A0 is enabled, this will be 30-50K connected to 5V, so using 50K/8.2K there'll be an analog reading of about 144 when the switch is open, 0 when closed. Therefore, just detect if A0 < 50 for a closed switch (else open).
image

Saves one resistor. Any other advantage whatsoever of using an analog read?

I didn't go into it in detail., but you appeared to be having trouble. :grin:

  • User defined hysteresis
  • No debounce needed. It's a micro-switch (fast switching) and analog read takes 100μs
  • Switch diagnostics with aging and usage (i.e fix/replace if analogRead never goes below 10)
  • Fewer parts, fewer problems
  • Save $0.00076 (you said whatsoever)

Your description is meaningful and it can be transformed into a workable circuit.