von
Geldesch B.
(Firma: haa)
(dravr )
22.12.2019 11:16
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 !!!!
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 )
22.12.2019 11:55
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 }
22.12.2019 12:16 :
Bearbeitet durch User
von
STK500-Besitrzer (Gast)
22.12.2019 12:40
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 )
22.12.2019 12:57
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 }
22.12.2019 13:00 :
Bearbeitet durch User
von
Wolfgang (Gast)
22.12.2019 13:29
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)
22.12.2019 14:48
> 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 )
22.12.2019 23:25
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.