(Newbie) Simple Project with Motion Sensors

Hi all! I'm completely new to Arduino and I got to create a simple project tied to my studies. I'd like to request some help with the code.

The idea is as follows:

There is one (or multiple) motion detector(s) installed in the ceiling. I am using HC-SR501 sensors.
When the sensor detects a person it sends a HIGH to my Arduino Uno.
The Arduino then switches a relais from NO to NC. NO toggles a line of red LEDs and NC a line of green LEDs. These LEDs are supposed to light up a glass panel to show whether the room is occupied or free.
I am trying to implement a timer so that when the sensor does not receive an input after let's say 60s it automatically turns to LOW and the red LEDs light up again. If however the sensor receives another signal it resets the timer.

As said I'm completely new to coding but I have added a "protoype" version of what I have so far. I am aware of it not working yet but hopefully it provides enough information for you to understand what I have in mind. If I should provide more info let me know.
Maybe you can help me with the code or rework the entire idea. Thanks a lot! :slightly_smiling_face:

CODE:

const int GreenRed = 4;                       // GreenRed (LEDs) to Pin4
const int SensorInput = 2;                    // SensorInput to Pin2                 

int GRState = LOW;                            // starting with State to LOW (RED)
int SensorState = LOW;                        // starting with State to LOW

unsigned long currentMillis;                  // Millis Timer to count
unsigned long previousMillis = 0;             // Reset Millis Timer to 0
const long interval = 60000;                  // Millis Timer counting up to 1 min
  


void setup() {
  pinMode(GreenRed, OUTPUT);                  // GreenRed (Pin4) as Output
  pinMode(SensorInput, INPUT);                // SensorInput (Pin2) as Input
}
 


void loop() {
  currentMillis = millis();                   // declare currentMillis as Millis Timer
  if (SensorState == HIGH) {
    GRState = HIGH;                           // GRState to HIGH -> GREEN
    currentMillis = previousMillis;           // set currentMillis to 0
    if (currentMillis >= interval) {          // When currentMillis reaches 60000ms:
      GRState = LOW;                          // GRState to LOW -> RED                           
    }
  }
}

And you thought that posting in the tutorials section was a great idea…?

➜ moved to a more suitable place

do yourself a favour and please read How to get the best out of this forum

I have updated the category, sorry

NO means Normally Open
NC means Normally Closed

Does it really switch the way you wired the relay or does it just trigger the relay?

Where is the sensor’s state updated?

What i mean is it triggering the relay. So one way it's the red, the other way the green LEDs.

That sensor outputs 3.3v on the DOUT pin. I'm not sure if that's enough to trigger the Uno. If I remember correctly, the lower trigger threshold is 3.5v.
Someone correct me if I've made a mistake.

Does that mean I have to change the pin? Or even the sensor?

There are a few ways to deal with it.

Let's wait for some users with more experience with these sensors to provide guidance.

I'll check back after I finish working on my chicken coop though, to be sure that you've been helped.

1 Like

thank you, good luck with that!

The 3.3V output of your module is enough to be seen as a HIGH by your 5V arduino UNO or similar, that’s fine

(Switch points are 0.3 x VCC for LOW and 0.6 x VCC for HIGH, so If VCC is 5 Volts, then > 3 V on an INPUT pin will be seen as HIGH)

2 Likes

I have connected VCC to the 5V pin of my Arduino. So that should be fine I guess


It is worth adding to @J-M-L' s summary the wonderful fact that the inputs have build in hysteresis, at least the '328 does.

I could say so does the '2560 and ask someone to correct me if I've made a mistake.:wink:

a7

1 Like

something like

bool ImOn = false;
unsigned long ImOnMillis = millis();
unsigned long ImOnTime = 6000;
voiding loopies() 
{
  currentMillis = millis();                   // declare currentMillis as Millis Timer
  if (SensorState == HIGH && ImOn==false) 
{
ImOn=true;
    GRState = HIGH;                           // GRState to HIGH -> GREEN
    currentMillis = previousMillis;           // set currentMillis to 0
ImOnMillis=millis();
    //if (currentMillis >= interval) {          // When currentMillis reaches 60000ms:
    //  GRState = LOW;                          // GRState to LOW -> RED                           
    //}
  }
if (  ((millis() - ImOnMillis) >= ImOnTime)  && ImOn )
{

do the LEd is the other color thingies here.

ImOn=false;

}


}

or some such thingies.

1 Like

Post your circuit in detail (I know it's a hassle, but it always makes things easier)


But it is enough to trigger a NPN BJT transistor.

Just use INPUT_PULLUP in your code and wire as follows:

2 Likes

That was my thinking, I wanted to let others provide their experience before I put together something like that.
Has the bonus of being a ground triggered pin, instead of hot triggered.

Really 3.3V should be fine, no need for additional hardware and wires….

After digging into it for a bit, I now finished my simplified code using 3 sensors. Seems to be working so far. The settings for the timing can be adjusted on the sensors themselves.

int SensorA = 5;
int SensorB = 6;
int SensorC = 7;
int StatusA = LOW;
int StatusB = LOW;
int StatusC = LOW;
int RGRelay = 2;

void setup() {
  pinMode(SensorA, INPUT);
  pinMode(SensorB, INPUT);
  pinMode(SensorC, INPUT);
  pinMode(RGRelay, OUTPUT);
}

void loop() {
  StatusA = digitalRead(SensorA);
  StatusB = digitalRead(SensorB);
  StatusC = digitalRead(SensorC);
  if( StatusA || StatusB || StatusC == HIGH) {
    digitalWrite(RGRelay, LOW);
  }
  else {
    digitalWrite(RGRelay, HIGH);
  }
}

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.