Skocz do zawartości

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


Komentator

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.

Link do komentarza
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.

Link do komentarza
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.

Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

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.

Link do komentarza
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.

Link do komentarza
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 😉

Link do komentarza
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
Link do komentarza
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?

Link do komentarza
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 🙂

Link do komentarza
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
Link do komentarza
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;
 }

}
Link do komentarza
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Anonim
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.