Inductive Proximity Sensor

The project is about a swing gate opener utilizing two motors.

I am trying to get the motors to work utilizing an arduino relay board and an inductive PNP (NO) proximity sensors.

What I am trying to achieve is that the door starts to open until it reaches and activates the proximity sensor. Then the door should stop and reverse until the sensor is deactivated.

The issue is that when I put a metal object to the proximity sensor the reaction is very slow and the door will hit and break the sensor. But when I remove the metal object the reaction is immediate and the motor stops.

The relay board is with 12V coils.
The proximity sensors are powered with 12V as well and a voltage divider is used to make the voltage 5V which goes to the arduino digital input.

I use two relays to make the motor go forward and reverse:

relay1

and

relay2

The third relay

relay3

switches a signal lamp on when the motor is activated.

The code does the following - the motor and the lamp indicator are switched on. If a high input from the proximity sensor is detected the motor and the indicator stop and the motor direction is reversed until the proximity sensor is deactivated and then the motor stops.

You can find the code attached.

int relay1 = 22;
int relay2 = 23;
int relay3 = 52;


void setup()
{
  pinMode(relay1, OUTPUT);
  pinMode(relay2, OUTPUT);
  pinMode(relay3, OUTPUT);
  pinMode(32, INPUT);
  //Serial.begin(9600);
}

void loop()
{
  delay(5000);
  
  digitalWrite(relay1, LOW);
  digitalWrite(relay2, HIGH);
  digitalWrite(relay3, LOW);


  
  
  if(digitalRead(32) == HIGH)
  {
    digitalWrite(relay1, HIGH);
    digitalWrite(relay2, HIGH);
    digitalWrite(relay3, HIGH);
    do
    {
      digitalWrite(relay1, HIGH);
      digitalWrite(relay2, LOW);
    }while(digitalRead(32) == HIGH);
    
    if(digitalRead(32)== LOW)
    {
      digitalWrite(relay1, HIGH);
      digitalWrite(relay2, HIGH);
    }
  }
}

Does Your proximity switch pull down to zero? Else I recimmend the input pin 32 declared as INPUT_PULLUP.
Could You mount Your sensor that the moving part is not travelling against the sensor? Passing by the sensor would be more mechanicaly safe.

Railroader:
Does Your proximity switch pull down to zero? Else I recimmend the input pin 32 declared as INPUT_PULLUP.
Could You mount Your sensor that the moving part is not travelling against the sensor? Passing by the sensor would be more mechanicaly safe.

I attached a schematic of my wiring.

The sensor will be stationary and the door will approach the sensor since it will be placed in the end position where the door should stop.

I tried to set pin 32 to INPUT_PULLUP but still have quite a bit of a delay. I read that if you set the input as a pull up it inverts the logic.

Okej. Use PULLUP only for that input. What values do You use in the voltage divider? Something near 10 kOhm I would use.

You use a relay board so free wheel, or kick back, diodes are probably provided by the board.
When dig32 is found HIGH You switch both relays ina very short time. My experience is that relays react quite a lot faster when they are turned on then when they turned off. Without seing Your wiring I guess that You migh get a short moment off a short on the 12 Volt. Then the pwr supply might cut off and wait before testing fore the short to be gone. I added a delay(100) to Your code.

What do You think?

int relay1 = 22;
int relay2 = 23;
int relay3 = 52;


void setup()
{
  pinMode(relay1, OUTPUT);
  pinMode(relay2, OUTPUT);
  pinMode(relay3, OUTPUT);
  pinMode(32, INPUT);
  //Serial.begin(9600);
}

void loop()
{
  delay(5000);

  digitalWrite(relay1, LOW);
  digitalWrite(relay2, HIGH);
  digitalWrite(relay3, LOW);




  if (digitalRead(32) == HIGH)
  {
    digitalWrite(relay1, HIGH);
//    digitalWrite(relay2, HIGH);//relay2 is already HIGH
    digitalWrite(relay3, HIGH);
    delay(100);//                        allow relay1 to release before relay2 is activated.
    digitalWrite(relay2, LOW);
    do
    {
      //      digitalWrite(relay1, HIGH);// relay1 is already set HIGH
      //      digitalWrite(relay2, LOW);// done above
    } while (digitalRead(32) == HIGH);

    if (digitalRead(32) == LOW)
    {
      //      digitalWrite(relay1, HIGH);//relay1 already is HIGH
      digitalWrite(relay2, HIGH);//DOES THIS WORK? realy2 is Active a very short time when dR32 goes LOW.
    }
  }
}

Please post a link to the exact proximity sensor you are using, or to the data sheet.

Most such sensors have several options for the output. Are you certain that yours is PNP, NO?

The diagram posted in reply #2 does not state the resistor values used on the output. Please add those values to the diagram and repost.

Also, add comments to your code, so that it is clear what is intended. For example, is this line testing for presence or absence of a conductive object within the sensor range?

  if (digitalRead(32) == HIGH)

Railroader:
Okej. Use PULLUP only for that input. What values do You use in the voltage divider? Something near 10 kOhm I would use.

You use a relay board so free wheel, or kick back, diodes are probably provided by the board.
When dig32 is found HIGH You switch both relays ina very short time. My experience is that relays react quite a lot faster when they are turned on then when they turned off. Without seing Your wiring I guess that You migh get a short moment off a short on the 12 Volt. Then the pwr supply might cut off and wait before testing fore the short to be gone. I added a delay(100) to Your code.

What do You think?

int relay1 = 22;

int relay2 = 23;
int relay3 = 52;

void setup()
{
 pinMode(relay1, OUTPUT);
 pinMode(relay2, OUTPUT);
 pinMode(relay3, OUTPUT);
 pinMode(32, INPUT);
 //Serial.begin(9600);
}

void loop()
{
 delay(5000);

digitalWrite(relay1, LOW);
 digitalWrite(relay2, HIGH);
 digitalWrite(relay3, LOW);

if (digitalRead(32) == HIGH)
 {
   digitalWrite(relay1, HIGH);
//    digitalWrite(relay2, HIGH);//relay2 is already HIGH
   digitalWrite(relay3, HIGH);
   delay(100);//                        allow relay1 to release before relay2 is activated.
   digitalWrite(relay2, LOW);
   do
   {
     //      digitalWrite(relay1, HIGH);// relay1 is already set HIGH
     //      digitalWrite(relay2, LOW);// done above
   } while (digitalRead(32) == HIGH);

if (digitalRead(32) == LOW)
   {
     //      digitalWrite(relay1, HIGH);//relay1 already is HIGH
     digitalWrite(relay2, HIGH);//DOES THIS WORK? realy2 is Active a very short time when dR32 goes LOW.
   }
 }
}

jremington:
Please post a link to the exact proximity sensor you are using, or to the data sheet.

Most such sensors have several options for the output. Are you certain that yours is PNP, NO?

The diagram posted in reply #2 does not state the resistor values used on the output. Please add those values to the diagram and repost.

Also, add comments to your code, so that it is clear what is intended. For example, is this line testing for presence or absence of a conductive object within the sensor range?

  if (digitalRead(32) == HIGH)

I attached a picture of the inductive sensor I have.

The relay board is an 8 channel arduino relay board and I guess it has all diodes it needs.

The relays are active LOW.

I actually utilize two relays in order to be able to run the motor forward and reverse.

I attached a wiring schematic of the relays connections, it does not include the switch, look at the relays contacts only.

I tried what Railroaded suggested and I think there is a bit of improvement in stopping the door but I think there is more delay when it reverses.

The input pin is HIGH when there is a metal object in front of the sensor.

Now I added comments to the code.

int relay1 = 22; // Motor Relay 1
int relay2 = 23; // Motor Relay 2
int relay3 = 52; // Relay for the lamp indicator


void setup()
{
  pinMode(relay1, OUTPUT);
  pinMode(relay2, OUTPUT);
  pinMode(relay3, OUTPUT);
  pinMode(32, INPUT); // Inductive Sensor Input
  //Serial.begin(9600);
}

void loop()
{
  delay(5000);
  
  digitalWrite(relay1, LOW);   // Relay 1 is ON and Relay 2 is OFF therefore the motor runs forward(door opens)
  digitalWrite(relay2, HIGH);
  digitalWrite(relay3, LOW);   // The lamp indicator is ON while the door is opening


  
  
  if(digitalRead(32) == HIGH)   // When the door(steel) reaches the stationary inductive sensor, there is a metal object in front the sensor therefore it is activated
  {
    digitalWrite(relay1, HIGH);   // The motor and the lamp indicator should first stop
    digitalWrite(relay2, HIGH);
    digitalWrite(relay3, HIGH);
    do
    {
      digitalWrite(relay1, HIGH);   // Relay 1 is OFF and Relay 2 is ON therefore the motor runs in reverse(door closes) until the sensor is deactivated
      digitalWrite(relay2, LOW);
    }while(digitalRead(32) == HIGH);
    
    if(digitalRead(32)== LOW)   // When the sensor is deactivated the motor should stop
    {
      digitalWrite(relay1, HIGH);
      digitalWrite(relay2, HIGH);
    }
  }
}

Your relay wiring is good, switching forward or backward. To me it looks like the relay coils are powered by 12 volt, the same as the motor.

The + in circle….. Does that go to the Arduino? I hope it passes a transistor because the Arduinos are made to handle max 5V, not 12V. You told about a relay board so I guess Your diagram is a principal diagram, not the actual wiring. I Think so, it makes sence.

Relays are active LOW You write. Do You mean that the Arduino pin goes low to activate the relay?
When the door is moving it moves until the sensor is reached, then both relays are switched off. Soo faar it looks okey to me.

Still hard to find out why stopping is slow. It can be the momentum of the motor. What does the start look like? Quick or slow?
Maybe a short pulse of reverse direction could help, if the power supply can handle it.

We'll keep on searching. The project is highly okey.

Reading Your code and relay diagram again…. There is very short time elapsing between switching OFF relay1 and switching ON relay2. During that short time the motor is short circuited, not the power supply as I suggested earlier. It is okey. However the pwr supply will maybe energize the motor to go backwards before the forward rotation has stopped and an owerload occurs. Is there any owerload indication on the pwr supply that makes a blinking? Look at my suggestion to Your code, a 100 mS delay….

Try this:

  if(digitalRead(32) == HIGH)   // When the door(steel) reaches the stationary inductive sensor, there is a metal object in front the sensor therefore it is activated
  {
    digitalWrite(relay1, HIGH);   // The motor and the lamp indicator should first stop
    digitalWrite(relay2, HIGH);
    digitalWrite(relay3, HIGH);
delay(100);// give time for the motor to stop. NEW CODE FROM Railroader 
   do
    {
      digitalWrite(relay1, HIGH);   // Relay 1 is OFF and Relay 2 is ON therefore the motor runs in reverse(door closes) until the sensor is deactivated
      digitalWrite(relay2, LOW);
    }while(digitalRead(32) == HIGH);

Hi,
Your wiring for the sensor is correct, you do not need pullup as this being PNP, the pulldown which you have supplied with the potential divider will do the job.


Do you have a DMM?

Tom.... :slight_smile:

Still waiting for these:

Please post a link to the exact proximity sensor you are using, or to the data sheet.

The diagram posted in reply #2 does not state the resistor values used on the output. Please add those values to the diagram and repost.

Railroader:
Your relay wiring is good, switching forward or backward. To me it looks like the relay coils are powered by 12 volt, the same as the motor.

The + in circle….. Does that go to the Arduino? I hope it passes a transistor because the Arduinos are made to handle max 5V, not 12V. You told about a relay board so I guess Your diagram is a principal diagram, not the actual wiring. I Think so, it makes sence.

Relays are active LOW You write. Do You mean that the Arduino pin goes low to activate the relay?
When the door is moving it moves until the sensor is reached, then both relays are switched off. Soo faar it looks okey to me.

Still hard to find out why stopping is slow. It can be the momentum of the motor. What does the start look like? Quick or slow?
Maybe a short pulse of reverse direction could help, if the power supply can handle it.

We'll keep on searching. The project is highly okey.

By saying that the relays are active LOW I mean that you have to send a LOW signal to activate the relay.

In the start it is always that the lamp indicator starts before the motor.

I power the arduino with 12V on the Vin pin but I can use the US.

Railroader:
Reading Your code and relay diagram again…. There is very short time elapsing between switching OFF relay1 and switching ON relay2. During that short time the motor is short circuited, not the power supply as I suggested earlier. It is okey. However the pwr supply will maybe energize the motor to go backwards before the forward rotation has stopped and an owerload occurs. Is there any owerload indication on the pwr supply that makes a blinking? Look at my suggestion to Your code, a 100 mS delay….

Try this:

  if(digitalRead(32) == HIGH)   // When the door(steel) reaches the stationary inductive sensor, there is a metal object in front the sensor therefore it is activated

{
    digitalWrite(relay1, HIGH);  // The motor and the lamp indicator should first stop
    digitalWrite(relay2, HIGH);
    digitalWrite(relay3, HIGH);
delay(100);// give time for the motor to stop. NEW CODE FROM Railroader
  do
    {
      digitalWrite(relay1, HIGH);  // Relay 1 is OFF and Relay 2 is ON therefore the motor runs in reverse(door closes) until the sensor is deactivated
      digitalWrite(relay2, LOW);
    }while(digitalRead(32) == HIGH);

I will try with the delay in the ''if'' statement.

TomGeorge:
Hi,
Your wiring for the sensor is correct, you do not need pullup as this being PNP, the pulldown which you have supplied with the potential divider will do the job.


Do you have a DMM?

Tom.... :slight_smile:

If you mean a digital multimeter, I have one.

jremington:
Still waiting for these:

I actually ordered an NPN (NO) sensors but I received PNP (NO).

The resistors are:

R1 = 100 ohms
R2 = 73 ohms (this is the resistor that goes to ground)

Soo faar, soo good meaning no obvious bad things found… More brainwork is needed,,,,

Your voltage divider will need 12 / ( 100 + 73 ) = 69 mA. Does the sensor support that much current?

Herureka! I think I found it.
What about this? Your 5000 mS delay in the beginning of loop() is the bastard! What is Your thought behind that? I don't see that so I ask. As long as the motor is running forward and the sensor at pin 32 is LOW the loop is spinning fast and spends nearly all the time hanging in "delay(5000)". What happends if the sensor goes active 1 mS after the sketch has entered the delay(5000)….? 4,999 seconds of owerrun.

Maybe there are things I'm not aware of so I suggest You to completely remove that delay, or decrease it to a few mS.

It got too late yesterday…….

New bids… Does the reverse relay kick in at all?
Can it be like this that the sensor first recognizes the metall but due to the inertia of the motor the metall comes too close to the sensor and it goes off?

Railroader:
Soo faar, soo good meaning no obvious bad things found… More brainwork is needed,,,,

Your voltage divider will need 12 / ( 100 + 73 ) = 69 mA. Does the sensor support that much current?

Herureka! I think I found it.
What about this? Your 5000 mS delay in the beginning of loop() is the bastard! What is Your thought behind that? I don't see that so I ask. As long as the motor is running forward and the sensor at pin 32 is LOW the loop is spinning fast and spends nearly all the time hanging in "delay(5000)". What happends if the sensor goes active 1 mS after the sketch has entered the delay(5000)….? 4,999 seconds of owerrun.

Maybe there are things I'm not aware of so I suggest You to completely remove that delay, or decrease it to a few mS.

It works now.

The reason for the delay(5000) was that I want the sequence to stop for a while and then run again. I could not think of a way to execute the program only once therefore I decided to just add a delay in order to know when the sequence is over and has started again. Apparently this is not the correct way to do it.

I added the a delay(100) as you suggested in the previous post without removing the delay(5000) and it did not work. Then I removed the delay(5000) and kept the delay(100) and it worked.

The next stage of the project is to implement the TFT screen and a password. Basically the password will be entered and the door should start opening. Then the door will stop after the sensor is activated and reverse until the sensor is deactivated. And then a button on the TFT screen should be pressed in order to close the door(the same sequence with the sensor) or I think to implement a real time clock and maybe after an hour of inactivity the door should close itself.

I am not sure how to make a "wait" function. For example, wait for the close button to be pressed and the program should not skip this and continue. If I use an "if" statement I think the program just skips it if it is not true.

What about the resistor value, are they fine?

Whow! Great that it works! Could You post this working, current code, just to be sure that no "unimportant" detail tricks us? I would also like to check my thinking yesterday. Totaly wrong I thought today, but Your sketch works... Strange to me.
Bed time here. I'll take a look at Your code tomorrow.
Maybe a

while(!close_button){};

could work?
What resistors do You think of? The voltage divider? Regarding the Arduino they are realy safe.

Railroader:
Whow! Great that it works! Could You post this working, current code, just to be sure that no "unimportant" detail tricks us? I would also like to check my thinking yesterday. Totaly wrong I thought today, but Your sketch works... Strange to me.
Bed time here. I'll take a look at Your code tomorrow.
Maybe a

while(!close_button){};

could work?
What resistors do You think of? The voltage divider? Regarding the Arduino they are realy safe.

I tried to implement the TFT display but I found another problem. The program just stopped randomly after some time running. Then I removed all the pins of the display from the arduino and the program worked. I tried to connect only the power pins of the TFT display - 3.3V, 5V and GND and the same problem again. I started to remove the pins one by one and when I removed 3.3V or GND the program started and worked normally. When I remove the 5V pin nothing happened. I tried to power the TFT from a digital pin by setting the pin to HIGH, still the same.

During the troubleshoot I got a spark on the arduino. I am not sure what shorted or if something was shorted but when I checked the voltage on the 5V pins it was around 3.7V. I had not measured it before.

Now when I run the same program the arduino just restarts itself and an LED called "L"(it is next to the "ON" LED) is blinking.

It is about the voltage divider resistor since you suggested values around 10k for the resistor, this was the reason I asked if the values were fine.

This is the code.

int relay1 = 22;
int relay2 = 23;
int relay3 = 52;

bool state = false;

void setup()
{
  pinMode(relay1, OUTPUT);
  pinMode(relay2, OUTPUT);
  pinMode(relay3, OUTPUT);
  pinMode(32, INPUT);
  //Serial.begin(9600);
}

void loop()
{
  delay(100);
  
  digitalWrite(relay1, LOW);
  digitalWrite(relay2, HIGH);
  digitalWrite(relay3, LOW);

  //state = digitalRead(32);
  
  
  if(digitalRead(32) == HIGH)
  {
    digitalWrite(relay1, HIGH);
    digitalWrite(relay2, HIGH);
    digitalWrite(relay3, HIGH);
    delay(100);
    do
    {
      digitalWrite(relay1, HIGH);
      digitalWrite(relay2, LOW);
    }while(digitalRead(32) == HIGH);
    
    if(digitalRead(32) == LOW)
    {
      digitalWrite(relay1, HIGH);
      digitalWrite(relay2, HIGH);
    }
  }
}

What to deal with right now? I think You need to check up Your hardare because of the incident You mentioned. Have You checked the power consumption of the TFT? Ground properly connected as well as Vcc….. How did You pwr Your project, from USB or other source? Program stopping more or less randomly after some time indicates an overload somewhere in my opinion.

Railroader:
What to deal with right now? I think You need to check up Your hardare because of the incident You mentioned. Have You checked the power consumption of the TFT? Ground properly connected as well as Vcc….. How did You pwr Your project, from USB or other source? Program stopping more or less randomly after some time indicates an overload somewhere in my opinion.

Yesterday I managed to make it work with the TFT display but it still resets itself from randomly.

I power the arduino from the USB and it works with the TFT display. It has just the reset problem.

If I power the arduino on the Vin pin with 12V it does not work with the TFT display. The arduino resets, the program starts and then nothing happens. I can not even reset the arduino manually utilizing the reset button.

Then I measured the current on the TFT display. On the 5V pin there is no current while on the 3.3V pin there about 900mA which I think is very high for the TFT display. Is it normal for the TFT display to have such a high current?

I tried to remove the 5V pin from the TFT and it was still powered. Then I removed the 3.3V pin from it therefore I had only the GND and all the other pins connected to the TFT. Surprisingly it was still powered only the brightness was a bit low which was strange for me.

The motor relays were initially activated (LOW) and I thought that they probably cause a short circuit. I set them to HIGH. Unfortunately still the same problem.

In the end I shorted the TFT display and it stopped working. I have to order a new display.

I retired a few years ago from doing door and gate automation. It sounds like you are doing something others have access to. (Password ? )

I don't want to be a killjoy or a nay sayer BUT beware of local laws and european directives regarding automation.

Liability definitely is a consideration in this age of litigation.

I ended up whereby my company had to fit infra red barrier beams, inductive ground loops (vehicle) and pneumatic safety strips (pedestrians) to meet all the requirements. It is also a european requirement that the closing force of a gate or door be measured and logged.

Please be careful for YOUR own sake. It's a red hot topic with health and safety.