Pir Sensor - On/Off 220V Switch

Hi, Im having some programming problems with my code.

Ive been trying to use a PIR sensor as an on/off switch to turn a 220V bulb.
Im using a PIR Sensor, an Arduino mega 2560 and a relay.

I want the light to turn ON when PIR senses motion (and stay ON), and turn off when it senses motion again.

The problem is I have only accomplish to turn the light ON (with motion) and after a few seconds it turns off automatically.

I think my problem is in the code. Here I leave it if someone can help me with it. Thankssss!

const int SENSOR_PIN = 2;
const int RELAY_PIN = 4;

void setup() {
  Serial.begin(9600);
  pinMode(SENSOR_PIN, INPUT);
  pinMode(RELAY_PIN, OUTPUT);
}

void loop() {
  int motion =digitalRead(SENSOR_PIN);
 
  // si hay movimiento
  if(motion){
    Serial.println("Motion detected");
    digitalWrite(RELAY_PIN, LOW);
  }else{
     Serial.println("===nothing moves");
     digitalWrite(RELAY_PIN,HIGH);
  }  
}
  pinMode(SENSOR_PIN, INPUT);

How IS your PIR sensor wired? Does it keep the pin pulled up to 5V or down to 0 AT ALL TIMES? If not, the mode should be INPUT_PULLUP.

  int motion =digitalRead(SENSOR_PIN);

This function return 0 or 1 (LOW or HIGH). No need to waste 16 bits of memory.

  if(motion){

You didn't define the variable as a boolean. Why are you treating it as such? Yes, I KNOW that this works, but if you want a boolean, define a boolean.

If you want motion to turn the relay on and motion to turn it off, that code is NOT doing that.

Look at the state change detection example. You need to count the number of times you sense motion, and do one thing when the count is odd, and another when the count is even.

PaulS:

  int motion =digitalRead(SENSOR_PIN);

This function return 0 or 1 (LOW or HIGH). No need to waste 16 bits of memory.

  1. This function returns LOW or HIGH. It is none of our business to look what specific values LOW and HIGH stand for. This is actually why we have these named constants LOW and HIGH in the first place: to use them in the code instead of relying on specific numerical values. Relying on specific values behind named constants is a very bad programming practice.

Function digitalRead is declared in Arduino.h as returning an int. This means that the proper type for receiving the result is int, period.

If you want to convert it to bool right away, you can do that. But the proper way to do it is

bool value = digitalRead(SENSOR_PIN) == HIGH;
  1. This is not a memory waste issue at all. Local (automatic) variables don't necessarily "waste memory". They might... but when it comes to declaring local variables of integral types, it is one of the last places one needs to worry about.

Hi thanks for the answers. Ive changed my code quite a lot but still have problems in programming.
Im not able to program the ODD or EVEN comand at the end of my code.
Please help. Thanks in advance

const int sensor = 2;
const int relay = 4;


int contador = 0;
int estadoboton = 0;
int ultimoestadoboton = 0;

void setup() {
  pinMode (sensor, INPUT);
  pinMode (relay, OUTPUT);
  Serial.begin(9600);
}


void loop(){
  estadoboton = digitalRead(sensor);
  if (estadoboton != ultimoestadoboton) {
    if(estadoboton == HIGH) {
      contador++;
      Serial.println("on");
      Serial.print("number of button pushes");
      Serial.println(contador);
    } else {
      Serial.println("off");
    }
    delay (1);
  }
  ultimoestadoboton = estadoboton;
  if (contador HOW TO RECOGNIZE ODD NUMBERS ) {
 digitalWrite(relay, HIGH);
  } else {
    digitalWrite(relay, LOW);
  }

}

What is the result of dividing n by 2? The remainder is 0 if n is even, and 1 if n is odd. There is a handy modulo operator (%) just for this purpose.