Skocz do zawartości

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


Komentator

Pomocna odpowiedź

1 minutę temu, Treker napisał:

To ja już nie mam innego pomysłu, chyba faktycznie "udało Ci się" uszkodzić Arduino w tak niestandardowy sposób 😉

Na to wychodzi 😄 Ważne że komunikacja przez UART działa bez zarzutu. Dzięki wielkie za pomoc w szukaniu usterki! :

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

Mam problem z zadaniem 4.4

zrobiłem 'ręcznie'  ale nie mam pomysłu jak to zautomatyzować

#define LED_R 10
#define LED_G 11
#define LED_B 12
#define LED_13 13
 
#define KONTAKTRON 0
#define PIR 2

volatile int ileRazy = 0;

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); //PIR jako wejście
    
  digitalWrite(LED_R, LOW);
  digitalWrite(LED_G, HIGH);
  digitalWrite(LED_B, LOW);

  attachInterrupt(digitalPinToInterrupt(PIR), alarm, RISING); // Przerwanie reagujące na zbocze rosnące
}
 
void loop() {
  if (ileRazy == 0) { 
    digitalWrite(LED_R, LOW);
    digitalWrite(LED_G, HIGH);
    digitalWrite(LED_B, LOW);    
  } else if (ileRazy == 1) { 
    digitalWrite(LED_R, LOW);
    digitalWrite(LED_G, LOW);
    digitalWrite(LED_B, LOW);   
  } else if (ileRazy == 2) { 
    digitalWrite(LED_R, LOW);
    digitalWrite(LED_G, HIGH);
    digitalWrite(LED_B, LOW);  
  } else if (ileRazy == 3) { 
    digitalWrite(LED_R, LOW);
    digitalWrite(LED_G, LOW);
    digitalWrite(LED_B, LOW);   
  } else if (ileRazy == 4) { 
    digitalWrite(LED_R, LOW);
    digitalWrite(LED_G, HIGH);
    digitalWrite(LED_B, LOW);   
  } else if (ileRazy == 5) { 
    digitalWrite(LED_R, LOW);
    digitalWrite(LED_G, LOW);
    digitalWrite(LED_B, LOW);   
  }
}

void alarm() { //Przerwanie
  ileRazy++; //Wykryto kolejny alarm
}

 

//

Działające wersje pozostałych zadań

4.1

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

#define KONTAKTRON 0

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(A5, OUTPUT); //Konfiguracja A5 jako wyjście
  
  digitalWrite(LED_R, LOW); //Dioda wyłączona
  digitalWrite(LED_G, LOW);
  digitalWrite(LED_B, LOW);
}

void loop() {
  if (digitalRead(KONTAKTRON) == LOW) { //Jeśli czujnik zwarty
    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);
    tone(A5, 3500);
  }
}

4.2

#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); //PIR jako wejście
    
  digitalWrite(LED_R, LOW); //Dioda wyłączona
  digitalWrite(LED_G, LOW);
  digitalWrite(LED_B, LOW);

  pinMode(A5, OUTPUT); //Konfiguracja A5 jako wyjście
}

void loop() {
  if (digitalRead(PIR) == LOW) { //Jeśli wykryto ruch
    digitalWrite(LED_R, LOW); //Stan OK - dioda zielona
    digitalWrite(LED_G, HIGH);
    noTone(A5);
  } else {
    digitalWrite(LED_R, HIGH); //Stan ALARM - dioda czerwona
    digitalWrite(LED_G, LOW);
    tone(A5, 4300); //Wygeneruj sygnał o częstotliwości 4300Hz na pinie A5  
    delay(150);  
    tone(A5, 3500); //Wygeneruj sygnał o częstotliwości 3500Hz na pinie A5  
    delay(150);
  }
}

4.3

#define LED_R 10
#define LED_G 11
#define LED_B 12
#define LED_SYG 13
 
#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(LED_SYG, OUTPUT);
 
  pinMode(KONTAKTRON, INPUT_PULLUP); //Kontaktron jako wejście
  pinMode(PIR, INPUT); //PIR jako wejście
    
  digitalWrite(LED_R, LOW);
  digitalWrite(LED_G, HIGH);
  digitalWrite(LED_B, LOW);

  attachInterrupt(digitalPinToInterrupt(PIR), alarm, FALLING); // wywołanie, gdy następuje zmiana wartości ze stanu wysokiego na niski
}
 
void loop() {

}

void alarm() {
    digitalWrite(LED_R, HIGH); //Stan ALARM - dioda czerwona
    digitalWrite(LED_G, LOW);
}

 

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

6 godzin temu, szon napisał:

zrobiłem 'ręcznie'  ale nie mam pomysłu jak to zautomatyzować

Do tego tematu możesz podejść na kilka sposobów. Jeden z nich to wykorzystanie zmiennej, którą zliczasz przełączenia. Oczywiście twoja wersja zadziała, ale przy 6 razie już niekoniecznie. 

Pierwsze co bym zmienił, to przeniósłbym kod odpowiedzialny za przełączanie wyjść (sterowanie LED), tam gdzie wykona się jedynie w momencie zmian:

void alarm() { //Przerwanie
  ileRazy++; //Wykryto kolejny alarm
  //tutaj <<----------
}

W ten sposób wyjścia będą przełączane tuż po inkrementacji zmiennej. A w jaki sposób poradzić sobie z napisaniem logiki?

Pomyśl co wspólnego mają przypadki ileRazy = 1,3,5 oraz 2, 4? Jedne to liczby nieparzyste drugie parzyste? A jak wyznaczyć kryterium oceniające która jest która? Np, sprawdzić podzielność przez 2. W tym celu tworzysz prosty warunek sprawdzający resztę z dzielenia:

if(ilerazy % 2 == 0){
  //2,4,6...
}
else {
  //1,3,5...
}

To podejście jest skrupulatne, ale zmienna ileRazy kiedyś się przepełni. Żeby tego uniknąć i zbliżyć się bardziej do istoty zadania, można uprościć sytuację i pozbyć się zmiennej. W tym celu w momencie wykrycia ruchu zrobimy to co jest w treści zadania - zmienimy stan na przeciwny. Jak?

Zapisz do pinu to co z niego odczytałeś ale z negacją:

digitalWrite(pin, !digitalRead(pin));

Bez dodatkowej zmiennej, kod działa wieczność. Jak chcesz dowiedzieć się więcej, możesz poszukać czegoś o operacji XOR, która przełącza wyjście. W C++ zapisuje się ją przy pomocy "daszka" ^.

  • Lubię! 1
  • Pomogłeś! 1
Link do komentarza
Share on other sites

@Gieneq Dzięki! Oba sposoby działają. 

4.4 z negacją

#define LED_R 10
#define LED_G 11
#define LED_B 12
#define LED_13 13
 
#define KONTAKTRON 0
#define PIR 2

void setup() {
  Serial.begin(9600); //Ustawienie prędkości transmisji
  pinMode(LED_R, OUTPUT); //Poszczególne piny sterujące diodą jako wyjścia
  pinMode(LED_G, OUTPUT);
  pinMode(LED_B, OUTPUT);
  pinMode(7, OUTPUT);
 
  pinMode(KONTAKTRON, INPUT_PULLUP); //Kontaktron jako wejście
  pinMode(PIR, INPUT); //PIR jako wejście
    
  digitalWrite(LED_R, LOW);
  digitalWrite(LED_B, LOW);
    
  attachInterrupt(digitalPinToInterrupt(PIR), alarm, RISING); // Przerwanie reagujące na zbocze rosnące
}
 
void loop() { 
}

void alarm() { //Przerwanie
  digitalWrite(LED_G, !digitalRead(LED_G));  // negacja
}

 

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

Witam, przy programie z kontaktronem zaczęły występować u mnie problemy z wgrywaniem programu na płytkę. Na jednej ze stron znalazłem informację, że piny 0 i 1 powinny być wolne, więc zmieniłem pin i problem narazie nie występuje. Czy faktycznie podłączanie elementów pod jeden z tych dwóch pinów powinno sprawiać podobne problemy?

Edytowano przez damianloew
Link do komentarza
Share on other sites

Dnia 30.07.2019 o 10:20, damianloew napisał:

Czy faktycznie podłączanie elementów pod jeden z tych dwóch pinów powinno sprawiać podobne problemy?

Wszystko zależy od tego jakie to elementy i co dokładnie robią - nie wszystkie będą zakłócały programowanie. Na pewno warto jednak unikać korzystania z pinów 0/1, jeśli chcemy wykorzystywać UART.

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

@Treker Dzięki, swoją drogą świetne są te wasze kursy, mam nadzieję że będzie ich powstawało coraz więcej. Sam po kursie podstaw Arduino tak się wciągnąłem, że zakupiłem elementy do kursów: Arduino II, Elektroniki I i II, Techniki cyfrowej, Budowy robotów i lutowania i od dłuższego czasu konsekwentnie je realizuję. Pozdrawiam 

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

@jas123 czy problem pojawił się dopiero teraz, a wcześniej płytka działała poprawienie? Masz wyłączony monitor portu szeregowego i inne programy, które mogą łączyć się z Arduino przez UART? Nie masz nic podłączonego do pinów 0 oraz 1?

  • Pomogłeś! 1
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.