Wątek przeniesiony 2018-11-08 11:58 z Inne języki programowania przez Marooned.

Arduino złe działanie przekaźników

0

Cześć
Czy jest ktioś na pokładzie kto ogarnia może hobbystycznie arduino?

Mam pewien problem w kodzie i nie wiem jak sobie z nim opradzić :D

Otóż mam zbudowany układ Arduino + LCD, + Czujnik odległości + Listwa 4 przekaźników. Chciałbym zrobić z dwóch przekaźników pompy wody, i to się udaje pomiar robiony przez czujnik odległosci podawany jest w cm, wyświetlany na LCD, natomiast problem to praca dwóch przekaźników, nie wiem jak je zmusić do działania pod taki algorytm.

  1. Start podmiany cieczy (np przycisk) -> w kodzie jest to po prostu zmienna z określoną wartościa.
  2. Uruchamianie 1 pompy (przekaźnik 1).
  3. Pomiar do 30 cm.
  4. Gdy czujnik pokaże 30 cm.
  5. Wyłaczenie 1 pompy.
  6. Uruchomienie 2 pompy (przekaźnik 2).
  7. Pomiar do 5 cm.
  8. Gdy czujnik pokaże 5 cm.
  9. Wyłączenie 2 pompy.
  10. Koniec podmiany.

Oto mój kod uwaga! bo mogą kogoś oczy rozboleć :D

#include <LiquidCrystal_I2C.h> // Dołączenie biblioteki do obsługi LCD
 LiquidCrystal_I2C lcd(0x3F, 16, 2); // Konfiguracja portu LCD 0x3F, ilość znaków w jednej linii 16, ilość linii 2 

#define trigPin 6
#define echoPin 7
#define p1 2 
#define p2 3 
#define p3 4 
#define p4 5 

void setup()
{
  pinMode(trigPin, OUTPUT); //Pin, do którego podłączymy trig jako wyjście
  pinMode(echoPin, INPUT); //a echo, jako wejście

  
  pinMode(p1, OUTPUT); //ustawienie wyjscia dla przekaznikow
  pinMode(p2, OUTPUT);
  pinMode(p3, OUTPUT);
  pinMode(p4, OUTPUT);
  
  digitalWrite(p1, HIGH); //ustawienie stanu poczatkowego dla przekaznikow
  digitalWrite(p2, HIGH);
  digitalWrite(p3, HIGH);
  digitalWrite(p4, HIGH);

  lcd.init();   // Funkcja inicjalizujaca LCD
  lcd.backlight(); // Włączenie lub wyłączenie podświetlania LCD 


}

void loop()
{
 zakresWyp(30); //Zakres do 15 cm

  delay(100);
} 

//funkcja mierzaca odleglosc i zwracajaca wynik w cm
int zmierzOdleglosc() { 
  long czas, dystans;
 
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
 
  czas = pulseIn(echoPin, HIGH);
  dystans = czas / 58;
 
  return dystans;
}
 
// funkcja pracy przekaznikow

void zakresWyp(int a) { 
  int jakDaleko = zmierzOdleglosc();
  if (jakDaleko < a) {

  lcd.setCursor(0, 0); 
  lcd.print(zmierzOdleglosc()); 
  lcd.println(" cm");
  lcd.setCursor(0, 1);
  lcd.print("Pompa P1 aktywna"); 

      digitalWrite(p1, LOW); //wlaczenie pompy 1
      
  } else {
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print(zmierzOdleglosc());
      lcd.println(" cm");
      lcd.setCursor(0, 1);      
      lcd.print("Pompa P1 nie aktywna"); 

      digitalWrite(p1, HIGH); //wylaczenie pompy 1
  }
}

Nie wiem jak do tego wstawic pompe 2 aby nie dzialay dwie na raz, jak odam do else np popmpe 2 to czujnik zgodnie z delay w sekcji loop zmienia stan i zalcza sie p[ompa 1 potem 2 znow 1 potem 2 i tak w kółko :(

0

Wszystko działa dobrze, masz przykładowo 30 litrów wody i pompa pierwsza się wyłączy, teraz spadnie do 29l i znowu się włączy.

Czyli to działa tak jak wstawisz włączenie pompy 2 do else, a do ifa wyłączenie:

30 - włącz pierwszą pompę
31 - włącz drugą pompę
30 - pierwszą,
31 - drugą
I to tak powinno oscylować według tego kodu.

Możesz napisać coś więcej jak to ma się zachowywać?

0

Cześć no i tak włąsnie działa jak napisałeś :D chciałbym aby chodziło jak ten algorytm który napisałem w skrócie to: wypompowanie 30 cm wody jedna pompa wody, po wypompowaniu wpompowanie 30 cm wody druga pompą , po takiej akcji koniec pracy aż do następnego wymuszenia.

za słaby jestem aby to pojac logicznie chyba, bo co nie zrobię czyli np druga funkcja z innym zakresem, nawet switch case robiłem to i tak jest efekt podobny do Twojego opisu działają dwie gdy delay w loop zdziala, niby moge delay zwiększyć ale to byłby błąd bo wada sie może przelać zanim sie dokona pomiar.

0

Możesz coś prostego zastosować nieblokującego wątku.

loop {
 if (czynnosc)
   if( max < odleglosc())
      pompować wodę
   else 
      czynnosc = false;
 else
   if (min > odleglosc())
      wypompowywać
  else
      czynnosc = true;
 delay(100);
}
0

Mam pytanie czy w tym kodzie jest za dużo o jeden else bo kompilator mi wywala błąd przy środkowym else

0

Pewnie gdzieś się nie domyka dodaj klamry do ifów i elsów, bo ja zrobiłem wcięcia w tym pseudokodzie.
I ogólnie to napisz ten kod, a nie kopiuj bo to tylko taki poglądowy.

0
if (czynnosc){
    
    if (10 < odleglosc()) {
        //pompuj wode pompa 2
        digitalWrite(p2, LOW); //wlaczenie pompy 2
        digitalWrite(p1, HIGH); //wylaczenie pompy 1
      } else {
        czynnosc = false;
        
        } 
      
    if (20 > odleglosc()) {
        //wypompuj wode
        digitalWrite(p2, HIGH);//wylaczenie pompy 2
        digitalWrite(p1, LOW);//wlaczenie pompy 1
       } else {
         czynnosc = true;
         }
         delay(500);
      }

Obserwacja

Po włączeniu działa pompa 2 pompujaca wode po zjechaniu przeszkoda do 10 cm załącza sie pompa 1 i tak już zostaje

0
if (czynnosc){ 

  if (30 > odleglosc()) { // ma np pompować wodę, aż wysokość przekroczy 30, wykonuje się dopóki warunek spełniony
    //pompuj wode pompa 2
    digitalWrite(p2, LOW); //wlaczenie pompy 2
    digitalWrite(p1, HIGH); //wylaczenie pompy 1
  } else { // jak przekroczyło zmień na wypompowywanie
    czynnosc = false;
  }

} else {

  if (10 < odleglosc()) { // wypompowuj aż spadnie poniżej 10
    //wypompuj wode
    digitalWrite(p2, HIGH);//wylaczenie pompy 2
    digitalWrite(p1, LOW);//wlaczenie pompy 1
  } else { // jak spadło to zmień na pompowanie
    czynnosc = true;
  }
         
}

Powinno działać, ale błędy mogą wystąpić w kilku miejscach, np. zawsze zapominam czy true jest 0 czy 1 xd, bo róznie to w różnych miejscach jest.

Tam był błąd w warunku odwrotnie, zamieniłem teraz jest chyba git, a jak nie to pokombinuj coś wymyślisz.

0

Dziękuje działa :D pozmieniałem tylko w warunkach < lub >, ale kombinuję już tylko z jednym ifem mianowicie gdy już przejdzie to napełnianie i stan wyniesie np 5cm to wyłacza obie pompy coś takiego

if(odleglosc() <= 5){
digitalWrite(p1, HIGH);
digitalWrite(p2, HIGH);
}

wkleiłem juz chyba wszędzie gdzie tylko mozna było ale stanu takiego nie mogę uzyskać. Za to z przekaźników i diod niezłą perkusje zrobiłem :D jakieś 500 uderzeń na sekunde :D

0

Ok udało się mi już znaleźć gdzie ma byc warunek i o dziwo działa :Ddziękuję ogórku za pomoc xd


if (czynnosc){ 
  
  if (min > odleglosc()) { // wypompowanie
    
    digitalWrite(p1, LOW);

  } else { // jak przekroczyło zmień na wypompowywanie

    czynnosc = false;
    
  }
 
} else {
 
  if (max < odleglosc()) { //uzupelnianie wody 
    
    digitalWrite(p1, HIGH);
    digitalWrite(p2, LOW);
    
  } else { // jak spadło to zmień na pompowanie
    //czynnosc = true;
  
       if(odleglosc() <7){
        digitalWrite(p1, HIGH);
        digitalWrite(p2, HIGH);
    }
  }
   
}

Stan na teraz po inicjalizacji zaczyna dzialac pompa 1 gdy ubędzie cieczy do 20cm, wyłącza sie pompa pierwsza i załacza 2 która ma za zadanie wpompować ciecz aż do np 5 cm p[omiaru wtedy wyłączają się obie pompy :D

1 użytkowników online, w tym zalogowanych: 0, gości: 1