Skocz do zawartości

Biblioteka Gyver.OS oraz przerwania, problem z zatrzymaniem


Pomocna odpowiedź

Napisano (edytowany)
#include <GyverOS.h>
GyverOS<6> OS;



#define B1 2
#define B2 3
#define LED1 4
#define LED2 5
#define S1 9
#define S2 10
#define BUZZER A5

bool podtrzymanieS1 = 0; 
bool przyciskS1;

bool podtrzymanieS2 = 0; 
bool przyciskS2;

bool podtrzymanieS3 = 0; 
bool przyciskS3;

int stanLED1 = LOW;
int stanLED2 = LOW;



unsigned long aktualnyCzas = 0;
unsigned long zapamietanyCzasLED = 0;
unsigned long zapamietanyCzasBUZ = 0;
unsigned long zapamietanyCzasSIL = 0;



void setup() {
  // Przypisanie wejść i wyjść
  pinMode(9, INPUT_PULLUP); //Przycisk "start" S1
  pinMode(10, INPUT_PULLUP); //Przycisk "zamykanie" S2
  pinMode(11, INPUT_PULLUP); //Przycisk "stop" S3
  
  pinMode(6, OUTPUT); //Sterowanie prędkością silnika M1
  pinMode(7, OUTPUT); //Sterowanie kierunkiem obrotu
  pinMode(8, OUTPUT); //Sterowanie kierunkiem obrotu
  
  pinMode(4, OUTPUT); // Sygnalizacja D2, D4
  pinMode(5, OUTPUT); //Sygnalizacja D1, D3

  pinMode(2, INPUT_PULLUP); //Krańcówka B1
  pinMode(3, INPUT_PULLUP); //Krańcówka B2
  
  
  pinMode(A5, OUTPUT); //Buzzer M2

  digitalWrite(A5, LOW); //Wyłączenia buzzera
  digitalWrite(4, LOW); //Wyłączenie świateł D2, D4
  digitalWrite(5, LOW); //Wyłączenie świateł D1, D3


 OS.attach(0, obrotyL, 100);
 OS.attach(1, obrotyP, 100);
 OS.attach(2, sygnalizacja, 100);
 OS.attach(3, dzwiek, 100);

attachInterrupt(digitalPinToInterrupt(2), zakonczenie, RISING);
attachInterrupt(digitalPinToInterrupt(3), zatrzymanie, RISING);  



}

void loop(){
  OS.tick();
  OS.stop(0);
  OS.stop(1);
  OS.stop(2);
  OS.stop(3);
  
przyciskS1 = !digitalRead(9);
  if (przyciskS1==1 and podtrzymanieS1==0){
   int podtrzymanieS1 = 1;
 
 while (int podtrzymanieS1=1){
 OS.exec(2);
 OS.exec(3);
 OS.exec(0);
    
  
  }   
}
  


  przyciskS2 = !digitalRead(10);
  if (przyciskS2==1 and podtrzymanieS2==0){
   int podtrzymanieS2 = 1;
 
   while (int podtrzymanieS2=1){

OS.exec(1);
OS.exec(2);
OS.exec(3);
    } 
  }

}



void obrotyL(){
  aktualnyCzas = millis();
  if (aktualnyCzas - zapamietanyCzasSIL >= 5000UL) 
    {
      zapamietanyCzasSIL = aktualnyCzas;
  
    analogWrite(6, 255);
    digitalWrite(7, LOW); //Silnik nr 1 - obroty w lewo
    digitalWrite(8, HIGH);
    }
}

void obrotyP(){
  aktualnyCzas = millis();
  if (aktualnyCzas - zapamietanyCzasSIL >= 5000UL) 
    {
      zapamietanyCzasSIL = aktualnyCzas;
  
  
    analogWrite(6, 255);
    digitalWrite(7, HIGH); //Silnik nr 1 - obroty w prawo
    digitalWrite(8, LOW);
    }
    
}

void sygnalizacja(){
  
    aktualnyCzas = millis();
  if (aktualnyCzas - zapamietanyCzasLED >= 500UL) 
    {
      
    zapamietanyCzasLED = aktualnyCzas;
    stanLED1 = !stanLED1;
    digitalWrite(LED1, stanLED1);

    stanLED2 = !stanLED2;
    digitalWrite(LED2, !stanLED2);
    
    }

}

void dzwiek(){
  
    aktualnyCzas = millis();
  if (aktualnyCzas - zapamietanyCzasBUZ >= 1000UL) 
    {
      
    zapamietanyCzasBUZ = aktualnyCzas;
    tone(A5, 3000, 500);
    }
}

void zatrzymanie(){
  
 
    digitalWrite(7, LOW); //Zatrzymanie silnika
    digitalWrite(8, LOW);
    
    OS.detach(0);
    OS.detach(1);
    OS.exec(2);
    OS.exec(3);
    
}


void zakonczenie(){
   
   noTone(A5); //Wyłączenia buzzera
  digitalWrite(4, LOW); //Wyłączenie świateł D2, D4
  digitalWrite(5, LOW); //Wyłączenie świateł D1, D3
  digitalWrite(7, LOW); //Zatrzymanie silnika
    digitalWrite(8, LOW);
    OS.detach(2); //Wyłączenie funkcji
    OS.detach(3);
    OS.detach(0);
    
    
}

Tworzę projekt mostu zwodzonego, i chciałem zrobić sterowanie na 3 przyciski. S1 ruch mostu do góry, S2 ruch mostu w dół i S3 zatrzymanie obrotu silnika.

W trakcie pracy Migają światła i buzzer. Na funkcji do przerwania "zakończenie" dałem krańcówkę która wyłącza wszystko gdy most zamknięty. 

Jednak mam problem z drugim przerwaniem z wyjściem (3), do którego podłączyłem drugą krańcówkę i przycisk S3. Chciałem żeby zadziałanie przycisku powodowało zatrzymanie tylko obrotów silnika a światła i buzzer dalej działały jednak po wciśnięciu S3 wyłącza się wszystko.

Czy mógłby ktoś podsunąć pomysł jakby to można było rozwiązać?

Edytowano przez Merasuke
void zatrzymanie(){
  
 
    digitalWrite(7, LOW); //Silnik nr 1 - obroty w prawo
    digitalWrite(8, LOW);
    
    OS.detach(0);
    OS.detach(1);
    OS.exec(2);
    OS.exec(3);
    
}

chodzi o ten fragment

(edytowany)
1 godzinę temu, farmaceuta napisał:

Co to za dziwne warunki?? 



while (int podtrzymanieS1 = 1)

 

jak dawałem bez tego while to włączał się silnik ale światła i buzer nie migały tylko raz się załączyły. Także to tak wyszło metodą prób i błędów i zadziało to zostawiłem XD

Edytowano przez Merasuke
(edytowany)

@Merasuke, łatwiej się czyta wiadomości, gdy ktoś je sensownie formatuje. W tym nie pisze własnej odpowiedzi w bloku cytatu cudzej wypowiedzi.

@farmaceuta postanowił w ten tajemniczy sposób, bezskutecznie najwyraźniej, zwrócić Twoją uwagę na to, że to nie jest warunek, bo tak, jak to napisałeś, jest to równoznaczne z while (1), czyli pętla nieskończona.

Edytowano przez trainee
  • Lubię! 1
13 minut temu, trainee napisał:

@Merasuke, łatwiej się czyta wiadomości, gdy ktoś je sensownie formatuje. W tym nie pisze własnej odpowiedzi w bloku cytatu cudzej wypowiedzi.

@farmaceuta postanowił w ten tajemniczy sposób, bezskutecznie najwyraźniej, zwrócić Twoją uwagę na to, że to nie jest warunek, bo tak, jak to napisałeś, jest to równoznaczne z while (1), czyli pętla nieskończona.

Dzięki, poprawiłem.

9 godzin temu, Merasuke napisał:

#define B1 2
#define B2 3
#define LED1 4
#define LED2 5
#define S1 9
#define S2 10
#define S3 11
#define B1 2
#define B2 3
#define LED1 4
#define LED2 5

Mogę też zasugerować oglądanie komunikatów, jakie wyświetla kompilator, bo nawet w domyślnej konfiguracji, w której zasadniczo milczy, wspomni o tym, że dwukrotnie definiujesz te same makra. To nie jest problem psujący zamierzone działanie, to tak tylko na marginesie, odnośnie rzeczy, które od razu rzucają się w oczy.

A jeszcze lepiej jak w File/Preferences, przełączy się Warnings na All. W każdym razie o ile to Arduino IDE, a tak może się wydawać.

  • Lubię! 1
7 minut temu, Merasuke napisał:

Dzięki, poprawiłem.

Aleeee-ee-e... czy Ty zmieniłeś też linijkę kodu w pierwszym poście, tę, do której odnosił się potem @farmaceuta? Bo w ten sposób to dopiero robi się zamieszanie, gdy pierwotne pytanie przestaje pasować do ciągu dalszego wątku.

@trainee dobra dałem z powrotem, jak pisałeś że to to samo to myślałem że nic to nie zmieni. Ostateczne pytanie i tak tyczy jak tu dać ten przycisk S3 żeby po jego wciśnięciu wyłączył się tylko silnik a światła dalej migały.

@trainee

  //OS.detach(0); // disable task 0
  //OS.setPeriod(0, 200); // change task period 0 to 200 ms
  //OS.start(0); // start task 0
  //OS.stop(0); // stop task 0
  //OS.exec(0); // do task 0 now

nie bardzo rozumiem czemu nie mogę wywoływać exec. Jest wypisana w funkcjach biblioteki. Z początku próbowałem na funkcjach start stop ale w ogóle nie reagowało na przyciski.

(edytowany)

Czy w każdym programie używasz każdej funkcji jaka jest dostępna w bibliotekach, które stosujesz? To nie jest tak, że jest to zakazane i nie istnieją przypadki, dla których ostatecznie można byłoby jej użyć. Ale w praktyce jest to dość pozbawione sensu, bo OS.exec(1) robi tyle samo w Twoim kodzie, co zrobiłoby po prostu napisanie obrotyP(). Więc wtedy pojawia się pytanie, po co ta cała biblioteka? Używanie bibliotek ma wtedy sens, gdy rozumie się, po co chce się ich użyć. Ta konkretna jest prostym planistą zadań i te zadania wywołują się "same" w momencie wywołania OS.tick(). U Ciebie się nie wywołują, bo zawieszasz kod w pętli nieskończonej while (1).

Edytowano przez trainee

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