New to Arduino, I'm having some issues understanding how to use millis() as a delay after a condition has been met.
Basically I want to turn a motor on after my photocell has detected low light for a determined period of time. then i want it to stay on for a certain time. I think i can use delay to keep the motor running but I just cant figure out how to have it countdown after the lighting condition has been met.
any input is greatly helpful
this is as far as I've gotten, it doesn't work as is but before i tried adding in the millis function it did, just without any delay after light condition met.
const int rpm = 9 ;
const int in1 = 6 ;
const int in2 = 5 ;
int sens = A0 ;
int sensVal = A0 ;
int i;
const unsigned long timeDelay = 5000;
unsigned long previousTime = 0;
void setup()
{
pinMode(rpm,OUTPUT) ;
pinMode(in1,OUTPUT) ;
pinMode(in2,OUTPUT) ;
Serial.begin(9600);
}
void loop(){
unsigned long currentTime = millis();
sensVal = analogRead(sens);
Serial.print("Light Input = ");
Serial.println(sensVal);
if (sensVal < 700) (currentTime - previousTime >= timeDelay);{ // adjust "sensVal" for light sensitivity
digitalWrite(in1,HIGH) ; // (in1,HIGH) (in2,LOW) = forward
digitalWrite(in2,LOW) ; // (in1,LOW) (in2,HIGH) = reverse
analogWrite(rpm,255) ; // (in1,HIGH) (in2,HIGH) = off
else
digitalWrite(in1,HIGH) ;
digitalWrite(in2,HIGH) ;
analogWrite(rpm,255) ;
}
}
const int rpm = 9 ;
const int in1 = 6 ;
const int in2 = 5 ;
const int sensorPin = A0 ;
const unsigned long timeDelay = 5000; // amount of time LDR is low before starting motor
const unsigned long runTime = 60000; // amount of time to run the motor once started
unsigned long previousTime = 0;
unsigned long startTime;
bool isRunning = false;
const int sensorThreshhold = 700;
void setup()
{
pinMode(rpm, OUTPUT) ;
pinMode(in1, OUTPUT) ;
pinMode(in2, OUTPUT) ;
Serial.begin(9600);
}
void loop() {
unsigned long currentTime = millis();
int sensVal ;
// first, check to see if we are running
// and turn off if we have run long enough
if ( isRunning == true ) {
if (currentTime - startTime >= runTime ) {
// turn motor off
digitalWrite(in1, HIGH) ;
digitalWrite(in2, HIGH) ;
isRunning = false;
}
}
else {
// we are not running, so check sensor
sensVal = analogRead(sensorPin);
Serial.print("Light Input = ");
Serial.println(sensVal);
if (sensVal < sensorThreshhold) {
// we are low so check if we have been low long enough to start motor
if (currentTime - previousTime >= timeDelay) {
// start the motor
digitalWrite(in1, HIGH) ; // (in1,HIGH) (in2,LOW) = forward
digitalWrite(in2, LOW) ; // (in1,LOW) (in2,HIGH) = reverse
analogWrite(rpm, 255) ; // (in1,HIGH) (in2,HIGH) = off
isRunning = true;
startTime = currentTime;
}
}
else {
// sensor is high so reset timer
previousTime = currentTime;
}
}
}
+1 Karma for using code tags with your first post!
DUDE! thank you! I've spent the past 2 days trying to figure this out and you did it in under 20 minutes
It works great, and I'll be honest I don't know really how bool works but I will be going through what you did to try and understand it better,
the only thing i need to change is that I only want it to cycle the fan once after the light goes below threshold, but this is an amazing help if you don't mind I'll probably post again about this as i want to add in a lcd screen with the status of the programming and some countdowns.
but I'll probably be playing with that for the next day or so. thanks again !
A 'bool' is true or false.
That is handy when using a if-statement.
For example when the sun is shining and it is not raining:
bool sun = true;
bool rain = false
if( sun && !rain) // in 'c', this is how it has been done for decades.
{
Serial.println( "Nice weather");
}
if( sun and not( rain)) // modern notation allowed in 'c++'
{
Serial.println( "Nice weather");
}
To keep something running for some time, that can be called a single-shot-timer. It turns itself off with a 'bool' variable. See for example this small example: millis_single_delay.ino
Okay, so say I want the motor to run for 10 seconds then shut off, then the loop resets and checks the sensor value, sensor value is still low so it restarts the run timer. how can i set it so after the motor has ran its timer to stay off until it has sensed light again to restart the loop?
Without delay(), the Arduino loop() runs hundreds of times per second. That faster and the more it runs, the better and smoother everything works.
Can you explain what you want ?
With a good explanation, half the code is already written.
You can now turn the motor on for some time.
You can keep the motor off for some time and check the light. That is already in the sketch by blh64. It is possible to use another previousMillis for that, or a second 'bool' variable. I think that will make the sketch easier.
When should the motor turn on ?
Is it allowed that the sensor detects light and dark while the motor is off and waiting ?
After the waiting (motor off) has finished, should the sensor detect dark first ? Or just check if there is light and start again ?
When it should be dark first, can that also be when the motor is running or waiting (with motor off) ?
Koepel:
With a good explanation, half the code is already written.
Amen to that... if only more people believed it.
That explanation can take many forms: traditional box and diamond flow-charts, state diagram, essays, paragraphs, pseudo-code. But whatever form it takes, it's worth spending time on it before hitting the code.
Thanks for the input, I'll try and do a point form explanation and see if you can help me understand this.
I'm using the code that blh64 made.
basically I want it to -
-check LDR
-if reading under theshold , run timer for X time
-if reading still under threshold after timer , run motor for X time
-after motor has run for X time, stop motor
-check LDR, if still under threshold, keep motor off
-if LDR goes above threshold, reset code
I've been trying to add in a second bool but every time it either won't run the motor after timer or the code doesn't work at all.
I keep thinking of it simply but I'm fresh to all this so its probably just a bit too much to wrap my head around with any examples I can find.
this code waits for the sensor to go back HIGH before allowing the motor to turn back on.
const int rpm = 9 ;
const int in1 = 6 ;
const int in2 = 5 ;
const int sensorPin = A0 ;
const unsigned long timeDelay = 5000; // amount of time LDR is low before starting motor or high before allowing restart
const unsigned long runTime = 60000; // amount of time to run the motor once started
unsigned long previousTime = 0;
unsigned long startTime;
bool isRunning = false;
bool isPaused = false;
const int sensorThreshhold = 700;
void setup()
{
pinMode(rpm, OUTPUT) ;
pinMode(in1, OUTPUT) ;
pinMode(in2, OUTPUT) ;
Serial.begin(9600);
previousTime = millis();
}
void loop() {
unsigned long currentTime = millis();
int sensVal ;
// first, check to see if we are running
// and turn off if we have run long enough
if ( isRunning == true ) {
if (currentTime - startTime >= runTime ) {
// turn motor off
digitalWrite(in1, HIGH) ;
digitalWrite(in2, HIGH) ;
isRunning = false;
isPaused = true; // don't run motor again until we detect light
}
}
else {
// we are not running, so check sensor
sensVal = analogRead(sensorPin);
Serial.print("Light Input = ");
Serial.println(sensVal);
if ( isPaused == true ) {
// don't restart motor unless we detect light
if ( sensVal >= sensorThreshhold ) {
// we are high so check if we have been high long enough to restart motor
if (currentTime - previousTime >= timeDelay) {
// restart the motor okay
isPaused = false;
}
}
else {
// sensor is low so reset timer
previousTime = currentTime;
}
}
else {
// okay to turn on motor so check sensor
if (sensVal < sensorThreshhold) {
// we are low so check if we have been low long enough to start motor
if (currentTime - previousTime >= timeDelay) {
// start the motor
digitalWrite(in1, HIGH) ; // (in1,HIGH) (in2,LOW) = forward
digitalWrite(in2, LOW) ; // (in1,LOW) (in2,HIGH) = reverse
analogWrite(rpm, 255) ; // (in1,HIGH) (in2,HIGH) = off
isRunning = true;
startTime = currentTime;
}
}
else {
// sensor is high so reset timer
previousTime = currentTime;
}
}
}
}