• Witaj na Forum Arduino Polska! Zapraszamy do rejestracji!
  • Znajdziesz tutaj wiele informacji na temat hardware / software.
Witaj! Logowanie Rejestracja


Ocena wątku:
  • 0 głosów - średnia: 0
  • 1
  • 2
  • 3
  • 4
  • 5
Zmiana diody przyciskiem. Wiele funkcji przycisku .
#1
Witajcie, mam problem z kodem. 
Potrzebuje aby po wciśnięciu swicha zapalała się dioda 1 , po kolejnym wciśnięciu gasiła się 1 a zapalała 2 , kolejne gasi się 2 a zapala 3 itd. Oprócz tego w dowolnym momencie przytrzymanie przycisku powoduje reset arduino . Doszedłem do tego momentu gdzie sekcja pierwsza (z diodami) działa poprawnie. Ale dłuższe przytrzymanie nie działa . Znaczy działa ale dopiero kiedy sekwencja diód jest na końcu ( musi przejść cały program). Możecie zerknąć i coś podpowiedzieć ? Korzystam z biblioteki OneButton
Kod:
#include <OneButton.h>


OneButton button(2, true);                         //attach a button on pin A1 to the library




void setup() {
digitalWrite(12,HIGH);
  pinMode(3, OUTPUT);                              // sets the digital pin as output
  pinMode(4, OUTPUT);                              // sets the digital pin as output
  pinMode(5, OUTPUT);                              // sets the digital pin as output
  pinMode(12, OUTPUT);

     
  button.attachDoubleClick(doubleclick);            // link the function to be called on a doubleclick event.
  button.attachClick(singleclick);                  // link the function to be called on a singleclick event.
  button.attachLongPressStop(longclick);            // link the function to be called on a longpress event.
 
}
 


void loop() {

  button.tick();                                    // check the status of the button


  delay(10);                                        // a short wait between checking the button
} // loop



void doubleclick() {                                // what happens when button is double-clicked
digitalWrite(3,HIGH);                             
delay(1000);                                       
digitalWrite(3,LOW);                             
}

void singleclick(){                                 // what happens when the button is clicked


  digitalWrite(3, LOW); //Czerwona
  digitalWrite(4, LOW); //Pomarańczowa
  digitalWrite(5, HIGH); //Zielona

  delay(2000);
  while (digitalRead(2) == HIGH) {} //Czekaj na wciśnięcie przycisku
 
  digitalWrite(3, LOW); //Czerwona
  digitalWrite(4, HIGH); //Pomarańczowa
  digitalWrite(5, LOW); //Zielona

  delay(2000);
  while (digitalRead(2) == HIGH) {} //Czekaj na wciśnięcie przycisku
 
  digitalWrite(3, HIGH); //Czerwona
  digitalWrite(4, LOW); //Pomarańczowa
  digitalWrite(5, LOW); //Zielona

  delay(2000);
  while (digitalRead(2) == HIGH) {} //Czekaj na wciśnięcie przycisku
 
  digitalWrite(3, HIGH); //Czerwona
  digitalWrite(4, HIGH); //Pomarańczowa
  digitalWrite(5, LOW); //Zielona

  delay(2000);
  while (digitalRead(2) == HIGH) {} //Czekaj na wciśnięcie przycisku
}

void longclick(){                                   
digitalWrite(12,LOW);                           
delay(1000);                                       
digitalWrite(12,HIGH);     
}
 
Odpowiedź
#2
Naucz się używać millis. Masz bibliotekę do obsługi przycisków i potem wstawiasz to: "while (digitalRead(2) == HIGH) {} //Czekaj na wciśnięcie przycisku"?
Tu jest potrzebny Switch case i po kolei przechodzisz kolejne stany przełączane zmienną w funkcji singleclick(), może być inna konstrukcja sterowana taką zmienną jeśli "itd" jest dużo.
Miło być decenianym https://buycoffee.to/kaczakat
 
Odpowiedź
#3
Czyli dokształcić się w funkcji millis i switch case ? Chodzi Ci o tą bibliotekę co załączyłem czy inną? Funkcji "itd" jest dokładnie 5 . Czy potem edytować obecny kod czy pisać od nowa ?

Wysłane z mojego M2007J3SY przy użyciu Tapatalka
 
Odpowiedź
#4
Wystarczy poprawić. Spokojnie może zostać setup, loop i nazwy funkcji, trzeba im tylko zmienić treść.
W funkcji od przyciśnięcia wystarczy jakaś zmienna k++ po każdym naciśnięciu przycisku i przy każdej wartości k inny zestaw stanów led. Akurat tu millis jest zbędne tak samo jak delay. W funkcji długiego naciśnięcia można zrobić reset Watchdog'iem, domyślam się, że podpiąłeś 12 pod RST jakimś kablem, co jest zupełnie zbędne, nadmiarowe, więc i błędne. Docelowo i tak każdy program powinien zawierać WD, więc i tak warto go umieć użyć. Po prostu w tym wypadku wymuszasz jego zadziałanie ustawiając krótki czas i instrukcje while(1), co oczywiście "zawiesi" program i spowoduje programowy reset.
Chodzi o to, że millis jest na końcu kursu Arduino, jakbyś go zrobił to miałbyś pewną paletę narzędzi i instrukcji opanowaną do wykorzystania, na razie nie wiesz o ich istnieniu, lub się zapomniało, za mało przećwiczyło. Każdą lekcję z kursu można zrobić na pierdyliard wariantów, a po dojściu do millis od nowa bez delay.
Jeśli jest to jakiś klon i WD nie działa prawidłowo to trzeba wgrać aktualny bootloader.
Miło być decenianym https://buycoffee.to/kaczakat
 
Odpowiedź
#5
Więc tak. Posiedzialem trochę i posiłkując się przykładami z internetu zbudowałem licznik(nowy kod). Działa prawidłowo. Próbując połączyć licznik z kodem OneButton już się robią schody .
Na tą chwile kod wygląda tak : 
Kod:
#include<OneButton.h>
OneButton button(2, true);     
int dioda_z=3; // pin podpiecia diody
//int button=2; // pin podpiecia buttona
int dioda=4;
int diodaa=5;
int rst=12;
int licznik;

void setup()
{
digitalWrite(rst, HIGH);
  pinMode(dioda_z,OUTPUT);
 
  pinMode(dioda, OUTPUT);
pinMode(diodaa, OUTPUT);
pinMode(rst, OUTPUT);         
button.attachClick(singleclick);   
button.attachLongPressStop(longclick); 
}
void loop()
{
if(digitalRead(2)==LOW) // gdy wcisniemy przycisk
{
  while(digitalRead(2)==LOW); //sprawia, że pomimo trzymania przycisku wcisnietego zmiana nastapi tylko raz
  {
   delay(500);
  }
  licznik++;
}
if (licznik==0) //gdy reszta z dzielenia przez 2 == 0
{
digitalWrite(diodaa, LOW);
  digitalWrite(dioda_z, HIGH);

}
if (licznik==1) //gdy reszta z dzielenia przez 2 == 0
{
digitalWrite(dioda_z, LOW);
  digitalWrite(dioda, HIGH);

}
if (licznik==2) //gdy reszta z dzielenia przez 2 == 0
{
  digitalWrite(diodaa, HIGH);

  digitalWrite(dioda,LOW);

}
if (licznik==3)
licznik=licznik=0;
}
//void singleclick(){}
void longclick(){                                   // what happens when buton is long-pressed
digitalWrite(12,LOW);                            // light the blue LED
delay(1000);                                       // wait one second
digitalWrite(12,HIGH);   
 W tym kodzie licznik działa prawidłowo , nie działa długie kliknięcie . Jeżeli funkcje licznika przeniosę do void singleclick ( kasując oczywiście //) to działa długie kliknięcie (reset) a nie działa licznik . Nie wiem jak to połączyć , gdzie tu jest błąd. Mogę prosić o podpowiedź ?
WD zostawmy narazie w spokoju  . 
Pozdrawiam
 
Odpowiedź
#6
Sprawdziłem przykładowy kod z tej biblioteki i u mnie działa w każdej opcji - zwykle/długie. Ale w nim jest:
void loop()
{
button.tick();

// You can implement other code in here or just wait a while
delay(1);

}
Bez tego button.tick() u mnie nie działa. Może przeczytaj cokolwiek o tej bibliotece, naucz się jej używać https://github.com/mathertel/OneButton .
Dodaj w każdej funkcji drukowanie zmiennych na serial, widzisz co się dzieje z twoimi zmiennymi lub w ogóle że funkcja została wywołana.
Przycisk musi być jakoś podłączony przez rezystor wew/zew ((np. 10k) do jednego stanu logicznego, przeciwnego do wymuszonego tym zwarciem przycisku, ma to być zgodne z tym co deklarujesz bibliotece.
Miło być decenianym https://buycoffee.to/kaczakat
 
Odpowiedź
#7
Przykładowy kod u mnie też działa normalnie (krótkie, podwójne i długie ) , problem zaczyna się kiedy w krótkim próbuje umieścić licznik .
Spróbuję wieczorem przepisać na serial print i zobaczymy . Pozdrawiam

Wysłane z mojego M2007J3SY przy użyciu Tapatalka
 
Odpowiedź
#8
Zamieść cały kod, bo tak na prawdę nie wiemy, co robisz. Ogólnie Onebutton wymaga button.tick() w pętli do poprawnego działania.

Co takiego chcesz osiągnąć przez licznik = licznik = 0?

Bałagan Twoim własnym wrogiem.

Pomysł z serialem jak najbardziej trafiony. Wrzucasz w programie Serial.print z jakimś komunikatem i wiesz, co się dzieje.

Wysłane z mojego POCOPHONE F1 przy użyciu Tapatalka
 
Odpowiedź
  


Skocz do:


Przeglądający: 1 gości