Forum: Mikrocontroller und Digitale Elektronik PIR Sensor am PC läuft am PC andersrum als am Netzteil


von Geldesch B. (Firma: haa) (dravr)


Lesenswert?

Hallo guten Tag,
ich habe einen PIR Sensor an einem Arduino UNO auf den Interrupteingang 
2 gelegt. Meine LED an PIN 7 geht an wenn eine Bewegung detektiert wird. 
Ich habe daraufhin das Board an ein 5 V Netzteil angeschlossen. Zuerst 
dachte ich der PIR Sensor funktioniert nicht, vlt. wegen eines 
Kurzschlusses. Dann habe ich beobachtet , dass sich die LED genau 
andersherum verhält. Wenn keine Bewegung detektiert wird ist die LED an. 
Bei Bewegung geht sie aus.

Hat jemand eine Idee für dieses Verhalten.
Hier folgt der Code dazu:
Wenn ein Interrupt ausgelöst wird wird geschaut ob die LED 
Statusvariable an ist. Wenn diese 1 ist heißt es, dass die LED an war ´, 
die LED soll nun ausgeschaltet werden.
Das Interrupt wird durch ein CHANGE ... ausgelöst. Also wenn der PIR 
Sensor das Spannungsniveau anhebt, senkt...

Wie gesagt am PC funktioniert das ganz gut.


1
 
2
3
#include <MQ2.h> // gas sensor
4
#include <Wire.h> 
5
#include <LiquidCrystal_I2C.h>
6
#include "DHT.h"//DHT22 ttempsensor
7
// definitions...
8
#define DHTPIN 6 //dht tempsensor
9
#define DHTTYPE DHT22 //DHT11, DHT21, DHT22
10
 
11
DHT dht(DHTPIN, DHTTYPE);
12
13
14
//I2C pins declaration
15
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
16
int Analog_Input = A0; // for gas sensor ?
17
int lpg, co, smoke; // GLOBAL VARIABLES
18
//detections
19
int ledPin = 7;                // LED 
20
int pirPin = 2;                // PIR Out pin , has interrupt feature
21
int pirStat = 0;               // PIR status changes is interrupt routine..
22
23
24
MQ2 mq2(Analog_Input);
25
26
void printLCDTest(){
27
  lcd.setCursor(0,0);
28
  lcd.print("START SENSORS !"); 
29
}
30
void printMQ2Data(){
31
    
32
  float* values= mq2.read(true); //set it false if you don't want to print the values in the Serial
33
  //lpg = values[0];
34
  lpg = mq2.readLPG();
35
  //co = values[1];
36
  co = mq2.readCO();
37
  //smoke = values[2];
38
  smoke = mq2.readSmoke();
39
  lcd.clear(); 
40
  lcd.setCursor(0,0);
41
  lcd.print("LPG:");
42
  lcd.print(lpg);
43
  lcd.print(" CO:");
44
  lcd.print(co);
45
  lcd.setCursor(0,1);
46
  lcd.print("SMOKE:");
47
  lcd.print(smoke);
48
  lcd.print(" PPM");  
49
}
50
void printDHT22Data(){
51
  
52
  // temp sensor dht
53
 float h = dht.readHumidity(); //Luftfeuchte auslesen
54
 float t = dht.readTemperature(); //Temperatur auslesen
55
 // Prüfen ob eine gültige Zahl zurückgegeben wird. Wenn NaN (not a number) zurückgegeben wird, dann Fehler ausgeben.
56
 if (isnan(t) || isnan(h)) 
57
 {
58
 Serial.println("DHT22 konnte nicht ausgelesen werden");
59
 lcd.clear();
60
  lcd.setCursor(0,0);
61
  lcd.print("Sensor Wackelkontakt");
62
 } 
63
 else
64
 {
65
  lcd.clear();
66
  lcd.setCursor(0,0);
67
  lcd.print("Feuchte: ");
68
  lcd.print(h);
69
  lcd.print(" %"); // prozent zeichen
70
  lcd.setCursor(0,1);
71
  lcd.print("Temp:    ");
72
  lcd.print(t);
73
  lcd.print(" C");
74
  
75
  
76
 Serial.print("Luftfeuchte: "); 
77
 Serial.print(h);
78
 Serial.print(" %\t");
79
 Serial.print("Temperatur: "); 
80
 Serial.print(t);
81
 Serial.println(" C");
82
 }
83
  // end temp sensor dht 
84
}
85
 void smartDelay();
86
void setup(){
87
  Serial.begin(9600);
88
   pinMode(ledPin, OUTPUT);   // PIR   
89
 pinMode(pirPin, INPUT);     // PIR LED
90
 int pirStat = 0;
91
  lcd.begin(16,2);//Defining 16 columns and 2 rows of lcd display
92
  lcd.backlight();
93
  mq2.begin();// start mq2 gas sensor
94
  dht.begin(); // start dht tempsensor
95
  printLCDTest();
96
  lcd.clear();
97
  attachInterrupt(digitalPinToInterrupt(pirPin), interrupt_routine, CHANGE);
98
99
   //pinMode(pirPin, INPUT_PULLUP);
100
101
}
102
void loop(){
103
104
 
105
  // print gas-sensor data
106
  printMQ2Data();
107
  delay(2000); // 1 = ?
108
  printDHT22Data();
109
  delay(4000);
110
  
111
}
112
void interrupt_routine(){
113
 
114
  Serial.println("Interrupt - switch");
115
if(pirStat == 1)
116
{
117
118
  digitalWrite(ledPin,LOW);
119
Serial.println("OFF");
120
pirStat =0;  
121
  
122
}
123
124
else{
125
  
126
  digitalWrite(ledPin,HIGH);
127
Serial.println("ON");
128
pirStat =1;
129
130
} 
131
}


Vielen Dank ,
hätte nicht gedacht dass so etwas passiert.
Unglaublich xD
Ich bin gespannt !!!!

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Ein Pinchange Interrupt wird jedesmal ausgelöst, wenn sich die Polarität 
des Pins ändert. Ob das eine fallende Flanke oder eine steigende ist, 
ist dem Pinchange Interrupt wurscht.
Die Chance steht also 50:50, das die ISR die richtige Flanke erwischt. 
Konfiguriere den IRQ auf fallende oder steigende Flanke. Alternativ 
checke den Pin in der ISR auf high oder low und verwerfe den 
ungewünschten Zustand.

Nochwas: Serielle Ausgaben in der ISR blocken alles und kosten unnötig 
Zeit. Setze lieber nur ein Flag und verlasse die ISR schnell wieder.

von Geldesch B. (Firma: haa) (dravr)


Lesenswert?

ok Danke.
Habe das jetzt mit einem Flag gemacht.
Im Hauptprogramm wird jetzt immer nch 500 ms geschaut ob sich der Flag 
geändert hat... somit ist die Verzögerungszeit für den Displaywechsel 
auch noch möglich :D

Aber ich muss unbedingt einen Timer verwenden denke ich jetzt !
1
 
2
3
#include <MQ2.h> // gas sensor
4
#include <Wire.h> 
5
#include <LiquidCrystal_I2C.h>
6
#include "DHT.h"//DHT22 ttempsensor
7
// definitions...
8
#define DHTPIN 6 //dht tempsensor
9
#define DHTTYPE DHT22 //DHT11, DHT21, DHT22
10
 
11
DHT dht(DHTPIN, DHTTYPE);
12
13
14
//I2C pins declaration
15
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
16
int Analog_Input = A0; // for gas sensor ?
17
int lpg, co, smoke; // GLOBAL VARIABLES
18
//detections
19
int ledPin = 7;                // LED 
20
int pirPin = 2;                // PIR Out pin , has interrupt feature
21
int pirStat = 0;               // PIR status changes is interrupt routine..
22
23
24
MQ2 mq2(Analog_Input);
25
26
void printLCDTest(){
27
  lcd.setCursor(0,0);
28
  lcd.print("START SENSORS !"); 
29
}
30
void printMQ2Data(){
31
    
32
  float* values= mq2.read(true); //set it false if you don't want to print the values in the Serial
33
  //lpg = values[0];
34
  lpg = mq2.readLPG();
35
  //co = values[1];
36
  co = mq2.readCO();
37
  //smoke = values[2];
38
  smoke = mq2.readSmoke();
39
  lcd.clear(); 
40
  lcd.setCursor(0,0);
41
  lcd.print("LPG:");
42
  lcd.print(lpg);
43
  lcd.print(" CO:");
44
  lcd.print(co);
45
  lcd.setCursor(0,1);
46
  lcd.print("SMOKE:");
47
  lcd.print(smoke);
48
  lcd.print(" PPM");  
49
}
50
void printDHT22Data(){
51
  
52
  // temp sensor dht
53
 float h = dht.readHumidity(); //Luftfeuchte auslesen
54
 float t = dht.readTemperature(); //Temperatur auslesen
55
 // Prüfen ob eine gültige Zahl zurückgegeben wird. Wenn NaN (not a number) zurückgegeben wird, dann Fehler ausgeben.
56
 if (isnan(t) || isnan(h)) 
57
 {
58
 Serial.println("DHT22 konnte nicht ausgelesen werden");
59
 lcd.clear();
60
  lcd.setCursor(0,0);
61
  lcd.print("Sensor Wackelkontakt");
62
 } 
63
 else
64
 {
65
  lcd.clear();
66
  lcd.setCursor(0,0);
67
  lcd.print("Feuchte: ");
68
  lcd.print(h);
69
  lcd.print(" %"); // prozent zeichen
70
  lcd.setCursor(0,1);
71
  lcd.print("Temp:    ");
72
  lcd.print(t);
73
  lcd.print(" C");
74
  
75
  
76
 Serial.print("Luftfeuchte: "); 
77
 Serial.print(h);
78
 Serial.print(" %\t");
79
 Serial.print("Temperatur: "); 
80
 Serial.print(t);
81
 Serial.println(" C");
82
 }
83
  // end temp sensor dht 
84
}
85
 void smartDelay();
86
void setup(){
87
  Serial.begin(9600);
88
   pinMode(ledPin, OUTPUT);   // PIR   
89
 pinMode(pirPin, INPUT);     // PIR LED
90
 int pirStat = 0;
91
  lcd.begin(16,2);//Defining 16 columns and 2 rows of lcd display
92
  lcd.backlight();
93
  mq2.begin();// start mq2 gas sensor
94
  dht.begin(); // start dht tempsensor
95
  printLCDTest();
96
  lcd.clear();
97
  attachInterrupt(digitalPinToInterrupt(pirPin), interrupt_routine, CHANGE);
98
   //pinMode(pirPin, INPUT_PULLUP);
99
100
}
101
void changeLEDStatus(){
102
if(pirStat == 1)
103
{
104
105
  digitalWrite(ledPin,HIGH);
106
Serial.println("HIGH");
107
  
108
}
109
else{
110
  digitalWrite(ledPin,LOW);
111
Serial.println("LOW");
112
113
}  
114
}
115
void loop(){
116
117
 
118
  // print gas-sensor data
119
  printMQ2Data();
120
  delay(500);
121
changeLEDStatus();
122
  delay(500);
123
  changeLEDStatus();
124
  delay(500);
125
  changeLEDStatus();
126
  delay(500);
127
  changeLEDStatus();
128
  printDHT22Data();
129
  delay(4000);
130
changeLEDStatus();
131
}
132
void interrupt_routine(){
133
pirStat =!pirStat; 
134
  Serial.println("change");
135
  
136
}

: Bearbeitet durch User
von STK500-Besitrzer (Gast)


Lesenswert?

Ohne jetzt noch mal den ganzen Code zu analysieren:
Du brauchst doch nur das "CHANGE" in "RISING" oder "FALLING" ändern und 
schon erkennt dein Programm, dass der PIR ausgelöst hat.
1
attachInterrupt(digitalPinToInterrupt(pirPin), interrupt_routine, CHANGE);

Geldesch B. schrieb:
> Aber ich muss unbedingt einen Timer verwenden denke ich jetzt !

In der ISR setzt du ein Flag, das du in deiner Hauptschleife - vor der 
(Display-) Ausgabe abfragst und ausgbist.

von Geldesch B. (Firma: haa) (dravr)


Lesenswert?

Jetzt nur noch das mit dem Interrupt hinbekommen...
ich weiß gar nicht ob man den timer überhaupt braucht.
evtl. kann man auch eine variable einfach hochzählen xD
Egal
1
#include <MQ2.h> // gas sensor
2
#include <Wire.h> 
3
#include <LiquidCrystal_I2C.h>
4
#include "DHT.h"//DHT22 ttempsensor
5
// definitions...
6
#define DHTPIN 6 //dht tempsensor
7
#define DHTTYPE DHT22 //DHT11, DHT21, DHT22
8
 
9
DHT dht(DHTPIN, DHTTYPE);
10
11
12
//I2C pins declaration
13
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
14
int Analog_Input = A0; // for gas sensor ?
15
int lpg, co, smoke; // GLOBAL VARIABLES
16
//detections
17
int ledPin = 7;                // LED 
18
int pirPin = 2;                // PIR Out pin , has interrupt feature
19
int pirStat = 0;               // PIR status changes is interrupt routine..
20
int timer = 0;
21
bool timerState;
22
23
MQ2 mq2(Analog_Input);
24
25
void printLCDTest(){
26
  lcd.setCursor(0,0);
27
  lcd.print("START SENSORS !"); 
28
}
29
void printMQ2Data(){
30
    
31
  float* values= mq2.read(true); //set it false if you don't want to print the values in the Serial
32
  //lpg = values[0];
33
  lpg = mq2.readLPG();
34
  //co = values[1];
35
  co = mq2.readCO();
36
  //smoke = values[2];
37
  smoke = mq2.readSmoke();
38
  lcd.clear(); 
39
  lcd.setCursor(0,0);
40
  lcd.print("LPG:");
41
  lcd.print(lpg);
42
  lcd.print(" CO:");
43
  lcd.print(co);
44
  lcd.setCursor(0,1);
45
  lcd.print("SMOKE:");
46
  lcd.print(smoke);
47
  lcd.print(" PPM");  
48
}
49
void printDHT22Data(){
50
  
51
  // temp sensor dht
52
 float h = dht.readHumidity(); //Luftfeuchte auslesen
53
 float t = dht.readTemperature(); //Temperatur auslesen
54
 // Prüfen ob eine gültige Zahl zurückgegeben wird. Wenn NaN (not a number) zurückgegeben wird, dann Fehler ausgeben.
55
 if (isnan(t) || isnan(h)) 
56
 {
57
 Serial.println("DHT22 konnte nicht ausgelesen werden");
58
 lcd.clear();
59
  lcd.setCursor(0,0);
60
  lcd.print("Sensor Wackelkontakt");
61
 } 
62
 else
63
 {
64
  lcd.clear();
65
  lcd.setCursor(0,0);
66
  lcd.print("Feuchte: ");
67
  lcd.print(h);
68
  lcd.print(" %"); // prozent zeichen
69
  lcd.setCursor(0,1);
70
  lcd.print("Temp:    ");
71
  lcd.print(t);
72
  lcd.print(" C");
73
  
74
  
75
 Serial.print("Luftfeuchte: "); 
76
 Serial.print(h);
77
 Serial.print(" %\t");
78
 Serial.print("Temperatur: "); 
79
 Serial.print(t);
80
 Serial.println(" C");
81
 }
82
  // end temp sensor dht 
83
}
84
 void smartDelay();
85
void setup(){
86
  timerSetup(); // timer init !
87
  Serial.begin(9600);
88
   pinMode(ledPin, OUTPUT);   // PIR   
89
 pinMode(pirPin, INPUT);     // PIR LED
90
 int pirStat = 0;
91
  lcd.begin(16,2);//Defining 16 columns and 2 rows of lcd display
92
  lcd.backlight();
93
  mq2.begin();// start mq2 gas sensor
94
  dht.begin(); // start dht tempsensor
95
  printLCDTest();
96
  lcd.clear();
97
  attachInterrupt(digitalPinToInterrupt(pirPin), interrupt_routine, CHANGE);
98
   //pinMode(pirPin, INPUT_PULLUP);
99
100
}
101
void changeLEDStatus(){
102
if(pirStat == 1)
103
{
104
105
  digitalWrite(ledPin,HIGH);
106
Serial.println("HIGH");
107
  
108
}
109
else{
110
  digitalWrite(ledPin,LOW);
111
Serial.println("LOW");
112
113
}  
114
}
115
116
117
bool checkTimerDHT(){
118
  
119
  if((timer>=2000)&&(timer <=2100)){
120
Serial.println(" 2000");
121
    return true;
122
    
123
  }
124
  else{
125
  return false;
126
  }
127
}
128
bool checkTimerMQ2(){
129
  if((timer>=4000)&&(timer <=4100)){
130
    timer=0;
131
Serial.println(" 4000");
132
    return true;
133
    
134
  }
135
  else{
136
  return false;
137
  }
138
}
139
void timerSetup(){
140
141
   TCCR0A=(1<<WGM01);    //Set the CTC mode   
142
  OCR0A=0xF9; //Value for ORC0A for 1ms
143
 
144
  TIMSK0|=(1<<OCIE0A);   //Set the interrupt request
145
  sei(); //Enable interrupt
146
 
147
  TCCR0B|=(1<<CS01);    //Set the prescale 1/64 clock
148
  TCCR0B|=(1<<CS00);
149
}
150
151
void changeLCDDisplay(){
152
  Serial.println(timer);
153
  Serial.println("checkTImerMQ2");
154
  Serial.println(checkTimerMQ2());
155
  Serial.println("checkTimerDHT");
156
  Serial.println(checkTimerDHT());
157
  if(checkTimerMQ2()==true){
158
printMQ2Data();
159
  }
160
  
161
if(checkTimerDHT()==true){
162
printDHT22Data();
163
Serial.println(" !!!!!!!!!!!!!!!!!!!!!!!!!");
164
  }
165
  else{}
166
}
167
168
void loop(){
169
changeLCDDisplay();
170
  // print gas-sensor data
171
  changeLEDStatus();
172
  //printDHT22Data();
173
  //changeLEDStatus();
174
}
175
176
177
void interrupt_routine(){
178
pirStat =!pirStat; 
179
  Serial.println("change");
180
  
181
}
182
183
184
ISR(TIMER0_COMPA_vect){    //This is the interrupt request
185
  timer++;
186
}

: Bearbeitet durch User
von Wolfgang (Gast)


Lesenswert?

Geldesch B. schrieb:
> ich weiß gar nicht ob man den timer überhaupt braucht.

Warum benutzt du nicht die Funktion millis() von Arduino. Mit deiner 
eigenen Nutzung vom Timer0 kommst du der allerdings ziemlich in die 
Quere.

Statt deiner Variablen timer könntest du auch mit millis() den von 
Arduino vorgesehehen Millisekundenzähler nutzen.

von Einer K. (Gast)


Lesenswert?

> int pirStat = 0;
Naja...
Da steckt min. eine Unsauberkeit drin und dazu auch noch ein Fehler: Das 
fehlende volatile.

Bei mir würde es ja eher so aussehen:
> volatile bool pirStat {false};

von Geldesch B. (Firma: haa) (dravr)


Lesenswert?

dankee:D

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.