Motor and proximity sensors - continue for 1 second after sensor is tripped

Hi all,

I have posted about this project before and I’m in the final stages here. My (hopefully) last problem is one I hope to be a simple fix but I’ll wait to see what advice you all may have. Basically in this project I’m using an arduino mega, wifi shield, and motor controller board with a large DC motor to open and close a gate. The motor cycles between two proximity sensors which tell it when the gate is open or closed. All I’m trying to add to my code now is for the motor to continue turning for one second after the closing proximity sensor is triggered to ensure that the gate is shut tightly. I’ve tried a few different delay functions but it’s a bit tricky because as long as the proximity sensor is still reading LOW, it just keeps looping and the motor never stops, causing it to bear down super tight and try to break itself. Or it stops as soon as it reads the proximity sensor. Any advice?

#include <SPI.h>
#include <WiFi.h>

const int dir = 35;
const int pwm = 34;
const int proxyPin = 40;
const int proxyPin2 = 41;


char ssid[] = "";      //  SSID
char pass[] = "";   // password
int keyIndex = 0;                 
int proxyState = 0;
int proxyState2 = 0;


int status = WL_IDLE_STATUS;
WiFiServer server(80);

void setup() {
  Serial.begin(9600);      

  ////////////////////////////// Hardware I/O /////////////////////////////////
  
  pinMode(pwm, OUTPUT);     
  pinMode(dir, OUTPUT);
  pinMode(proxyPin, INPUT);
  pinMode(proxyPin2, INPUT);
  
////////////////////////////////// WiFi Startup /////////////////////////////////

  // check for the presence of the shield:
  if (WiFi.status() == WL_NO_SHIELD) {
    Serial.println("WiFi shield not present");
    while (true);       // don't continue
  }

  String fv = WiFi.firmwareVersion();
  if (fv != "1.1.0") {
    Serial.println("Please upgrade the firmware");
  }

  // attempt to connect to Wifi network:
  while (status != WL_CONNECTED) {
    Serial.print("Attempting to connect to Network named: ");
    Serial.println(ssid);                   // print the network name (SSID);

    // Connect to WPA/WPA2 network. Change this line if using open or WEP network:
    status = WiFi.begin(ssid, pass);
    // wait 10 seconds for connection:
    delay(10000);
  }
  server.begin();                           
  printWifiStatus();                        
}


void loop() {

/////////////////////////////////// WiFi loop ////////////////////////////////////

  WiFiClient client = server.available();   // listen for incoming clients

  if (client) {                             // if you get a client,
    Serial.println("new client");           // print a message out the serial port
    String currentLine = "";                // make a String to hold incoming data from the client
    while (client.connected()) {            // loop while the client's connected
      if (client.available()) {             // if there's bytes to read from the client,
        char c = client.read();             // read a byte, then
        Serial.write(c);                    // print it out the serial monitor
        if (c == '\n') {                    // if the byte is a newline character


    //////////////////////////////// Interface Design /////////////////////////////////////

          if (currentLine.length() == 0) {
            // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
            // and a content-type so the client knows what's coming, then a blank line:
            client.println("HTTP/1.1 200 OK");
            client.println("Content-type:text/html");
            client.println();

           
            client.print("<title>");
               client.print("AutoValve Control Page");
            client.print("</title>");
            
            client.print("

");
            
            client.print("<head>");
               client.print("<div style='font-size:60px'>");
                  client.print("<center> AutoValve Control Page </center>");
               client.print("</div>");
            client.print("</head>");
            
            client.print("

");
            
            // the content of the HTTP response follows the header:
            client.print("<body>");
                 client.print("<div style='font-size:60px'>");
                    client.print("<center> <a href=\"/Open\">OPEN</a> </center>");
                    client.print("
");
                    client.print("<center> <a href=\"/Close\">CLOSE</a> </center>");
                 client.print("</div>");
                 client.print("

");

             
                if (proxyState == LOW){
                  client.print("<div style='font-size:45px'>");
                     client.print("<center> Current Position: CLOSED </center>");
                  client.print("</div>");
               }
               
               if (proxyState2 == LOW){
                  client.print("<div style='font-size:45px'>");
                      client.print("<center>  Current Position: OPEN </center>");
                  client.print("</div>");
               }

           client.print("</body>");

             
            // The HTTP response ends with another blank line:
            client.println();
            // break out of the while loop:
            break;
          } else {    // if you got a newline, then clear currentLine:
            currentLine = "";
          }
        } else if (c != '\r') {  // if you got anything else but a carriage return character,
          currentLine += c;      // add it to the end of the currentLine
        }



 ///////////////Hardware control loop//////////////////////////

 digitalWrite(pwm, LOW);

 proxyState = digitalRead(proxyPin);
 proxyState2 = digitalRead(proxyPin2);
 
   if (currentLine.endsWith("GET /Open") && (proxyState == LOW)) {
     digitalWrite(pwm, HIGH);  //turn the motor on
     digitalWrite(dir, HIGH);  //in the opening direction
    
         while(digitalRead(proxyPin2) == HIGH){     //as long as proxy2 is not triggered
            digitalWrite(pwm, HIGH);                  //keep motor on 
            digitalWrite(dir, HIGH);                //in the opening direction
               }
               }
       if(proxyState2 == LOW){
         digitalWrite(pwm, LOW);     //when proxy2 is triggered, turn the motor off
             }



             
  if (currentLine.endsWith("GET /Close") && (proxyState2 == LOW)) {
     digitalWrite(pwm, HIGH);  //turn the motor on
     digitalWrite(dir, LOW);  //in the closing direction
    
      while(digitalRead(proxyPin) == HIGH){     //as long as proxy1 is not triggered
         digitalWrite(pwm, HIGH);                //keep motor on 
         digitalWrite(dir, LOW);                //in the closing direction
    }
    }
   if(proxyState == LOW){                 //***Continue for 1 second after proxyPin reads LOW
    delay(1000);
    digitalWrite(pwm, LOW);                //***NOT WORKING*** 
        }
      }
      
    }
 ///////////////////////////////////// WiFi close loop //////////////////////////////////
    // close the connection:
    client.stop();
    Serial.println("client disonnected");
  }
}

void printWifiStatus() {
  // print the SSID of the network you're attached to:
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  // print your WiFi shield's IP address:
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);

  // print the received signal strength:
  long rssi = WiFi.RSSI();
  Serial.print("signal strength (RSSI):");
  Serial.print(rssi);
  Serial.println(" dBm");
  // print where to go in a browser:
  Serial.print("To see this page in action, open a browser to http://");
  Serial.println(ip);
}

I've tried this delay function but it's a bit tricky because as long as the proximity sensor is still reading LOW, it just keeps looping and the motor never stops, causing it to bear down super tight and try to break itself.

Try this statement again WITHOUT using "it". We have no idea what "it" refers to.

const int proxyPin = 40;
const int proxyPin2 = 41;

So, you have two proximity sensors numbered uh-huh and two. Why? One and two make more sense.

    digitalWrite(pwm, LOW);                //***NOT WORKING***

It IS working. The next iteration of loop() will find that the proximity sensor is low, because the gate is closed, so it will try to run the motor some more.

You need a variable to keep track of the state of the gate - open, opening, closed, closing, etc. When the gate is closing, and the proximity sensor becomes low, run the motor for one second longer, then shut it off and set the state to closed.

If the gate is closed, don't try to close it more.

PaulS:
You need a variable to keep track of the state of the gate - open, opening, closed, closing, etc. When the gate is closing, and the proximity sensor becomes low, run the motor for one second longer, then shut it off and set the state to closed.

Hmm yeah so are you suggesting switch/case statements or boolean?

The term you want to learn about is "finite state machine". Don't even look at the Wikipedia page for that. It's got a bunch of confusing math theory that nobody cares about. Actually coding one is dirt simple and yes usually involves a switch/case.

Thanks, I'll check it out.