Skocz do zawartości
Komentator

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

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

Udostępnij ten post


Link to post
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ę! 1

Udostępnij ten post


Link to post
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

Udostępnij ten post


Link to post
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
}

 

Udostępnij ten post


Link to post
Share on other sites
(edytowany)

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

Udostępnij ten post


Link to post
Share on other sites

Tak - piny 0 i 1 to również interfejs UART używany między innymi do wgrywania programu.

  • Lubię! 2

Udostępnij ten post


Link to post
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

Udostępnij ten post


Link to post
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

Udostępnij ten post


Link to post
Share on other sites

@damianloew miło słyszeć! Powodzenia w dalszych eksperymentach 😉

  • Lubię! 1

Udostępnij ten post


Link to post
Share on other sites

Mam problem, piszę program chce go wgrać do arduino ,po 2 minutach wyskakuje mi : problem z wgrywaniem na płytkę. Czy może to być wina arduino?

 

Udostępnij ten post


Link to post
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

Udostępnij ten post


Link to post
Share on other sites

Świetnie, że udało się rozwiązać problem i wszystko już działa! W takim razie powodzenia przy dalszych eksperymentach 🚀

  • Lubię! 1

Udostępnij ten post


Link to post
Share on other sites
(edytowany)

@Kakol155 miło czytać pozytywny komentarz, zachęca to do dalszej pracy, może właśnie nad 3 częścią kursu. 😉 A miałbyś propozycje tematów? 

Edytowano przez Gieneq
  • Lubię! 1

Udostępnij ten post


Link to post
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!

Gość
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...