Skocz do zawartości

arduino uno losowe działanie programu do maszyny przez przełącznik obrotowy DFRobot Gravity 12-pozycyjny V1


majster86

Pomocna odpowiedź

Witam wzystkich forumowiczów

Jest to mój piwerszwy post na forum. Zainteresowałem się arduino ponieważ mam maszynę gdzie strerowanie jest zrealizowane na prawie 30 zaworach pneumatycznych festo z lat 80- tych gdzie sparciały wszystkie membrany, przez co koszt wymiany całości idzie w tysiące zł, dlatego postanowiłem spróbować zmienić sterowanie na arduino.

I tu pojawia się problem ponieważ maszyna musi działać w kilku trybach aktualnie jest to zrealizowane o przełącznk obrotowy dlatego też do sterowania trybami zastosowałem przełącznik DFRobot Gravity - przełącznik obrotowy 12-pozycyjny V1 

Wykorzystałem gotowy szablon dostępny na stronie https://wiki.dfrobot.com/Rotary_Switch_Module_V1__SKU_SEN0156_

tylko mam problem ponieważ czasami posczególny tryb pracy opisany w case 1 lub case 4 działa lub nie i nie wiem od czego to zależy 

Poniżej podaję kod obok są komentarze które opisują jak maszyna powinna działać 

Czy ktoś kto ma większe doświadczenie może powiedzieć coś jest nie tak, ewentualnie jak zmusić program żeby przy przełączeniu przełacznika obotowego tylko w w tym trybie tkwił do momentu przełączenia na inny tryb? 

int adc_key_val[12] ={630,680,750,810,845,860,890,905,920,940,950,980};

int NUM_KEYS = 12;

int adc_key_in;

int key=-1;

int oldkey=-1;

void setup(){

  pinMode(2, OUTPUT);        // wyjście na siłownik poziomy

  pinMode(3, OUTPUT);        // wyjście na siłownik pionowy

  pinMode(4, OUTPUT);        // wyjście na dociski górne

  pinMode(5, OUTPUT);        // wyjście na przekażnik silnika

  pinMode(6, INPUT_PULLUP);  // Włącznik nożny

  pinMode(7, INPUT_PULLUP);  // krańcówka górna nr X

  digitalWrite(2, HIGH);

  digitalWrite(3, HIGH);

  digitalWrite(4, HIGH);

  digitalWrite(5, HIGH);

  Serial.begin(9600);                   // 9600 bps

}

void loop()

{

  adc_key_in = analogRead(0);            // read the value from the sensor

  key = get_key(adc_key_in);             // convert into position

  if (key != oldkey)                     // if a position is detected

   {

    delay(50);  // wait for debounce time

    adc_key_in = analogRead(0);          // read the value from the sensor

    key = get_key(adc_key_in);           //convert into position

    if (key != oldkey)

    {

      oldkey = key;

      if (key >=0){

        switch(key)

        {

           case 0:Serial.println("S1 OK");

                  break;

           case 1: digitalWrite(2, LOW); digitalWrite(3, HIGH); //dane wejściowe siłownik poziomy do przodu, siłownik pionowy w dół

                 if (digitalRead(6) == LOW) {                   //Jeśli pedał wciśnięty

                    do {

                       digitalWrite(4, LOW);                    // Docisk materiału

                       delay(500);                              

                       digitalWrite(5, LOW);                    // włączyć silnik

                       delay(500);                              

                      digitalWrite(3, LOW);                     // siłownik pionowy do góry

                     } while (digitalRead(7) == HIGH);          //Jeśli dojdzie do krańcówki

                      digitalWrite(3, HIGH);                    //siłownik pionowy w dół

                      delay(700);

                      digitalWrite(5, HIGH);                    //wyłączyć silnik

                      delay(700);

                       digitalWrite(4, HIGH);                    //odblokowac docisk materiału

                      }

       

           case 2:Serial.println("S3 OK");

                  break;

           case 3:Serial.println("S4 OK");

                  break;

           case 4: digitalWrite(3, LOW); digitalWrite(2, HIGH); // dane wejściowe siłownik pionowy w górę, siłownik poziomy do tyłu,

                  if (digitalRead(6) == LOW) {                   //Jeśli pedał wciśnięty

                    do {

                       digitalWrite(4, LOW);                    // Docisk materiału

                       delay(500);                              

                       digitalWrite(5, LOW);                    // włączyć silnik

                       delay(500);                              

                      digitalWrite(2, LOW);                     // siłownik pionowy do góry

                     } while (digitalRead(7) == HIGH);          //Jeśli dojdzie do krańcówki

                      digitalWrite(2, HIGH);                    //siłownik poziomy w dół

                      delay(700);

                      digitalWrite(5, HIGH);                    //wyłączyć silnik

                      delay(700);

                       digitalWrite(4, HIGH);                    //odblokowac docisk materiału

                     }

           case 5:Serial.println("S6 OK");

                  break;

           case 6:Serial.println("S7 OK");

                  break;

           case 7:Serial.println("S8 OK");

                  break;

           case 8:Serial.println("S9 OK");

                  break;

           case 9:Serial.println("S10 OK");

                   break;

           case 10:Serial.println("S11 OK");

                  break;

           case 11:Serial.println("S12 OK");

                  break;

        }

      }

    }

  }

 delay(100);

}

// Convert ADC value to key number

int get_key(unsigned int input)

{

    int k;

    for (k = 0; k < NUM_KEYS; k++)

    {

      if (input < adc_key_val[k])

     {

            return k;

        }

   }

       if (k >= NUM_KEYS)k = -1;

       return k;

}

 

Link do komentarza
Share on other sites

(edytowany)

Z losowym działaniem sobie poradziłem, trzeba było wpisać inne dane na początku w int adc_key_val[12] te podane na tronie producenta nie były prawdziwe, przez co czasami mimo tego ze był styk 1 w tym przełaczniku to sterownik odczytywał to jako styk 2 i dlatego nie działało.

Ale teraz pojawił się inny problem.

jeżeli ustawię pokrętło w pozycji 2, czyli w programie będzie case 1 to pierwsze instrukcje po case są wykonywane to znaczy digitalWrite(2, LOW); digitalWrite(3, HIGH); Nietety nie działa instrukcja warunkowa if chyba że w momencie przełączenia na pokretło na pozycję 2 od razu trzymam wciśnięty przycisk (digitalRead(6) == LOW) ale to działa tylko raz ponieważ jak się go puści i naciśnie przycisk (digitalRead(7) == HIGH) to już nie ma możliwości aby była wykonywana część kodu po pętli if. Z jakiego powodu tak się dzieje? czy w instrukcji CASE nie można zawrzeć petli IF ? a może gdzieś trzeba zastosować jakieś opóźnienia. Niestety na razie nie pomaga nawet trzymanie przycisku digital read (6 )przez cały czas i tak program z jakiegoś powodu nie wchodzi do pentli if.

Co może być powodem? 

Edytowano przez majster86
Link do komentarza
Share on other sites

(edytowany)

może źle to napisałem ponieważ w CASE 0 jest 1 czyli to jest 1 pozycja na przełączniku, ta na samym dole, a jak dam na 2 pozycję w przełączniku to wchodzi na CASE 1 to się zgadza a dla pewności dodałem jeszce kod za case 1  Serial.println("S2 OK") po to aby mi na monitorze szeregowaym wyświetlał aktualną pozycję, czyli wiem że jest napewno w pozycji numer 2. Zwróć uwagę że powyżej jest część kodu ze strony producenta gdzie jest "Case 0:Serial.println("S1 OK"); " Czyli dla case 0 jet Pierwza pozycja S1 OK. Pozatym są wykonywane pierwsze instrukcje za CASE 1 czyli digitalWrite(2, LOW); digitalWrite(3, HIGH) które ustawiają przekaźniki w konkretnym położeniu. Mimo tego nie wykonuje się dalsza część kodu już ta za if chyba że tak jak napisałem przed przełączeniem na pozycję jest wcinięty przycisk, ale w takim wypadku to i tak działa tylko raz.

Edytowano przez majster86
Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

wydaje mi się że z jakiegoś powodu jeżeli nie zmieni się pozycji na przełączniku to program się nie wykonywuje ponownie od nowa tylko nie wiem dlaczego. Czy końcówka kodu 

// Convert ADC value to key number

int get_key(unsigned int input)

{

    int k;

    for (k = 0; k < NUM_KEYS; k++)

    {

      if (input < adc_key_val[k])

     {

            return k;

        }

   }

       if (k >= NUM_KEYS)k = -1;

       return k;

}

nie powinna być w pętli void loop? przyznam że to skopiowałem z przykładu od producenta przełącznika i dlaczego ona jest umieszczona za pętlą void lop to nie wiem.

Link do komentarza
Share on other sites

@majster86 program leci w kółko pętlę loop tysiące razy na sekundę. Jeśli key ==1 to wykonuje się case1. W kółko.

Jeśli w czasie kiedy program realizuje linijkę z if czytającym pin i ty go masz wciśnięty to if się wykona, jeśli nie jest wciśnięty to nie, logiczne.

 Jeśli chcesz by program reagował na pojedyncze naciśnięcie to napisz funkcję zapisującą do zmiennej, że wciśnięto przycisk, oraz drugą czy wykonano to co miało się zrobić po wciśnięciu przycisku. 

W warunku ifa sprawdzasz obie zmienne, czy wciśnięto przycisk i czy juz wykonało sie to co miało się wykonać.

Oczywiście jeśli to ma się wykonać za każdym razem jak naciskasz przycisk to tej drugiej zmiennej nie rób.

 

Link do komentarza
Share on other sites

(edytowany)

@SOYER no właśnie z jakiegoś powodu to nie działa tak jak piszesz, mogę cały czas trzymać przycisk nawet przez kilka minut i nic to nie zmienia. sprawdzałem to na kilka sposobów i mam wrażenie że program NIE wykonywuje się od nowa tylko zatrzymuje się w konkretnym CASIe na który aktualnie jest ustawiony przełącznik ale tutaj już nie wykonuje nieskończenie instrukcji tylko sięzatrzymuje . już sprawdzałem z BREAK albo bez BREAK  jest taki sam problem nawet wywaliłem instrukcję SWITCH i zastąpiłem IFem i nadal jest ten problem że wykonuje się tylko raz i jeżeli w tym czasie jest wciśnięty przycisk to się wykona a jak nie to już do tego nie wraca. Przy czym napewno nie jest to problem sprzętowy ponieważ ten wycinek  programu który ma się wykonywać w CASE jak wklejem w osobny program działa dobrze. mam wrażenie że coś z tą końcówka jest nie tak i to powoduje zatrzyamnie programu.

Edytowano przez majster86
Link do komentarza
Share on other sites

Ok, nie wiem co tam było nie tak, w każdym razie znalazłem stronę https://starter-kit.nettigo.pl/2017/06/jeden-pin-przyciskow/ i na tej podstawie popełniłem taki kod, publikuję bo może komuś się przyda, na razie działa, teraz trzeba dokupić resztę osprzętu i sprawdzić jak będzie działać na maszynie. Co prawda przełącznik z tematu jest 12 pozycyjny ale mi były potrzebne tylko 4, dlatego tylko te są opisane w kodzie 

#define BTN_PIN A0

#define BTN1    687 // pozycja 1 program wiercenia od dołu 
#define BTN2    810 // pozycja 2 program wiercenie od dołu i boku razem 
#define BTN3    905 // pozycja 3 program wiercenia od boku
#define BTN4    957 // pozycja 4 program wiercenia od boku z pogłębieniem (na dwa razy)

void setup() {
  pinMode(BTN_PIN, INPUT);
  Serial.begin(9600);
 pinMode(2, OUTPUT);        // wyjście na siłownik poziomy
  pinMode(3, OUTPUT);        // wyjście na siłownik pionowy
  pinMode(4, OUTPUT);        // wyjście na dociski górne
  pinMode(5, OUTPUT);        // wyjście na przekażnik silnika
  pinMode(6, INPUT_PULLUP);  // Włącznik nożny
  pinMode(7, INPUT_PULLUP);  // krańcówka górna nr X
  digitalWrite(2, HIGH);
  digitalWrite(3, HIGH);
  digitalWrite(4, HIGH);
  digitalWrite(5, HIGH);
}
bool isAnalogBtnPressed(int analogVal, int btnValue) {
  return abs(btnValue - analogVal) <= 20;
}
void loop() {
  int btnData = analogRead(BTN_PIN);
  if(isAnalogBtnPressed(btnData, BTN1) && (digitalRead(6) == LOW)) {                        //Jeśli 1 program i pedał wciśnięty)) 
    Serial.println("Wcisnieto przycisk 1 wiercenie od czoła"); digitalWrite(2, HIGH); digitalWrite(3, LOW);    //dane wejściowe siłownik poziomy do przodu, siłownik pionowy w dół
      do {
            digitalWrite(4, LOW);                    // Docisk materiału
            delay(500);                              
            digitalWrite(5, LOW);                    // włączyć silnik
            delay(500);                              
            digitalWrite(3, LOW);                     // siłownik pionowy do góry
            } while (digitalRead(7) == HIGH);          //Jeśli dojdzie do krańcówki
            digitalWrite(3, HIGH);                    //siłownik pionowy w dół
            delay(700);
            digitalWrite(5, HIGH);                    //wyłączyć silnik
            delay(700);
            digitalWrite(4, HIGH);                    //odblokowac docisk materiału
                

  } else if(isAnalogBtnPressed(btnData, BTN2)) {
    Serial.println("Wcisnieto przycisk 2");
  }  else if(isAnalogBtnPressed(btnData, BTN3) && (digitalRead(6) == LOW)) { //Jeśli 3 program i pedał wciśnięty
    Serial.println("Wcisnieto przycisk 3 wiercenie od dolu"); digitalWrite(3, LOW); digitalWrite(2, HIGH);
         do {
            digitalWrite(4, LOW);                    // Docisk materiału
            delay(500);                              
            digitalWrite(5, LOW);                    // włączyć silnik
            delay(500);                              
            digitalWrite(2, LOW);                     // siłownik poziomy do przodu
             } while (digitalRead(7) == HIGH);          // Jeśli dojdzie do krańcówki 
               digitalWrite(2, HIGH);                    // siłownik poziomy do tyłu
               delay(700);
               digitalWrite(5, HIGH);                    // wyłączyć silnik
               delay(700);
               digitalWrite(4, HIGH);                    //odblokowac docisk materiału

  }  else if(isAnalogBtnPressed(btnData, BTN4)) {
    Serial.println("Wcisnieto przycisk 4");
  }

  delay(100);

 

Link do komentarza
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Gość
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.