How to stop the motor

I basically have the two thing happening that I want the motor turns one way if the photocell is above 300 and the other way if its not but it just runs over and over and I want it to just run once then stop until the photocell goes above or below a value

So if I were to write this out without knowing code it would go like this

If the light goes above 300 then turn the motor forward for 2 seconds then stop
If the light goes below 100 then turn the motor backwards for 2 seconds then stop

Bonus I would also like to incorporate a button to run the above manually so I can run the motor one way or the other depending on its forward or backwards state. So if motor is was run forward run the motor backwards for 2 seconds etc… like a photocell override

Here is my code thus far that runs the motor over and over in one direction if the light threshold is above 300 and then reverses if below 300

#include <math.h>

int pinI1=8;//define I1 interface
int pinI2=11;//define I2 interface 
int speedpinA=9;//enable motor A
int spead =255;//define the spead of motor
int sensorValue = 0;  
int sensorPin = 0;  

const int ledPin=12;                 //Connect the LED Grove module to Pin12, Digital 12
const int thresholdvalue=10;         //The treshold for which the LED should turn on. Setting it lower will make it go on at more light, higher for more darkness
float Rsensor; //Resistance of sensor in K
void setup() {
  Serial.begin(9600);                //Start the Serial connection
  pinMode(ledPin,OUTPUT);            //Set the LED on Digital 12 as an OUTPUT
  pinMode(pinI1,OUTPUT);
  pinMode(pinI2,OUTPUT);
  pinMode(speedpinA,OUTPUT);
}

void forward()
{
     analogWrite(speedpinA,spead);//input a simulation value to set the speed
     digitalWrite(pinI2,LOW);//turn DC Motor A move anticlockwise
     digitalWrite(pinI1,HIGH);
}
void backward()//
{
     analogWrite(speedpinA,spead);//input a simulation value to set the speed
     digitalWrite(pinI2,HIGH);//turn DC Motor A move clockwise
     digitalWrite(pinI1,LOW);
}
void stop()//
{
     digitalWrite(speedpinA,LOW);// Unenble the pin, to stop the motor. this should be done to avid damaging the motor. 
     delay(60000);
 
}

void loop() {

  
sensorValue = analogRead(sensorPin);  //get the value from input pin
  Serial.println(sensorValue);  //print the value to Serial monitor
  delay(2000);

      if (sensorValue < 300) //if there is darkness then turn motor on

      {
  forward();
  delay(1000);
  stop();
      }
      else
      {
  backward();
  delay(1000); 
  stop(); 
      }

}

Thank you for the help
Jamie

So if I were to write this out without knowing code it would go like this

If the light goes above 300 then turn the motor forward for 2 seconds then stop
If the light goes below 100 then turn the motor backwards for 2 seconds then stop

Stop forever, as in never run again?

So you're looking for a signal edge, or when the sensor value goes from below 300 to above 300. Keep track of the last value that you read. If that value is less than or equal to 300 and the new value is greater than 300, then perform your action.

PaulS: Not forever, run 1 time when above 300 run once when below 300.

Its a door that opens once in the morning then close once in the evening.

There are two ways to structure this code.

If you are certain that you will never need this sketch to do anything else apart from open and close the door, you can write a simple blocking sketch that waits for the light to come up and then opens the door, waits for the light to go down then closes the door. This is the simplest approach but note that this approach really doesn't lend itself at all to doing anything else in the same sketch.

The more general approach is to write a non-blocking sketch that uses a state machine to know whether it is opening, open, closing, closed; use elapsed time and light levels to change state and turn the motor on and off according to which state it's in. This is much more elegant but harder to get right. If you haven't done this before then you might want to start with the simple blocking approach first, then come back to the non-blocking approach later.

PeterH:
If you are certain that you will never need this sketch to do anything else apart from open and close the door, you can write a simple blocking sketch that waits for the light to come up and then opens the door, waits for the light to go down then closes the door. This is the simplest approach but note that this approach really doesn't lend itself at all to doing anything else in the same sketch.

At the moment all I want the sketch to do is open and close the door so I think the simple blocking sketch is the way to go for now.

Based on my code above what do I need to do to make it a simple blocking sketch?

jhiner1978:
Based on my code above what do I need to do to make it a simple blocking sketch?

Write code that does the four steps I listed in the right order. You could do it something like this:

// Make sure that DAWN_THRESHOLD is slightly higher than DUSK_THRESHOLD, otherwise slight variations in light around dawn/dusk will make the door open/close

// wait for dawn
while(analogRead(sensorPin) < DAWN_THRESHOLD)
{
  // it's nighttime - do nothing
}
// now it is dawn

openDoor();

// wait for dusk
while(analogRead(sensorPin) > DUSK_THRESHOLD)
{
  // it's daytime - do nothing
}
// now it is dusk

closeDoor();

Put that code in loop(), and it will open and close the door once per day. Don’t plan to do anything else at the same time, though, because this blocking approach isn’t the right way to do multiple things concurrently. If you want to add features to your sketch after you have got this blocking approach working, I strongly suggest you move to a non-blocking approach as the next step.

Thanks PeterH i'll give that a try this evening. Just as a reference in the future what is an example of the other way of doing it?

Would there be a way to add a push button to close if open and open if closed

Cheers, i'll post my results
Jamie

So I’m pretty close Its working great and now im trying to add a couple things

  1. Log the data on sd card, I have the the sheild connected but when I put in
 if (!SD.begin(SS)) {
    Serial.println("initialization failed!");
    return;
  }
 Serial.println("initialization done.");

the motor just runs and runs.

Its not a huge deal but I just wanted to see when the door opens and closes by looking at the log

  1. After I set the time on the RTC is there a way to store in on there, I know it has a battery, But I want to be able to set the time then hit the reset button and not lose the time and have to set it every time I hit the reset button on the arduino. I tried uploading the code then commenting out the code but maybe im commenting out the wrong code.

  2. would like to add a if button to open if closed or close if open etc…

Here is the code thus far

/*
/*Chicken Door 1.0
* 
*/
#include <math.h>
#include <Wire.h>
#include "DS1307.h"
#include <SD.h>
File myFile;

DS1307 clock;//define a object of DS1307 class

int pinI1=8;//define I1 interface
int pinI2=11;//define I2 interface 
int speedpinA=9;//enable motor A
int spead = 255;//define the spead of motor
int sensorValue = 0;  
int sensorPin = 0;  

const int chipSelect = SS;
const int ledPin=12;                 //Connect the LED Grove module to Pin12, Digital 12
const int thresholdvalue=10;         //The treshold for which the LED should turn on. Setting it lower will make it go on at more light, higher for more darkness
float Rsensor; //Resistance of sensor in K

void setup() 
{
 // Open serial communications and wait for port to open:
  Serial.begin(9600);
   while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }
  
 // Serial.print("Initializing SD card...");
  // On the Ethernet Shield, CS is pin 4. It's set as an output by default.
  // Note that even if it's not used as the CS pin, the hardware SS pin 
  // (10 on most Arduino boards, 53 on the Mega) must be left as an output 
  // or the SD library functions will not work. 
  // pinMode(10, OUTPUT);
   
  //if (!SD.begin(SS)) {
  //  Serial.println("initialization failed!");
   // return;
  //}
// Serial.println("initialization done.");
  
  // open the file. note that only one file can be open at a time,
  // so you have to close this one before opening another.
  myFile = SD.open("test.txt", FILE_WRITE);
  
  // if the file opened okay, write to it:
  if (myFile) {
    Serial.print("Writing to test.txt...");
    myFile.println("testing 1, 2, 3.");
	// close the file:
    myFile.close();
    Serial.println("done.");
 // } else {
    // if the file didn't open, print an error:
  //  Serial.println("error opening test.txt");
 // }
  
   // re-open the file for reading:
  //myFile = SD.open("test.txt");
 // if (myFile) {
  //  Serial.println("test.txt:");
    
    // read from the file until there's nothing else in it:
   // while (myFile.available()) {
   // 	Serial.write(myFile.read());
    //}
    // close the file:
   // myFile.close();
 // } else {
  	// if the file didn't open, print an error:
 //   Serial.println("error opening test.txt");
  }
  
  pinMode(ledPin,OUTPUT);            //Set the LED on Digital 12 as an OUTPUT
  pinMode(pinI1,OUTPUT);
  pinMode(pinI2,OUTPUT);
  pinMode(speedpinA,OUTPUT);

	clock.begin();
	clock.fillByYMD(2013,3,05);//Jan 19,2013
	clock.fillByHMS(21,04,00);//15:28 30"
	clock.fillDayOfWeek(TUE);//Saturday
	clock.setTime();//write time to the RTC chip

  
}

void closeDoor()
{
     analogWrite(speedpinA,spead);//input a simulation value to set the speed
     digitalWrite(pinI2,LOW);//turn DC Motor A move anticlockwise
     digitalWrite(pinI1,HIGH);
     delay(6000);
     Serial.println("Door Is Closed.");
      myFile = SD.open("test.txt", FILE_WRITE);
      myFile.write("Door Is Closed.");
      myFile.write(sensorValue);
      printTime();
     digitalWrite(pinI2,LOW);//turn DC Motor A move clockwise
     digitalWrite(pinI1,LOW);
}
void openDoor()//
{
     analogWrite(speedpinA,spead);//input a simulation value to set the speed
     digitalWrite(pinI2,HIGH);//turn DC Motor A move clockwise
     digitalWrite(pinI1,LOW);
     delay(6000);
     Serial.println("Door Is Open.");
      myFile = SD.open("test.txt", FILE_WRITE);
      myFile.write("Door Is .");
      myFile.write(sensorValue);
      printTime();
     digitalWrite(pinI2,LOW);//turn DC Motor A move clockwise
     digitalWrite(pinI1,LOW);
}
void printTime()
{
	clock.getTime();
	Serial.print(clock.hour, DEC);
	Serial.print(":");
	Serial.print(clock.minute, DEC);
	Serial.print(":");
	Serial.print(clock.second, DEC);
	Serial.print("	");
	Serial.print(clock.month, DEC);
	Serial.print("/");
	Serial.print(clock.dayOfMonth, DEC);
	Serial.print("/");
	Serial.print(clock.year+2000, DEC);
	Serial.print(" ");
	Serial.print(clock.dayOfMonth);
	Serial.print("*");
	switch (clock.dayOfWeek)// Friendly printout the weekday
	{
		case MON:
		  Serial.print("MON");
		  break;
		case TUE:
		  Serial.print("TUE");
		  break;
		case WED:
		  Serial.print("WED");
		  break;
		case THU:
		  Serial.print("THU");
		  break;
		case FRI:
		  Serial.print("FRI");
		  break;
		case SAT:
		  Serial.print("SAT");
		  break;
		case SUN:
		  Serial.print("SUN");
		  break;
	}
	Serial.println(" ");
}

void loop() {
// Make sure that DAWN_THRESHOLD is slightly higher than DUSK_THRESHOLD, otherwise slight variations in light around dawn/dusk will make the door open/close

// wait for dawn
while(analogRead(sensorPin) < 400)
{
  sensorValue = analogRead(sensorPin);  //get the value from input pin
  Serial.println(sensorValue);  //print the value to Serial monitor
  delay(3000);
}
// now it is dawn

openDoor();

// wait for dusk
while(analogRead(sensorPin) > 20)
{
    sensorValue = analogRead(sensorPin);  //get the value from input pin
  Serial.println(sensorValue);  //print the value to Serial monitor
  delay(3000);

}
// now it is dusk

closeDoor();
  
}

All that commented out code is not contributing to your problem. Expecting us to wade through it is unfair. The delete key is there for a reason. Use the force.

I figured you would want to see the code I was using to try and write the log to the SD card

Code with out the commented out SD card stuff

/*
/*Chicken Door 1.0
* 
*/
#include <math.h>
#include <Wire.h>
#include "DS1307.h"

DS1307 clock;//define a object of DS1307 class

int pinI1=8;//define I1 interface
int pinI2=11;//define I2 interface 
int speedpinA=9;//enable motor A
int spead = 255;//define the spead of motor
int sensorValue = 0;  
int sensorPin = 0;  

void setup() {
  Serial.begin(9600);
  }
  
  pinMode(ledPin,OUTPUT);            //Set the LED on Digital 12 as an OUTPUT
  pinMode(pinI1,OUTPUT);
  pinMode(pinI2,OUTPUT);
  pinMode(speedpinA,OUTPUT);

	clock.begin();
	clock.fillByYMD(2013,3,05);//Jan 19,2013
	clock.fillByHMS(21,04,00);//15:28 30"
	clock.fillDayOfWeek(TUE);//Saturday
	clock.setTime();//write time to the RTC chip

  
}

void closeDoor()
{
     analogWrite(speedpinA,spead);//input a simulation value to set the speed
     digitalWrite(pinI2,LOW);//turn DC Motor A move anticlockwise
     digitalWrite(pinI1,HIGH);
     delay(6000);
     Serial.println("Door Is Closed.");
      printTime();
     digitalWrite(pinI2,LOW);//turn DC Motor A move clockwise
     digitalWrite(pinI1,LOW);
}
void openDoor()//
{
     analogWrite(speedpinA,spead);//input a simulation value to set the speed
     digitalWrite(pinI2,HIGH);//turn DC Motor A move clockwise
     digitalWrite(pinI1,LOW);
     delay(6000);
     Serial.println("Door Is Open.");
      myFile = SD.open("test.txt", FILE_WRITE);
      myFile.write("Door Is .");
      myFile.write(sensorValue);
      printTime();
     digitalWrite(pinI2,LOW);//turn DC Motor A move clockwise
     digitalWrite(pinI1,LOW);
}
void printTime()
{
	clock.getTime();
	Serial.print(clock.hour, DEC);
	Serial.print(":");
	Serial.print(clock.minute, DEC);
	Serial.print(":");
	Serial.print(clock.second, DEC);
	Serial.print("	");
	Serial.print(clock.month, DEC);
	Serial.print("/");
	Serial.print(clock.dayOfMonth, DEC);
	Serial.print("/");
	Serial.print(clock.year+2000, DEC);
	Serial.print(" ");
	Serial.print(clock.dayOfMonth);
	Serial.print("*");
	switch (clock.dayOfWeek)// Friendly printout the weekday
	{
		case MON:
		  Serial.print("MON");
		  break;
		case TUE:
		  Serial.print("TUE");
		  break;
		case WED:
		  Serial.print("WED");
		  break;
		case THU:
		  Serial.print("THU");
		  break;
		case FRI:
		  Serial.print("FRI");
		  break;
		case SAT:
		  Serial.print("SAT");
		  break;
		case SUN:
		  Serial.print("SUN");
		  break;
	}
	Serial.println(" ");
}

void loop() {
// Make sure that DAWN_THRESHOLD is slightly higher than DUSK_THRESHOLD, otherwise slight variations in light around dawn/dusk will make the door open/close

// wait for dawn
while(analogRead(sensorPin) < 400)
{
  sensorValue = analogRead(sensorPin);  //get the value from input pin
  Serial.println(sensorValue);  //print the value to Serial monitor
  delay(3000);
}
// now it is dawn

openDoor();

// wait for dusk
while(analogRead(sensorPin) > 20)
{
    sensorValue = analogRead(sensorPin);  //get the value from input pin
  Serial.println(sensorValue);  //print the value to Serial monitor
  delay(3000);

}
// now it is dusk

closeDoor();
  
}

Seems like your really close here..

If the light goes above 300 then turn the motor forward for 2 seconds then stop
If the light goes below 100 then turn the motor backwards for 2 seconds then stop

Just change it to

If the light goes above 300 && !forward then turn the motor forward for 2 seconds then stop; forward = true;
If the light goes below 300 && forward then turn the motor backwards for 2 seconds then stop; forward = false;

You need to set the initial condition of forward though..

Hope this helps

-jim lee

Thanks Jim

The opening and closing of the door based on the light sensor is working great its the other stuff im trying to get to work

The data logging, Setting the RTC only once, and opening and closing with one button depending on the current state of the door

Thanks