• 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
Funkcja IF i operatory logiczne
#1
Witam wszystkich

Pisząc i ucząc się programować natrafiłem na problem z prawidłowym działaniem programu mimo że kompiluje się poprawnie. Mianowicie w ostatniej funkcji IF (zgaś diody po naciśnięciu przycisków)  nie działa tak jak należy i nie bardzo wiem czemu nie działa. Proszę o pomoc w ustaleniu co zrobiłem źle

Funkcja powinna działać w ten sposób:

IF ((naciśniętyKlawisz1 lub (OR) naciśniętyKlawisz2) i (AND) (świeciLed1 lub (OR) świeciLed2))
zgaś Led 1 oraz Led2

Kod:
const int buttonPin1 = 2;
const int buttonPin2 = 3;
const int ledPin1 = 12;
const int ledPin2 = 13;

unsigned long aktualnyCzas = 0;
unsigned long czasDrgania = 0;
unsigned long czasLED1 = 0;
unsigned long czasLED2 = 0;

int delayTime = 15;


void setup() {

  pinMode(12, OUTPUT);
  digitalWrite(12, LOW);
  pinMode(13, OUTPUT);
  digitalWrite(13, LOW);
  pinMode (buttonPin1, INPUT_PULLUP);
  pinMode (buttonPin2, INPUT_PULLUP);
}

void loop() {

  aktualnyCzas = millis();
 
// zapal LED1
  if (isButtonPressed(buttonPin1) && (digitalRead(ledPin2) == LOW)) {      // jak przycisk-1 zostal wcisniety i LED2 nie swieci to zapal LED1
    digitalWrite(12, HIGH);
    czasLED1 = millis();
  }
   else if (aktualnyCzas - czasLED1 >= 8000UL){
      czasLED1 = aktualnyCzas;  
      digitalWrite(12, LOW);
    }
 
// zapal LED2
  if (isButtonPressed(buttonPin2) && (digitalRead(ledPin1) == LOW)){       // jak przycisk-1 zostal wcisniety i LED2 nie swieci to zapal LED2
    digitalWrite(13, HIGH);
    czasLED2 = millis();
  }
     else if (aktualnyCzas - czasLED2 >= 8000UL){
      czasLED2 = aktualnyCzas;  
      digitalWrite(13, LOW);
    }

// zgas LEDy po nacisnieciu przyciskow
  if (((isButtonPressed(buttonPin1)) || (isButtonPressed(buttonPin2))) && ((digitalRead(ledPin1) == HIGH) || (digitalRead(ledPin2) == HIGH))) {
    digitalWrite(12, LOW);
    digitalWrite(13, LOW);
  }
}

bool isButtonPressed (int button) {               // likwidacja drgania stykow dla wszystkich przycisków
  if (digitalRead(button) == LOW) {
  czasDrgania = millis();
    if (aktualnyCzas - czasDrgania >=15UL){
      czasDrgania = aktualnyCzas;
    }
   
  if (digitalRead(button) == LOW) {
  return true;
    }
   }
return false;

}
 
Odpowiedź
#2
Warunek IF po "rozbiciu" na dwa mniejsze warunki działa lecz napotkałem inny problem. Mianowicie uC działa tak szybko że po wciśnięciu przycisku "zgaś LED" i zanim zdążę puścić przycisk to program robi pętlę i zaczyna od początku - zapalając LED gdyż odczytuje że mam wciśnięty przycisk. A ja jeszcze nie zdążyłem go puścić... Próbowałem umieścić w różnych miejscach warunki z timerami aby spowolnić wykonywanie warunków jeden po drugim ale nie dało to oczekiwanych rezultatów. 
Proszę o podpowiedz co zastosować aby naciśnięcie przycisku odczytywane było tylko raz do danego warunku?
 
Odpowiedź
#3
Człowiek jest w stanie w ciągu 1s wcisnąć przycisk 5-20 X, uC sprawdzi stan przycisku w tym czasie >1mln X, a sam przycisk spowoduje pierdyliard zmian tego stanu przez właściwość swojej konstrukcji. Poszukaj w Google jak zrobić programowa eliminację drgań styków albo użyj gotowej biblioteki, np. BUTTON, BOUNCE2.
 
Odpowiedź
#4
Dziękuję za podpowiedz.
Udało mi się wykorzystać bibliotekę - i dla jednego przycisku i jednej diody działa tak jak chcę. Choć natrafiłem na kolejny problem, mianowicie z obsługą kilku przycisków. Kombinowałem stworzyć formułę która będzie rozróżniała który przycisk został wciśnięty ale nie bardzo mi to wychodzi.
Poniżej zamieszczam przykład z biblioteki i proszę o podpowiedz jak na tym przykładzie zrobić dwa lub więcej przycisków


Kod:
#include <Bounce2.h>

#define BUTTON_PIN 2
#define LED_PIN 13

int ledState = LOW;


Bounce b = Bounce(); // Instantiate a Bounce object

void setup() {
 
  b.attach(BUTTON_PIN,INPUT_PULLUP); // Attach the debouncer to a pin with INPUT_PULLUP mode
  b.interval(25); // Use a debounce interval of 25 milliseconds
 
 
  pinMode(LED_PIN,OUTPUT); // Setup the LED
  digitalWrite(LED_PIN,ledState); // Turn off the LED

}

void loop() {

   b.update(); // Update the Bounce instance
   
   if ( b.fell() ) {  // Call code if button transitions from HIGH to LOW
     ledState = !ledState; // Toggle LED state
     digitalWrite(LED_PIN,ledState); // Apply new LED state
   }
}
 
Odpowiedź
#5
Z pomocą wujka Google rozwiązałem problem kilku przycisków z biblioteką Bounce2
Dla przyszłości podaje przykładowy działający program:


Kod:
#include <Bounce2.h>
const int button1a = 2;
const int button1b = 3;
const int ledPin1a = 12;
const int ledPin1b = 13;

bool LED1a = LOW;
bool LED1b = LOW;

unsigned long aktualnyCzas = 0;
unsigned long czasDrgania = 0;
unsigned long czasLED1a = 0;
unsigned long czasLED1b = 0;

Bounce p1a = Bounce();
Bounce p1b = Bounce();

void setup() {
  Serial.begin(9600);
  pinMode(12, OUTPUT);
  digitalWrite(12, LOW);
  pinMode(13, OUTPUT);
  digitalWrite(13, LOW);
  p1a.attach(button1a, INPUT_PULLUP);
  p1a.interval(20);
  p1b.attach(button1b, INPUT_PULLUP);
  p1b.interval(20);
}
void loop() {
  p1a.update();
  p1b.update();
  bool stanP1a = p1a.read();
  bool stanP1b = p1b.read();
  aktualnyCzas = millis();

// zapal LED1a
    if (p1a.fell() && LED1b == LOW) {
      LED1a =!LED1a;
      digitalWrite(12, LED1a);
      czasLED1a = aktualnyCzas;
  }
    if (LED1a){;
         if (aktualnyCzas - czasLED1a >= 3000UL){
          czasLED1a = aktualnyCzas;   
          digitalWrite(12, LOW);
          LED1a = LOW;
      }
    }
// zapal LED1b
    if (p1b.fell() && LED1a == LOW) {
      LED1b =!LED1b;
      digitalWrite(13, LED1b);
      czasLED1b = aktualnyCzas;
  }
    if (LED1b){
      Serial.println("SWIECI LED1b");
         if (aktualnyCzas - czasLED1b >= 3000UL){
          czasLED1b = aktualnyCzas;   
          digitalWrite(13, LOW);
          LED1b = LOW;
      }
    }
}
 
Odpowiedź
  


Skocz do:


Przeglądający: 1 gości