różne funkcje włączane 1 przyciskiem

Masz problem z Arduino? Tutaj możesz szukać pomocy.
ODPOWIEDZ
Killer1984
Młodszy majsterkowicz
Posty: 4
Rejestracja: 21 wrz 2014, 22:20

różne funkcje włączane 1 przyciskiem

Post autor: Killer1984 » 21 wrz 2014, 22:37

Cześć,
Od kilku dni męczę się nad jedną funkcją - chciałbym żeby jeden klawisz obsługiwał 3 przekaźniki,
ale:
przy 1 wciśnięciu poniżej 500milisekund
włączył/wyłączył(wystarczy zmiana zmiennej) się pierwszy przekaźnik,
przy 2 wciśnięciu poniżej 500milisekund
włączył/wyłączył(wystarczy zmiana zmiennej) się drugi przekaźnik,
przy 3 wciśnięciu poniżej 500milisekund
włączył/wyłączył(wystarczy zmiana zmiennej) się trzeci przekaźnik

przy przytrzymaniu przycisku powyżej 500milisekund włączyły się wszystkie przekaźniki(jeśli żaden z nich nie jest włączony) lub wyłączyły(jeśli dowolny przekaźnik jest włączony)

Zależałoby mi na tym żeby jak najmniej używać opóźnień, żeby każda z powyższych funkcji wykonywała się raz(szczególnie w momencie przytrzymania przycisku - żeby przekaźnik nie włączał się i wyłączał cyklicznie)

Do tej pory udało mi się wyskrobać coś takiego, jednak nie wiem jak zabrać się za resztę moich założeń...
pin 5 jest INPUT_PULLUP ;-)

Kod: Zaznacz cały

  
int ledPinNumber = 0;
boolean status[4] = {
  0, 0, 0, 0
};
boolean buttonState = 1;
  unsigned long currentTime = 0;
  unsigned long previousTime = 0;
  unsigned long waitingTime = 1000;

  buttonState = digitalRead(5);

  if ((digitalRead(5) == 0) )
  {  delay(10);
    previousTime = millis();
    currentTime = millis();
    while ((currentTime - previousTime) <= waitingTime)
    {
      buttonState = digitalRead(5);
      delay(10);
      if ((buttonState != digitalRead(5)) && (digitalRead(5) == 0))
      {
        ledPinNumber++;
        previousTime = millis();
      }
      currentTime = millis();
    }
    if (millis() > waitingTime )
      if (ledPinNumber <= 3)
      {
        status[ledPinNumber] = ! status[ledPinNumber];
      }

    
    
  }
Za każdą podpowiedź będę bardzo wdzięczny!

Co miesiąc do wygrania nagrody o wartości ponad 1600 zł!


Awatar użytkownika
djbuh
Majsterkowicz
Posty: 232
Rejestracja: 9 gru 2012, 19:45
Lokalizacja: Bytom
Kontakt:

Re: różne funkcje włączane 1 przyciskiem

Post autor: djbuh » 21 wrz 2014, 23:48

Wykorzystaj przerwania i timer. Przerwania wywołuj przyciskiem. W momencie wywołania pierwszego przerwania (= pierwszego wciśnięcia) zacznij odliczać 500 ms timerem i zwiększ licznik przyciśnięć o 1. Musisz też zaimplementować w podprogramie obsługi przerwania blokadę, która będzie zapobiegała ponownemu wystartowaniu timera, w przypadku, gdy licznik wciśnięć jest większy od zera (chodzi o to, żeby timer wystartował tylko przy pierwszym wciśnięciu, a przy kolejnych chodzi tylko o inkrementację zmiennej przechowującej ilość wciśnięć). Dalej czekasz, możesz robić sobie coś w pętli głównej, 500 ms to dużo czasu :). Do póki kolejne przerwanie od wciśnięcia przycisku nie przyjdzie, mikrokontroler będzie coś sobie robił. Po 500 ms wywołane zostaje przerwanie timera oznaczające koniec odliczania. W tym momencie najpierw sprawdzasz stan przycisku, jeżeli jest wciśnięty to robisz to: "włączyły się wszystkie przekaźniki(jeśli żaden z nich nie jest włączony) lub wyłączyły(jeśli dowolny przekaźnik jest włączony)". Oczywiście sprawdzasz najpierw ifem czy przekaźniki są włączone, czy nie. Jeżeli przycisk nie jest wciśnięty, sprawdzasz jaką wartość ma zmienna odliczająca wciśnięcia i na tej podstawie reagujesz stanem na wyjściu sterującym przekaźnikiem.

Jakby coś było niejasne, postaram się wyjaśnić. To tylko moja wersja tego programu, wymyślona na szybko, zapewne da się to zrobić inaczej.
stiven
Złota rączka
Posty: 1592
Rejestracja: 13 maja 2014, 08:47
Lokalizacja: Zielona Góra

Re: różne funkcje włączane 1 przyciskiem

Post autor: stiven » 22 wrz 2014, 12:47

Zrobiłem taki program na diodach, przetestowany, działa tak jak miało być.

Kod: Zaznacz cały

unsigned long previousTime;
unsigned long currentTime;
unsigned long waitingTime = 500;

int stan;
boolean led1 = 0;
boolean led2 = 0;
boolean led3 = 0;
int x = 0;

void setup()
{
  pinMode(2, INPUT_PULLUP);
  
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);
  pinMode(8, OUTPUT);
  
  digitalWrite(6, LOW);
  digitalWrite(7, LOW);
  digitalWrite(8, LOW);
}                                 


void loop()
{
  previousTime = millis();

  while(digitalRead(2) == 0)     //w trakcie kiedy wciśnięty przycisk, wykonuje się tylko to co w pętli while
  {
    currentTime = millis();
    if(x == 0)                   //x jako zmienna pomocnicza, aby to co w tym ifie wykonało się tylko raz w trakcie wciśnięcia przycisku
    {                               //a później niżej tylko raz zmiana stanów zmiennych
      stan = stan++;
      if(stan >= 4) stan = 1;
      x = 1;
    }
    if(currentTime - previousTime > waitingTime)
    {
      stan = 4;
    }
  }

  if(x == 1)
  {
    if(stan == 1) led1 = !led1;
    if(stan == 2) led2 = !led2;
    if(stan == 3) led3 = !led3;
    if(stan == 4)
    {
      if(led1 == 1 || led2 == 1 || led3 == 1)
      {
        led1 = 0;
        led2 = 0;
        led3 = 0;
      }else
      {
        led1 = 1;
        led2 = 1;
        led3 = 1;
      }
    }
    x = 0;
  }
  digitalWrite(6, led1);
  digitalWrite(7, led2);
  digitalWrite(8, led3);
  
  delay(100);
}
zgred125
Majsterkowicz
Posty: 88
Rejestracja: 23 gru 2013, 22:39

Re: różne funkcje włączane 1 przyciskiem

Post autor: zgred125 » 22 wrz 2014, 21:15

Miałem kiedyś podobny problem rozwiązałem to tak:
#define led1 5
#define led2 6
#define led3 7
boolean a,b,c;
#define button 18
#include <PinChangeInt.h>
void button_push()
{
  if(digitalRead(button)==LOW)
  {
    delay(20);
    int jak_dlugo=0;
    while(digitalRead(button)==LOW)
    {
      jak_dlugo++;
      delay(5);
    }
    if (jak_dlugo<100)
    {
      int x=a+b+c;
      switch(x)
      {
      case 0:
        a=!a;
        break;
      case 1:
        b=!b;
        break;
      case 2:
        c=!c;
        break;
      case 3:
        a=LOW;
        b=LOW;
        c=LOW;
        break;
      }
    }
    else
    {
      if (a+b+c>0)
      {
        a=LOW;
        b=LOW;
        c=LOW;
      }
      else
      {
        a=HIGH;
        b=HIGH;
        c=HIGH;
      }
    }
    Serial.println(jak_dlugo);
  }

}
void setup()
{
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
  pinMode(button, INPUT_PULLUP);
  PCintPort::attachInterrupt(button, button_push, FALLING);
  Serial.begin(9600);
}

void loop()
{
  digitalWrite(led1, a);
  digitalWrite(led2, b);
  digitalWrite(led3, c);
}
Kod jest napisany pod ATMEGĘ 328P więc jeśli chcesz korzystać z Arduino to musisz zmienić sposób wywoływania przerwania. Czwarte z kolei wciśnięcie przycisku (nawet poniżej 500ms) zgasi wszystkie przekaźniki jeśli nie chcesz tej funkcji skasuj case 3 z switcha. Cały kod jest wycięty do osobnego voida więc dopóki nie wciśniesz przycisku program lata tylko w loop
Killer1984
Młodszy majsterkowicz
Posty: 4
Rejestracja: 21 wrz 2014, 22:20

Re: różne funkcje włączane 1 przyciskiem

Post autor: Killer1984 » 22 wrz 2014, 22:36

Cześć!
Trochę niedokładnie opisałem to czego oczekiwałem od działania programu, jednak dzięki waszym sugestiom udało mi się osiągnąć cel! :-) dziękuję wam za pomoc!!!! :-)
ODPOWIEDZ

Strony partnerskie: