Motor - Count time - Change direction

Hello,
I have done some projects involving DC motors with Arduino but now I have some problems.
I need to control a DC motor through a H-bridge.
The motor starts in one direction when PIR detects someone, then stops when no one is there, and then again and etc.
When the addition of the working time of the motor reach 12 minutes in one direction, the cycle starts again but in the other direction and so on.
If you have any ideas are more than welcome
Thanks a lot
echigard

Reading a PIR is quite simple. Driving a motor is not difficult. Remembering elapsed time is also simple, just think millis().

Please tell us exactly what PIR, motor and motor driver you are using and post your best attempt at a progam that does what you have described. Then we will have something to start helping with.

Steve

Thank you Steve,
I didn't think about millis().
I will work on it and I'll be back
edgardo

The demo Several Things at a Time illustrates the use of millis() to manage timing. It may help with understanding the technique.

Have a look at Using millis() for timing. A beginners guide if you need more explanation.

...R

Great Robin!
Thanks a lot.
I will start with the beginners guide.
I need to count only the amount of time the motor is ON until it reach 12 minutes despite the time it was stop.
I have to arrive to manage it.

Thank you again

edgardo

echigard:
I need to count only the amount of time the motor is ON until it reach 12 minutes despite the time it was stop.

That sort of thing is often a problem of thinking clearly rather than of writing code. Keep in mind that the computer is very stupid so you have to be its brains.

...R

Hi guys,
in this time I was working in my project and I decided to change some things.
Basically it is a turntable that start to move in one direction when the PIR detect movement in the room and stops when the movement stops.
Continue in that way until the end of one turn, then the turntable press a button which changes motor direction and the process starts again but backwards. And so on.
So the PIR manages the start and stop of the motor and two buttons manage the motor direction.
I’m working with ARDUINO UNO, H-Bridge, PIR sensor Parallax and 2 buttons.
I have already donne the sketch for the PIR base on a sketch by Kristian Gohlke and it works fine. Also I did the sketch for the motor direction change with some help of a colleague and also works fine.
What I can not resolve and that’s why I’m asking for help, is combine both. I try several way of combine it, I read a lot of posts in the forum and notes arround but really I can not make it work
Here my functional sketches
PIR code

/* 
 
 * Based on the sketch by Kristian Gohlke / krigoo (_) gmail (_) com / http://krx.at
 * @date:   3. September 2006 
 * kr1 (cleft) 2006 
 * released under a creative commons "Attribution-NonCommercial-ShareAlike 2.0" license
 * http://creativecommons.org/licenses/by-nc-sa/2.0/de/
 *
 *
 *
 * The sensor's output pin goes to HIGH if motion is present.
 * However, even if motion is present it goes to LOW from time to time, 
 * which might give the impression no motion is present. 
 * This program deals with this issue by ignoring LOW-phases shorter than a given time, 
 * assuming continuous motion is present during these phases.
 *  
 */

/////////////////////////////
//VARS
//the time we give the sensor to calibrate (10-60 secs according to the datasheet)
int calibrationTime = 30;        

//the time when the sensor outputs a low impulse
long unsigned int lowIn;
//the amount of milliseconds the sensor has to be low
//before we assume all motion has stopped
long unsigned int pause = 10000;
boolean lockLow = true;
boolean takeLowTime;
int pirPin = 2;    //the digital pin connected to the PIR sensor's output
int IN3 = 5; 
int IN4 = 4;
int ENB = 3; // ENB conectada al pin 3 de Arduino
/////////////////////////////
//SETUP
void setup() {
  Serial.begin(9600);
  pinMode (ENB, OUTPUT); 
  pinMode (IN4, OUTPUT);    // Input4 conectada al pin 4 
  pinMode (IN3, OUTPUT);    // Input3 conectada al pin 5
  pinMode(pirPin, INPUT);
 
 digitalWrite(pirPin, LOW);

  //give the sensor some time to calibrate
  Serial.print("calibrating sensor ");
    for(int i = 0; i < calibrationTime; i++){
      Serial.print(".");
      delay(1000);
      }
    Serial.println(" done");
    Serial.println("SENSOR ACTIVE");
    delay(50);
  }

////////////////////////////
//LOOP
void loop() {
  if (digitalRead(pirPin) == HIGH && millis() > 1000) {
    // Motor gira en un sentido
  analogWrite(ENB,220);
  digitalWrite (IN4, HIGH);
  digitalWrite (IN3, LOW); 
    
    if (lockLow) {
      //makes sure we wait for a transition to LOW before any further output is made:
      lockLow = false;
      Serial.println("---");
      Serial.print("motion detected at ");
      Serial.print(millis() / 1000);
      Serial.println(" sec");
      delay(50);
    }
    takeLowTime = true;
  }
  if (digitalRead(pirPin) == LOW) {
    if (takeLowTime) {
      lowIn = millis();          //save the time of the transition from high to LOW
      takeLowTime = false;       //make sure this is only done at the start of a LOW phase
    }
    //if the sensor is low for more than the given pause,
    //we assume that no more motion is going to happen
    if (!lockLow && millis() - lowIn > pause) {
      //makes sure this block of code is only executed again after
      //a new motion sequence has been detected
      lockLow = true;
      Serial.print("motion ended at ");      //output
      Serial.print((millis() - pause) / 1000);
      Serial.println(" sec");
      delay(50);
      analogWrite(ENB,220);
  digitalWrite (IN4, LOW); 
    }
  }
}

Buttons code

const int buttonForwardPin = 8;     // the number of the pushbutton pin
const int buttonRewersePin = 9;     // the number of the pushbutton pin
const int IN3 = 5; 
const int IN4 = 4;
const int ENB = 3; 
int buttonStateF = 0;
int buttonStateR = 0;
int IN3State = LOW;
int IN4State = LOW;
void setup() {
  // put your setup code here, to run once:

  pinMode(ENB, OUTPUT);
  pinMode(IN4, OUTPUT);
  pinMode(IN3, OUTPUT);
  pinMode(buttonRewersePin, INPUT);
  pinMode(buttonForwardPin, INPUT);
digitalWrite(IN3, LOW);
digitalWrite(IN4, LOW);
digitalWrite(buttonRewersePin, 0);
digitalWrite(buttonForwardPin, 0);
  
}

void loop() {
  buttonStateF = digitalRead(buttonForwardPin);
  buttonStateR = digitalRead(buttonRewersePin);

  // check if the pushbutton is pressed.
  // if it is, the buttonState is HIGH:
  if (buttonStateF == 1) {

    digitalWrite(IN4, HIGH);
    digitalWrite(IN3, LOW);
    analogWrite(ENB, 255);
    buttonStateR = 0;
  }
  if (buttonStateR == 1) {

    digitalWrite(IN4, LOW);
    digitalWrite(IN3, HIGH);
    analogWrite(ENB, 250);
    buttonStateF = 0;
  }
  buttonStateR = 0;
  buttonStateF = 0;
  // FORWARD

  delay(1000);

}

Any ideas and suggestions are more than welcome.
Thank you very much on advance.

rudni

Please post your best attempt at combining the two sketches and we can start from there.

Steve

Thank you Steve,
I have one sketch I was working yesterday. I feel embarrassed but I will post it.
Thank you again.

//VARS
//the time we give the sensor to calibrate (10-60 secs according to the datasheet)
int calibrationTime = 30;        

//the time when the sensor outputs a low impulse
long unsigned int lowIn;
//the amount of milliseconds the sensor has to be low
//before we assume all motion has stopped
long unsigned int pause = 10000;
boolean lockLow = true;
boolean takeLowTime;
const int pirPin = 2;    //the digital pin connected to the PIR sensor's output
const int button1Pin = 2;     // the number of the pushbutton1 pin
const int button2Pin = 7;     // the number of the pushbutton2 pin
const int IN3 = 5; 
const int IN4 = 4;
const int ENB = 3;   
int button1State = 0;         // variable for reading the pushbutton status
int button2State = 0;         // variable for reading the pushbutton

void setup() { 

  //start serial connection
  Serial.begin(9600);
    // initialize the pushbutton pin as an input:
  pinMode(button1Pin, INPUT);     
  pinMode(button2Pin, INPUT);   
  digitalWrite (button1Pin, HIGH);
  digitalWrite (button2Pin, HIGH); 
  // initialize the relay pin as an output:
 pinMode (ENB, OUTPUT); 
  pinMode (IN4, OUTPUT);    // Input4 conectada al pin 4 
  pinMode (IN3, OUTPUT);
  //preset the relays to LOW
  digitalWrite(IN3, LOW); 
  digitalWrite(IN4, LOW); 
   pinMode(pirPin, INPUT);
 
 digitalWrite(pirPin, LOW);

  //give the sensor some time to calibrate
  Serial.print("calibrating sensor ");
    for(int i = 0; i < calibrationTime; i++){
      Serial.print(".");
      delay(1000);
      }
    Serial.println(" done");
    Serial.println("SENSOR ACTIVE");
    delay(50);
  }

  


void loop() {
 
// read the state of the pushbutton values:
  button1State = digitalRead(button1Pin);
  button2State = digitalRead(button2Pin);

  if ((button1State == HIGH) && (digitalRead(pirPin) == HIGH && millis() > 1000)) {
    // Motor gira en un sentido
  analogWrite(ENB,220);
  digitalWrite (IN4, HIGH);
  digitalWrite (IN3, LOW); 
    
    if (lockLow) {
      //makes sure we wait for a transition to LOW before any further output is made:
      lockLow = false;
      Serial.println("---");
      Serial.print("motion detected at ");
      Serial.print(millis() / 1000);
      Serial.println(" sec");
      delay(50);
    }
    takeLowTime = true;
  }{     
   analogWrite(ENB,220);
  digitalWrite (IN4, HIGH);
  digitalWrite (IN3, LOW);         
    }  
    if ((button1State == HIGH) && (digitalRead(pirPin) == LOW)) {
    if (takeLowTime) {
      lowIn = millis();          //save the time of the transition from high to LOW
      takeLowTime = false;       //make sure this is only done at the start of a LOW phase
    }
    //if the sensor is low for more than the given pause,
    //we assume that no more motion is going to happen
    if (!lockLow && millis() - lowIn > pause) {
      //makes sure this block of code is only executed again after
      //a new motion sequence has been detected
      lockLow = true;
      Serial.print("motion ended at ");      //output
      Serial.print((millis() - pause) / 1000);
      Serial.println(" sec");
      delay(50);
      analogWrite(ENB,220);
  digitalWrite (IN4, LOW); 
    }


  if ((button2State == HIGH) && (digitalRead(pirPin) == HIGH && millis() > 1000)) {
    // Motor gira en un sentido
  analogWrite(ENB,220);
  digitalWrite (IN4, LOW);
  digitalWrite (IN3, HIGH); 
    
    if (lockLow) {
      //makes sure we wait for a transition to LOW before any further output is made:
      lockLow = false;
      Serial.println("---");
      Serial.print("motion detected at ");
      Serial.print(millis() / 1000);
      Serial.println(" sec");
      delay(50);
    }
    takeLowTime = true;
  }
    if ((button2State == HIGH) && (digitalRead(pirPin) == LOW)) {
    if (takeLowTime) {
      lowIn = millis();          //save the time of the transition from high to LOW
      takeLowTime = false;       //make sure this is only done at the start of a LOW phase
    }
    //if the sensor is low for more than the given pause,
    //we assume that no more motion is going to happen
    if (!lockLow && millis() - lowIn > pause) {
      //makes sure this block of code is only executed again after
      //a new motion sequence has been detected
      lockLow = true;
      Serial.print("motion ended at ");      //output
      Serial.print((millis() - pause) / 1000);
      Serial.println(" sec");
      delay(50);
      analogWrite(ENB,220);
  digitalWrite (IN3, LOW); 
    }
 }
  }
   }

Both pirPin and button1Pin are defined as being pin 2. You can't have them both connected to that same pin. Once you fix that you can test the program and tell us what it is doing that is different from what you want it to do.

Steve

Thank you Steve, I didn’t see it!!!
It’s night here, tomorrow morning I will try it.

rudni

I’m back.
I have arrange what Steve pointed me yesterday and I arranged another things. It works bad but …
When it starts the sensor calibrates and then the sensor detects the movement.
But without ant button pressed once movement is detected the motor starts following the directions of the button in Pin 9, if I push the 8 it changes direction but only if I am pushing when I leave it the motor returns to the other direction. I would need that the momentary pressure fix the direction until the next change.
When the movement stops the motor stops. But the PIR is not waiting for the transition (PAUSE TIME) to LOW.
Here the modified code

//VARS
//the time we give the sensor to calibrate (10-60 secs according to the datasheet)
int calibrationTime = 30;        

//the time when the sensor outputs a low impulse
long unsigned int lowIn;
//the amount of milliseconds the sensor has to be low
//before we assume all motion has stopped
long unsigned int pause = 10000;
boolean lockLow = true;
boolean takeLowTime;
const int pirPin = 2;    //the digital pin connected to the PIR sensor's output
const int button1Pin = 8;     // the number of the pushbutton1 pin
const int button2Pin = 9;     // the number of the pushbutton2 pin
const int IN3 = 5; 
const int IN4 = 4;
const int ENB = 3;   
int button1State = 0;         // variable for reading the pushbutton status
int button2State = 0;         // variable for reading the pushbutton

void setup() { 

  //start serial connection
  Serial.begin(9600);
    // initialize the pushbutton pin as an input:
  pinMode(button1Pin, INPUT);     
  pinMode(button2Pin, INPUT);   
digitalWrite(button1Pin, LOW);
digitalWrite(button2Pin, LOW);
  // initialize the H-Bridge pin as an output:
 pinMode (ENB, OUTPUT); 
  pinMode (IN4, OUTPUT);   
  pinMode (IN3, OUTPUT);
  
  digitalWrite(IN3, LOW); 
  digitalWrite(IN4, LOW); 
   pinMode(pirPin, INPUT);
 
 digitalWrite(pirPin, LOW);

  //give the sensor some time to calibrate
  Serial.print("calibrating sensor ");
    for(int i = 0; i < calibrationTime; i++){
      Serial.print(".");
      delay(1000);
      }
    Serial.println(" done");
    Serial.println("SENSOR ACTIVE");
    delay(50);
  }

void loop() {
 
// read the state of the pushbutton values:
  button1State = digitalRead(button1Pin);
  button2State = digitalRead(button2Pin);
  digitalRead(pirPin);

  if (digitalRead(pirPin) == HIGH && millis() > 1000) {
  if (button1State == HIGH){
        // Motor one direction
  analogWrite(ENB,220);
  digitalWrite (IN4, HIGH);
  digitalWrite (IN3, LOW); 
   } 
   else if (digitalRead(pirPin) == HIGH && millis() > 1000) {
    if (button2State == HIGH);
  
    // Motor other direction
  analogWrite(ENB,220);
  digitalWrite (IN4, LOW);
  digitalWrite (IN3, HIGH);
    } 
    if (lockLow) {
      //makes sure we wait for a transition to LOW before any further output is made:
      lockLow = false;
      Serial.println("---");
      Serial.print("motion detected at ");
      Serial.print(millis() / 1000);
      Serial.println(" sec");
      delay(50);
  }  
    takeLowTime = true;
 }
   else if (digitalRead(pirPin) == LOW) {
    if (takeLowTime) {
      lowIn = millis();          //save the time of the transition from high to LOW
      takeLowTime = false;       //make sure this is only done at the start of a LOW phase
    }
    //if the sensor is low for more than the given pause,
    //we assume that no more motion is going to happen
    if (!lockLow && millis() - lowIn > pause) {
      //makes sure this block of code is only executed again after
      //a new motion sequence has been detected
      lockLow = true;
      Serial.print("motion ended at ");      //output
      Serial.print((millis() - pause) / 1000);
      Serial.println(" sec");
      delay(50);
      analogWrite(ENB,0);
  
    }

      delay(50);
      analogWrite(ENB,0);
 
     }
    }

Thank you

rudni