PIR Sensor Question

I have a Parallax PIR sensor (http://www.ladyada.net/media/sensors/PIRSensor-V1.2.pdf) and I have code that checks to see if the sensor goes high. It works with the exception that I get random triggers every once in a while when there is no motion involved. I am assuming I need a pull-up/pull-down resistor but I'm not sure which pin it should go on. The V- is going to the GND on the arduino, the V+ is going to the 5v on the arduino, and the SIG is going to an analog pin on the arduino.

This is an example of my sensor checking code:

if (SENSOR == LOW) {
digitalWrite(TRANSISTOR, LOW);
} else {
digitalWrite(TRANSISTOR, HIGH);
}

and the SIG is going to an analog pin on the arduino

if (SENSOR == LOW) {
digitalWrite(TRANSISTOR, LOW);
} else {
digitalWrite(TRANSISTOR, HIGH);
}

Is is unlikely that an analogue pin will consistently go LOW (== 0).
Try either a digital pin, or invent some threshold.

Would reversing the logic work?

if (SENSOR == HIGH) {
digitalWrite(TRANSISTOR, HIGH);
} else {
digitalWrite(TRANSISTOR, LOW);
}

Almost certainly no, except for those rare occasions when "SENSOR==1"
Why don't you post your whole sketch?
Any reason for using an analogue pin and not a digital one?

I have no reasoning for using an analog input vs digital. I just thought I was supposed to use an analog. I'm very new to coding the arduino too.

//Closes a circuit on a hacked keyboard to type a letter with the use of a relay

#define SENSOR 2 //the input pin where the PIR sensor is connected
#define TRANSISTOR 4 //the output pin where the BASE pin for the transistor is connected

int val = 0; //the state of the PIR input pin
int val2 = 0; //the state of the transistor output pin

void setup() {
pinMode (SENSOR, INPUT); //sets SENSOR as an input
pinMode (TRANSISTOR, OUTPUT); //sets the TRANSISTOR as an output
Serial.begin(9600); //sets up the serial port
}

void loop () {
val = analogRead(SENSOR); //read the state of SENSOR and store it
val2 = digitalRead(TRANSISTOR); //read the state of TRANSISTOR and store it

if (val == LOW) { //check to see if the PIR has been tripped
digitalWrite(TRANSISTOR, LOW); //stop sending voltage to TRANSISTOR
} else {
digitalWrite(TRANSISTOR, HIGH); //send voltage to TRANSISTOR
}

Serial.println(val2); //print out the state of val2

if (val2 == HIGH) { //check to see if TRANSISTOR pin is sending any voltage
digitalWrite(TRANSISTOR, LOW); //stop sending any voltage to TRANSISTOR
delay(2000); //wait two seconds for the PIR to stop sending a signal
}
delay(10); //delay 10ms for program stability
}

Now I'm confused - which pin is the PIR physically wired to?
Analogue pin 2 or digital pin 2?

I also don't understand why you're reading the state of the TRANSISTOR output.

Forget the transistor for now, and do some serial debug prints based on the value of digital pin 2.
Enable the internal pull-ups:

pinMode (SENSOR, INPUT);
digitalWrite (SENSOR, HIGH);

Analogue 2. I wrote that because if I didn't, the keyboard I hacked would act as if the key was pressed down constantly. It's sorta complicated with the relay and the way the PIR stays high for two seconds. I don't think that portion of the code is causing the false readings.

But reading an analogue input (mostly) doesn't return HIGH (1) or LOW (0), but some value in the range 0...1023, depending on the voltage on the pin.

The "pinMode(SENSOR, INPUT);" does absolutely nothing to help you; it is setting the mode of digital input 2.

Thanks for pointing that out. So by switching the sensor input from an analogue input to a digital input I can utilize the internal pull-up and it will be expecting HIGH or LOW and not a range that is associated with analogue signals?

So by switching the sensor input from an analogue input to a digital input I can utilize the internal pull-up and it will be expecting HIGH or LOW and not a range that is associated with analogue signals?

Yes.

Here is what I think needs to be changed, in bold. In, addition, physically wire up the signal wire from the PIR to digital pin 2 instead of analogue pin 2.

//Closes a circuit on a hacked keyboard to type a letter with the use of a relay

#define SENSOR 2 //the input pin where the PIR sensor is connected (digital pin 2)
#define TRANSISTOR 4 //the output pin where the BASE pin for the transistor is connected (digital pin 4)

int val = 0; //the state of the PIR input pin
int val2 = 0; //the state of the transistor output pin

void setup() {
pinMode (SENSOR, INPUT); //sets SENSOR as an input
digitalWrite(SENSOR, HIGH); //enables the internal pull-up
pinMode (TRANSISTOR, OUTPUT); //sets the TRANSISTOR as an output
Serial.begin(9600); //sets up the serial port
}

void loop () {
val = digitalRead(SENSOR); //read the state of SENSOR and store it
val2 = digitalRead(TRANSISTOR); //read the state of TRANSISTOR and store it

if (val == LOW) { //check to see if the PIR has been tripped
digitalWrite(TRANSISTOR, LOW); //stop sending voltage to TRANSISTOR
} else {
digitalWrite(TRANSISTOR, HIGH); //send voltage to TRANSISTOR
}

Serial.println(val2); //print out the state of val2

if (val2 == HIGH) { //check to see if TRANSISTOR pin is sending any voltage
digitalWrite(TRANSISTOR, LOW); //stop sending any voltage to TRANSISTOR
delay(2000); //wait two seconds for the PIR to stop sending a signal
}
delay(10); //delay 10ms for program stability
}

You may want to set the initial state of the transistor output in "setup", with a "digitalWrite".
You may also want to stop reading it - it doesn't make much sense.

This look good? I didn't even know about the internal pull-up on the arduino. I love this community. :smiley:

void setup() {
pinMode (SENSOR, INPUT); //sets SENSOR as an input
digitalWrite(SENSOR, HIGH); //enables the internal pull-up
pinMode (TRANSISTOR, OUTPUT); //sets the TRANSISTOR as an output
digitalWrite(TRANSISTOR, LOW); //set the initial state of the transistor to low
Serial.begin(9600); //sets up the serial port
}

This look good? I didn't even know about the internal pull-up on the arduino. I love this community.

That looks good to me.

Again, reading the TRANSISTOR output doesn't make any sense, and since you know the status of SENSOR (which you store in the variable "val"), you don't have to read anything for the TRANSISTOR.

So, get rid of the line "val2 = digitalRead(TRANSISTOR);" at the top of loop(), and replace the line "if (val2 == HIGH) {" (near the bottom of loop()" with "if (val == HIGH) {".

Also - for my own edification, and because I am not an expert on all things Arduino (I just pretend I am ;)) - isn't HIGH defined as 1 (in the headers), whereas LOW is defined as 0, and is therefore more or less equivalent to true/false?

That is, rather than writing "if (signal == HIGH) {" or "if (signal == LOW) {", you could simply write "if (signal) {" or "if (!signal) {" (respectively), and get the same results?

Also - does the compiler generate the same amount of code either way, or does one or the other method yield shorter code (provided they are equivalent, of course)?

I read the transistor and take it to LOW if it is HIGH and then I pause the program due to my physical PIR/Relay setup. If I don't it spams the PC.

If you carefully read your code, and look at the changes I am suggesting, you will find they are logically equivalent, and make more sense from a hardware standpoint. Right now, you are reading a pin set to OUTPUT, not INPUT, which may work, but doesn't fully make sense, depending on how you are thinking about it...