Skocz do zawartości
Komentator

Kurs Arduino II - #4 - przerwania, kontaktron, czujnik PIR

Pomocna odpowiedź

grg0, tak wszystko zacznie działać znowu dalej. Po prostu w tym trybie ciągły ruch powoduje przedłużanie stanu alarmowego na wyjściu, ponieważ każde wykrycie powoduje odliczanie czasu Tx od początku. W drugim trybie tylko pierwszy ruch powoduje start odliczania czasu Tx.

Inaczej mówiąc, jeśli ruch trwa 2 sekundy, a na Tx mamy 3 sekundy, to:

- w pierwszej sytuacji stan alarmowy potrwa 5 sekund,
- w drugiej sytuacji stan alarmowy potrwa 3 sekundy.

Udostępnij ten post


Link to post
Share on other sites

Czy to jest też tak, że po przejściu w stan niski czujnik czeka tyle samo co w stanie wysokim aż zacznie rejestrację kolejnego stanu? Mam często tak, że jeśli wykryje ruch, potem zmieni stan na brak ruchu to jeśli od razu znowu ruszam ręką to już tego nie wykrywa. A jeśli 'dam mu odpocząć' na parę sekund to znowu zaczyna łapać ruch poprawnie.

Udostępnij ten post


Link to post
Share on other sites
Będą dalsze części?

Oczywiście, że będą. Planowane odcinki są widoczne w zapowiedzi kursu: Kurs Arduino, poziom II – #1 – wstęp, spis treści

Gut6, w nocie katalogowej można znaleźć informację o około 2,5 sekundy opóźnienia przed kolejnym alarmem, więc pewnie to właśnie ten czas 🙂 Jest on niezależny od ustawień na potencjometrach.

Udostępnij ten post


Link to post
Share on other sites

Dzięki. Chyba jednak jest to te 5 sekund bo policzyłem. Po wykryciu braku ruchu alarm włączy się ponownie dopiero po 5 sekundach. Przynajmniej wiem już o co w ogóle chodzi. 😉 Wcześniej myślałem, że to może jakiś wadliwy czujnik.

Udostępnij ten post


Link to post
Share on other sites

Kolejny odcinek kursu Arduino pojawi się już w najbliższy czwartek 🙂 Zajmiemy się budową chyba najbardziej praktycznego do tej pory projektu - prostej centralki alarmowej! Przy okazji będzie kilka słów o trochę innym podejściu do pisania dłuższych programów.

Udostępnij ten post


Link to post
Share on other sites

Cześć, mam pytanie do fragmentu z części "HC-SR501 w praktyce":

#define LED_R 10
#define LED_G 11
#define LED_B 12

#define KONTAKTRON 0
#define PIR 2

void setup() {
 pinMode(LED_R, OUTPUT); //Poszczególne piny sterujące diodą jako wyjścia
 pinMode(LED_G, OUTPUT);
 pinMode(LED_B, OUTPUT);

 pinMode(KONTAKTRON, INPUT_PULLUP); //Kontaktron jako wejście
 pinMode(PIR, INPUT_PULLUP); //PIR jako wejście

 digitalWrite(LED_R, LOW); //Dioda wyłączona
 digitalWrite(LED_G, LOW);
 digitalWrite(LED_B, LOW);
}

void loop() {
 if (digitalRead(PIR) == LOW) { //Jeśli wykryto ruch
   digitalWrite(LED_R, LOW); //Stan OK - dioda zielona
   digitalWrite(LED_G, HIGH);
 } else {
   digitalWrite(LED_R, HIGH); //Stan ALARM - dioda czerwona
   digitalWrite(LED_G, LOW);
 }
}

Rozumiem, że podłączamy wyjście OUT sensora do pinu 2 Arduino i ustawiamy go z wewnętrznym rezystorem podciągającym wejście.

Później sprawdzamy, czy wykryto ruch (gdy stan LOW), tylko czemu w tym momencie włączamy diodę zieloną ?

Czy ten kod z poradnika jest poprawny?

Oraz drugie pytanie: czy tryb H uzyskuje łącząc pin środkowy z pinem H, czy nie łącząc nic ?

Mam czujnik z zestawu Botland, ktory wyglada mniej wiecej tak (ma zworke):

Pozdrawiam 😉

Udostępnij ten post


Link to post
Share on other sites

m_rat, witam na forum 🙂 Kod jest poprawny. Gdy czujnik wykryje ruch na jego wyjściu otrzymamy stan wysoki. Może faktycznie komentarz wprowadza w błąd. Lepiej byłoby tak jak poniżej. W każdym razie sam kod powinien działać poprawnie (czyli tak jak na filmie), czy masz z nim jakieś problemy?

 if (digitalRead(PIR) == LOW) { //Sprawdzamy stan czujnika
   digitalWrite(LED_R, LOW); //Stan OK - dioda zielona 
   digitalWrite(LED_G, HIGH); 
 } else { 
   digitalWrite(LED_R, HIGH); //Stan ALARM - dioda czerwona 
   digitalWrite(LED_G, LOW); 
 } 
Oraz drugie pytanie: czy tryb H uzyskuje łącząc pin środkowy z pinem H, czy nie łącząc nic ? Mam czujnik z zestawu Botland, ktory wyglada mniej wiecej tak (ma zworke):

Jeśli masz zworkę, to zwyczajnie przekładasz ją z jednej pozycji na drugą czyli na zasadzie "środkowy pin i skrajny lewy" "środkowy pin i skrajny prawy". Inaczej się fizycznie nie da, ponieważ musisz połączyć pin od wybranego trybu z tym środkowym.

  • Lubię! 1

Udostępnij ten post


Link to post
Share on other sites

Mam wątpliwości co do zrozumienia INPUT_PULLUP, bo z artykułu na Forbocie: "Rezystor sprawia, że gdy microswitch jest rozwarty występuje na wejściu stan wysoki, a gdy zostaje zwarty, stan przechodzi w niski (połączenie Pull-up).".

I tu bym zrozumiał to w ten sposób, że LOW -> wcisniety, HIGH -> puszczony i to rozumowanie się sprawdzało do tego momentu, gdy nadszedł PIR.

Ponieważ tu sprawdzamy według zasady LOW -> brak ruchu, HIGH -> ruch.

Czy pull-up nie powinien trzymać cały czas HIGH, gdy nie ma sygnału z sensora?

Drugi problem jest taki, że przy tym kodzie i skręconych Tx i Sx na minimum (max obrót przeciwnie do wskazówek) i ustawionym trybie H mam efekt:

Arduino włącza się, dioda zielona, gdy wykonam ruch, zapala się czerwona i taki stan jest przez 5s, po czym włącza się zielona.

I tu by było wszystko okej, ale:

-gdy wykonam ruch od razu po włączeniu zielonej to czujnik i tak czeka nastepne 5s i dopiero wtedy wlacza sie czerwona.

-gdy wykonam ruch 5s od swiecenia diody zielonej to ruch wykrywany jest od razu, zapala sie czerwona i trzyma taki stan 5s.

Skad bierze się to opoznienie?

Udostępnij ten post


Link to post
Share on other sites

Czy nikt nie zna odpowiedzi na te pytania?

Udostępnij ten post


Link to post
Share on other sites

m_rat, wybacz brak odpowiedzi - nie miałem pod ręką czujnika w niedzielę, aby to sprawdzić i temat później umknął.

Jeśli nie uda mi się zrobić testu jeszcze dziś, to na pewno dam znać jutro 🙂

Udostępnij ten post


Link to post
Share on other sites

Nie ma sprawy, to czekam na te dwa męczące mnie pytania (INPUT_PULLUP oraz to dziwne opóźnienie) 😉 !

Udostępnij ten post


Link to post
Share on other sites

m_rat, udało mi się dorwać czujnik, więc odpowiadam! Jeśli chodzi o INPUT_PULLUP, to faktycznie wkradł tu się błąd i w przypadku tego PIRa powinniśmy deklarować wejście bez rezystora podciągającego. Sprawdziłem jednak dla pewności obie wersję programu i czujnik działa poprawnie w każdej z konfiguracji, więc nie jest to dużym problemem. Jednak faktycznie zgodnie ze sztuką powinien być sam INPUT (poprawię w artykule) - dzięki za wyłapanie błędu 🙂 Różnica była jedynie taka, że z rezystorem podciągającym przy braku ruchu otrzymywaliśmy 0,3V zamiast 0V. Pullup nie powodował zmiany sygnału na wejściu do 3.3V, ponieważ przez rezystor podciągający płynie stosunkowo mały prąd. Sygnał od czujnika był więc "mocniejszym" stanem logicznym, który ściągał całość blisko 0V.

Temat różnych czasów i opóźnień najprościej sprowadzić mi do odpowiedzi "ten czujnik tak ma" 😉 Dokładny sposób jego działania jest opisany w każdej dokumentacji trochę inaczej... Ogólnie mówiąc wychodzi na to, że ustawienia jednego z potencjometrów wpływają dodatkowo na czas blokady, którą zauważyłeś. Fragment jednej z dokumentacji: " induction blocking time (the default setting: 2.5S block time): sensor module, after each sensor output (high change Into a low level), you can set up a blockade followed by time period, in this time period the sensor does not accept any sensor signal. " Aby zmienić ten czas trzeba pobawić się już lutownicą - szczegóły: https://www.elecfreaks.com/wiki/index.php?title=PIR_Motion_Sensor_Module:DYP-ME003#Changing_pulse_time_and_timeout_length

  • Lubię! 1

Udostępnij ten post


Link to post
Share on other sites

Teraz wszystko jasne.

Nie ma za co 🙂

Ja również dziękuje za wyjaśnienia oraz ten kurs.

Pozdrawiam!

Udostępnij ten post


Link to post
Share on other sites

Witam pytanie w sprawie PIR. Zastanawia mnie czy mogę w jakiś sposób skrócić moment w którym jest HIGH. Czy też tak macie że po stanie wysokim trzeba jakąś chwilę odczekać i dopiero potem PIR jest w stanie znowu wykryć ruch.

#include "pitches.h"
int melody[] = {
 NOTE_GS7, NOTE_AS6, NOTE_D7, 0, NOTE_C8, NOTE_B5
};
int durations [] = {
 8, 8, 4, 4, 8, 8
};
void setup() {
 pinMode(2, INPUT);
 Serial.begin(9600);
}
boolean wejscie = false;
int licznik = 0;
void loop() {
 if(digitalRead(2) == HIGH) {
   Serial.println(licznik = licznik + 1);
 }

 if(digitalRead(2) == HIGH && wejscie == false) {
       for (int thisNote = 0; thisNote < 3; thisNote++) {
     int duration = 1000 / durations[thisNote];
     tone(A5, melody[thisNote], duration);
     int pause = duration * 1.30;
     delay(pause);
     noTone(A5);
   }
    wejscie = true;
 }
 if(digitalRead(2) == LOW){
   noTone(A5);
   wejscie = false;
   licznik = 0;
 }

}

Udostępnij ten post


Link to post
Share on other sites

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »

×