Skocz do zawartości

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


Komentator

Pomocna odpowiedź

A sorawdziłeś napięcue na środkowym pinie? Jeśli omyłkowo tam podłączyłeś 5V to czujnik muał prawo nie przeżyć... powinno być zero bez ruchu i 3.3V po wykryciu ruchu.

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

1 minutę temu, ethanak napisał:

A sorawdziłeś napięcue na środkowym pinie? Jeśli omyłkowo tam podłączyłeś 5V to czujnik muał prawo nie przeżyć... powinno być zero bez ruchu i 3.3V po wykryciu ruchu.

Ale ze mnie głupiec, zamiast próbować naprawić problem to zepsułem czujnik, w sensie dałem przewód zasilający 5v z arduino do środkowego pinu i masę do arduino i sprawdzilem napięcie. Wyszło 0.5v. Przepraszam

  • Lubię! 1
Link do komentarza
Share on other sites

Spokojnie, czujniki są tanie i dostępne choćby na allegro. A czegoś przy okazji się nauczyłeś.

To, że coś spalisz przy eksperymentach to normalne, ważne aby palić jak najtańsze elementy 🙂

  • Lubię! 1
Link do komentarza
Share on other sites

4 minuty temu, ethanak napisał:

Spokojnie, czujniki są tanie i dostępne choćby na allegro. A czegoś przy okazji się nauczyłeś.

To, że coś spalisz przy eksperymentach to normalne, ważne aby palić jak najtańsze elementy 🙂

Bardzo Ci dziękuję Ethanak. Postaram się zamówić czujnik w najbliższym czasie, może też nowy grot, itp. Myślę, że z nowym czujnikiem nie będzie problemu. Oby był tylko potrzebny do tego tematu, kiedyś do niego wróce 😉 Dziękuje jeszcze raz.

Link do komentarza
Share on other sites

Witam, wracam do kursów arduino po prawie roku przerwy i cieszę się że w końcu mogę wrócić do wstawiania programu rozwiązanych zadań. 

Zad 1 

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

#define KONTAKTRON 3
//#define BUZZER 9 Wersja na szaro z buzzerem

void setup() {
  pinMode(LED_R, OUTPUT);
  pinMode(LED_G, OUTPUT);
  pinMode(LED_B, OUTPUT);
  //pinMode(BUZZER, OUTPUT);

  pinMode(KONTAKTRON, INPUT_PULLUP);

  digitalWrite(LED_R, HIGH);
  digitalWrite(LED_G, HIGH);
  digitalWrite(LED_B, HIGH);

  Serial.begin(9600);
}

void loop() {
  if (digitalRead(KONTAKTRON) == HIGH){
    digitalWrite(LED_R, LOW);
    digitalWrite(LED_G, HIGH);
    
    
    //tone(BUZZER, 1000);
    //delay(500);
    //noTone(BUZZER);
    //delay(500);
    
  } else {
      digitalWrite(LED_R, HIGH);
      digitalWrite(LED_G, LOW);

      //noTone(BUZZER);
  } 
  Serial.println(digitalRead(KONTAKTRON));
}

Zad 2 

#define LED_R 13
#define LED_G 12
#define LED_B 11

#define PIR 3
#define BUZ 5

bool stan = false;

void setup() {
  pinMode(LED_R, OUTPUT);
  pinMode(LED_G, OUTPUT);
  pinMode(LED_B, OUTPUT);

  pinMode(PIR, INPUT);
  pinMode(BUZ, OUTPUT);

  digitalWrite(LED_R, LOW);
  digitalWrite(LED_G, LOW);
  digitalWrite(LED_B, LOW);
}

void loop() {
  if (digitalRead(PIR) == LOW){
    digitalWrite(LED_R, HIGH);
    digitalWrite(LED_G, LOW);
    stan = false;
      
  }else {
    digitalWrite(LED_R, LOW);
    digitalWrite(LED_G, HIGH);
    if (stan == false){
        tone(BUZ, 1000);
        delay(400);
        noTone(BUZ);
        delay(50);
        tone(BUZ, 1500);
        delay(400);
        noTone(BUZ);
        tone(BUZ, 900);
        delay(400);
        noTone(BUZ);
        
        stan = true;
    }
  }
}

Zad 3

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

#define PIR 3

void setup() {
  pinMode(LED_R, OUTPUT);
  pinMode(LED_G, OUTPUT);
  pinMode(LED_B, OUTPUT);

  pinMode(PIR, INPUT);

  digitalWrite(LED_R, HIGH);
  digitalWrite(LED_G, LOW);
  digitalWrite(LED_B, HIGH);

  attachInterrupt(digitalPinToInterrupt(PIR), alarm, FALLING);
}

void loop() {
  digitalWrite(LED_SYG, LOW);
  delay(2000);
  digitalWrite(LED_SYG, HIGH);
  delay(2000);
}

void alarm(){
  digitalWrite(LED_R, LOW);
  digitalWrite(LED_G, HIGH);
}

Zad 4

#define LED_R 10
#define LED_G 11

#define PIR 3

volatile bool stan = false;

void setup() {
  pinMode(LED_R, OUTPUT);
  pinMode(LED_G, OUTPUT);

  pinMode(PIR, INPUT);

  digitalWrite(LED_R, HIGH);
  digitalWrite(LED_G, HIGH);

  attachInterrupt(digitalPinToInterrupt(PIR), alarm, RISING);
}

void loop() {
  if (stan == false){
    digitalWrite(LED_R, HIGH);
    digitalWrite(LED_G, LOW);
  } else {
    digitalWrite(LED_R, LOW);
    digitalWrite(LED_G, HIGH);
  }
}

void alarm() {
  if(stan == true){
    stan = false;
  } else {
    stan = true;
  }
}

Ufff... trochę tego było ale jakoś dałem rade. Osobiście stwierdzam że kurs zaczyna się świetnie, warto podszkolić swoje umiejętności bo po poprzednim trochę się pozapominało. Będę wdzięczny ocenę za moich rozwiązań i gratuluje autorowi stworzenia genialnego kursu.

  • Lubię! 1
Link do komentarza
Share on other sites

Dnia 31.03.2023 o 21:19, solowkidamian napisał:

Osobiście stwierdzam że kurs zaczyna się świetnie, warto podszkolić swoje umiejętności bo po poprzednim trochę się pozapominało. Będę wdzięczny ocenę za moich rozwiązań i gratuluje autorowi stworzenia genialnego kursu.

Miło słyszeć, że kurs się podoba! Wszystko wygląda dobrze, na przyszłość warto dodać jakieś komentarze (nawet w tak prostych kodach), aby po czasie łatwiej załapać co dokładnie ten kod robi. Teraz na pewno pamiętasz czym jest "if(stan == true)", ale za jakiś czas może być ciężko z przypomnieniem sobie czym jest "stan" i co w tym przypadku oznacza true/false.

  • Lubię! 1
Link do komentarza
Share on other sites

(edytowany)

Witam.  Mam pytanie odnośnie przerwań a konkretnie wykonywania funkcji w przerwaniu. Normalnie funkcja powinna wykonać się tylko raz na przerwanie. W moim przypadku wykonuje się kilka razy i nie wiem dlaczego?

 pinMode(3,INPUT_PULLUP); //czujnik obrotow
  attachInterrupt(digitalPinToInterrupt(3),licz,FALLING);

}

void loop() {
  aktualnyCzas=millis();
  dioda();
  obroty();
}

//Miganie dioda
 void dioda(){
    if (aktualnyCzas-zapamietanyCzas>=200UL){
      zapamietanyCzas=aktualnyCzas;
      stanLED=!stanLED;
      digitalWrite(13,stanLED);
    }
 }

 void licz() {
  impulsy++;
  Serial.println(impulsy);
 }

 void obroty() {
  if (aktualnyCzas-duration>=1000UL) {
    duration=aktualnyCzas;
    obr=impulsy*60/6;
    impulsy=0;
    Serial.print(obr);
    Serial.println(" ob/min");
  }
 }

Chodzi o funkcję licz. Ma być inkrementowana zmienna impulsy o jeden gdy pojawi się sygnał na pinie 3. W praktyce po jednym impulsie z czujnika mam wartość licznika 2,4,8 a nawet 32 się zdarzyło. Zauważyłem, że również nie ma znaczenia czy wstawię RISING, FALLING,LOW,HIGH program zawsze reaguje i na 0 i na 1 od czujnika. Pytanie co robię źle, lub może płytka jest uszkodzona?

Edytowano przez PierotB
Nie widzę swojego postu
Link do komentarza
Share on other sites

@PierotB witam na forum 🙂 Jak rozumiem pytania nie dotyczy żadnego konkretnego przykładu z tego kursu. Co dokładnie masz podłączone do Arduino w roli czujnika? Prawdopodobnie jest to kwestia drgań styków tego czujnika. Możesz dodać np. filtr RC, aby wyeliminować ten problem: https://forbot.pl/blog/czym-jest-filtr-rc-jak-dziala-i-co-warto-o-nim-wiedziec-id40448

Link do komentarza
Share on other sites

@PierotB sprobuj tego 

uint32_t last = 0;
 
 
 void setup() {
  pinMode(3,INPUT_PULLUP); //czujnik obrotow
  attachInterrupt(digitalPinToInterrupt(3),licz,FALLING);

}

void loop() {
  aktualnyCzas=millis();
  dioda();
  obroty();
}

//Miganie dioda
 void dioda(){
    if (aktualnyCzas-zapamietanyCzas>=200UL){
      zapamietanyCzas=aktualnyCzas;
      stanLED=!stanLED;
      digitalWrite(13,stanLED);
    }
 }

 void licz() {
  if (millis() - last > 200UL) {
  impulsy++;
  Serial.println(impulsy);
  last = millis();
   }
 }

 void obroty() {
  if (aktualnyCzas-duration>=1000UL) {
    duration=aktualnyCzas;
    obr=impulsy*60/6;
    impulsy=0;
    Serial.print(obr);
    Serial.println(" ob/min");
  }
 }

tylko sobie dopisz swoje zmienne globalne bo ci sie nie chcialo calego kodu skopiowac

Link do komentarza
Share on other sites

@farmaceuta Niestety nie pomogło. A co to ma robić uint32_t last = 0;? Mógłbyś wyjaśnić? 

Czujnik, który posiadam to szczelinowy 10mm z komparatorem LM393, nie sądzę aby podawał kilka impulsów ale odpiąłem go i wpiąłem kabelek bezpośrednio podając masę. Sytuacja jest identyczna. Ciekawe jest, że jeśli nie robię tego na przerwaniu to jest całkiem nieźle jednak są delikatne przekłamania w wyższej prędkości. Biorąc pod uwagę, że teraz nic innego nie działa oprócz migającej diody to jakoś sobie radzi ale po dopisaniu większego kodu mogą być większe przekłamania. Ma ktoś może jeszcze jakiś pomysł, a może jakiś test samego aruino?  

Link do komentarza
Share on other sites

uint32_t last = 0;
int impulsy = 0;
 
 void setup() {
  pinMode(3,INPUT_PULLUP); //czujnik obrotow
  attachInterrupt(digitalPinToInterrupt(3),licz,FALLING);
  Serial.begin(9600);
}

void loop() {
  
}



 void licz() {
  if (millis() - last > 200UL) {
  impulsy++;
  Serial.println(impulsy);
  last = millis();
   }
 }

 

kod powyzej u mnie dziala bez zarzutu...sprawdzany na guziku

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.