0

Functionality:

Have made use of of IR sensor to toggle the state of LED light and motorFAN. Therefore, when trigger distance condition is met, both LED light and motorFAN state will toggle from LOW to HIGH. After a delay of 5 seconds, the motorFAN state will toggle from HIGH to LOW, while the state of the LED light will remain HIGH, as long as the trigger distance condition is met. The LED light will toggle to LOW when the trigger distance is no longer satisfied.

Issue:

When the trigger distance condition is met, both the LED light and motorFAN state will toggle from LOW to HIGH.

However, the motorFan state will not toggle from HIGH to LOW after a 5 seconds delay, it will still remain HIGH.

Second issue, after both LED light and motorFan state has toggled to LOW from HIGH when the trigger distance condition is no longer satisfied. And when the condition is satisfied again, only the LED light is toggled to HIGH from LOW but the motorfan state is not toggled and remain in state of LOW.

Hence, need to ask for help in rectifying the issue and what has been done wrong. Thanks.

Code:

const int signalPin = 1; //wire pin to analog for IR Sensor 
//Motor-Fan connected to arduino pin number
//const  int FanPin = 5;

//Motor-Fan Relay
byte FanRelay = 4;
//const int FanRelay = 4;
//Light Relay
byte LightRelay = 6;
//const int LightRelay = 5;
int IRSignal; //variable signal, will hold the analog value read by Arduino


long duration;
int distance;
unsigned long Timer;
unsigned long Interval = 10000; //teh repeat Interval
unsigned long SmellInterval = 10000;

void setup() 
{
  //Execute only once at startup 

  //pinMode (FanPin , OUTPUT) ; // Set pinMode for FanPin as OUTPUT, display  
  pinMode (signalPin, INPUT);  //infared sensor line will be an input to the   Arduino
  pinMode(FanRelay, OUTPUT);
  pinMode(LightRelay, OUTPUT);
  Serial.begin(9600); // Open serial port to communicate with the Ultrasaonic Sensor
}

void loop() 
{

  //execute multiple times in a loop

  IRSignal = analogRead(signalPin); //arduino reads the value from the infared sensor
  distance = 9462 / (IRSignal -16.92);
  Serial.println(distance);
  if(distance < 30 && distance > 0)
  {
    Timer = millis(); 
    // Write a pin of HIGH
    Serial.println("1");

    digitalWrite (FanRelay, HIGH);
    digitalWrite (LightRelay, HIGH);

    if (Timer > SmellInterval){
      //digitalWrite (FanPin, LOW);
      digitalWrite (FanRelay, LOW);
    }
  }
  else
  {
    Serial.println("0");
    //Check if Timer is longer than 10s

    if ((millis()-Timer)>Interval){
      //digitalWrite (FanPin, LOW);
      //digitalWrite (FanRelay, LOW);
      digitalWrite (LightRelay, LOW);
    }
  }
  delay(1000);
}
Luke
  • 982
  • 1
  • 7
  • 27

1 Answers1

0

The issue lies here:

Timer = millis(); 
....
if (Timer > SmellInterval){
  //digitalWrite (FanPin, LOW);
  digitalWrite (FanRelay, LOW);
}

The Timer variable will hold current value of millis() which is system time from the last reset. That means that, the if condition will be satisfied always after 10s of running the program.

This is why FanRelay remains low the second time your condition is satisfied - enough time expired, so immediately after it is turned on, it is turned off.

Turning off after a delay will also not work (BTW both your delays are 10s, not 5s like you mention in the post). You need to save the time only the first time the distance condition was met and check the time difference from that moment.

See https://www.arduino.cc/en/Tutorial/BlinkWithoutDelay for a similar example. Also your design will be much more readable and easy to debug if you use a state machine concept. Some reading on wiki, and StackOverflow. In a state machine you define a set of states (like no_object_detected, object_just_detected, object_detected_a_while_ago), and transitions between them (when they happen, and what should be done when they occur).

CL.
  • 173,858
  • 17
  • 217
  • 259
mactro
  • 518
  • 7
  • 13