Skocz do zawartości

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


Pomocna odpowiedź

2 minuty temu, ethanak napisał:

No i teraz trzeci przewód i sprawdź czy działa

Jeśli ci chodzi o to, żeby podpiąć już tak jak na schemacie, to dalej nie działa.

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.

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

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
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.

  • 10 miesiące później...

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
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
  • 1 miesiąc później...
(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

@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

@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

@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?  

Uint32 jest to zmienna dla zapamiętania aktualnego czasu w funkcji przerwania...taki filtr programowy ..

Wklej tu cały kod z tą moja wersja to sprawdzę później u siebie

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

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ę »
×
×
  • Utwórz nowe...