Skocz do zawartości

Jak wprowadzić liczbę dwucyfrową do konstrukcji switch case Arduino Uno


Pomocna odpowiedź

Napisano

Witam

Udało mi się napisać program do sterowania obrotnicą do makiety. Wszystko działa przy wybieraniu z klawiatury membranowej liczby jednocyfrowej. Problem mam z wpisaniem liczby dwucyfrowej - po wpisaniu pierwszej cyfry program rozpoczyna działanie - przykład wprowadzenie liczby 35 miało spowodować obrót pomostu z położenia 3 do położenia 5 - case 35.



eksperyment 1b
 #include <Keypad.h>
 #include <Stepper.h>

const byte ROWS = 4;
const byte COLS = 3;
char keys[ROWS][COLS] =
{{'1','2','3'},
{'4','5','6'},
{'7','8','9'},
{'*','0','#'}};
byte rowPins[ROWS] = {2,3,4,5};
byte colPins[COLS] = {6,7,8};
Keypad keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

const int in1Pin = 10;
const int in2Pin = 12;
const int in3Pin = 9;
const int in4Pin = 11;
Stepper motor(180, in1Pin, in2Pin, in3Pin, in4Pin);

int pozycja = 0;

void setup()
{
  pinMode(in1Pin, OUTPUT);
  pinMode(in2Pin, OUTPUT);
  pinMode(in3Pin, OUTPUT);
  pinMode(in4Pin, OUTPUT);  
  motor.setSpeed(35);
  Serial.begin(9600);
}


void loop()
{

char key = keypad.getKey();
if (key !=NO_KEY)
 {

  switch(key)
  {
    case '1':
       Serial.print(" ");
       motor.step(683);
     
       break;
    case '2':
       Serial.print(" ");
       motor.step(171);
      
       break;
   case '3':
       Serial.print(" ");
       motor.step(171);
     
       break;
    case '4':
       Serial.print(" ");
       motor.step(+171);
     
       break;
  
    case '5':
       Serial.print(" ");
       motor.step(854);
       
       break;

    case '6':
       Serial.print(" ");
       motor.step(-683);
      
       break;
    case '7':
       Serial.print(" ");
       motor.step(-171);
       
       break;
   case '8':
       Serial.print(" ");
       motor.step(-171);
      
       break;
    case '9':
       //Serial.print(" ");
       motor.step(-171);
       
       break;
  
    case '0':
      // Serial.print(" ");
       motor.step(-854);
       
       break;  

    case '35':
      // Serial.print(" ");
       motor.step(-754);
       
       break; 

    case '41':
      // Serial.print(" ");
       motor.step(-620);
       
       break;
  }
  
 }
  
}

 Ponieważ nigdy nie miałem do czynienia z programowaniem proszę o uzupełnienie mojego programu oczywiście o ile jest to możliwe. 

Dziękuję za pomoc.

Wiesiek

 

@majsterek1 musisz w takim razie dorobić sobie jakąś funkcję, która "domyśla się", że jeśli np. w ciągu mniej niż 2 sekund wciśnięto dwa przyciski to program ma te dane połączyć w liczbę dwucyfrową. Nie da się tego zrobić tak jak teraz tzn., że zmienna key steruje od razu switchem. Musisz zapamiętać wartość, odczekać trochę, sprawdzić czy została podana inna wartości, i jeśli tak to zrobić z tego liczbę dwucyfrową. To nie jest proste, ale na pewno dasz radę 🙂 Przyda się tu funkcja millis - daj znać jak będziesz miał coś napisane to pomożemy z doszlifowaniem szkicu 😉

  • Pomogłeś! 1

Oprócz rozwiązania "czasowego" można jeszcze spróbować opcji z dodatkowymi przyciskami. Jeśli na klawiaturze masz jeszcze coś oprócz zwykłych cyfr (gwiazdka? hash? enter?), to załóż, że np:

  • wpisywanie zawsze zaczyna się od gwiazdki i zawsze ma dwie (albo zawsze trzy) cyfry, np: *05 albo *37 (lub *003, *128)
  • wpisywanie zawsze kończy się znakiem specjalnym, np: 8* lub 23*
  • jeśli wprowadzane liczby są jakiegoś niewielkiego zakresu (np. 0-29) to przeznacz dwa przyciski na pierwszą cyfrę (przykładowo niech A i B oznacza 10 i 20 ) a przyciski cyfrowe na drugą, wtedy masz: 5 - po prostu pięć, A8 - osiemnaście, B1 - dwadzieścia jeden. Tak mają niektóre piloty z numeracją kanałów TV.
  • Lubię! 1

Ja proponuję zacząć od czegoś prostszego: od napisania funkcji zwracającej liczbę od 0 do 9 w przypadku naciśnięcia klawisza lub np. -1 jeśli żadnego nie naciśnięto. Na razie dla obsługi pojedynczego wciśnięcia klawisza.

Program główny (loop) mógłby wyglądać np. tak:

void loop()
{
    int key = klawisz();
    if (key >= 0) { // w sumie niepotrzebne, zgadnij dlaczego
        switch(key) {
          case 0:
            //cośtam
            break;
          case 1:
            // cośtam
            break;
          // i tak dalej
        }
    }
}

A funkcja mogłaby zaczyna się od:

int klawisz()
{
	char key = keypad.getKey();
	if (key == NO_KEY) return -1; // nie wciśnięto żadnego klawisza

Poza tym dziwi mnie jedna rzecz: chcesz za pomocą dwucyfrowego kodu przesuwać obrotnicę od położenia A do położenia B. Ale przecież program powinien znać bieżące położenie obrotnicy, wystarczyłoby podać jedynie docelowe...

 

  • Lubię! 1

Z kodu chyba właśnie wynika, że Kolega obraca tym urządzeniem od aktualnego położenia w przód lub w tył o zadaną (z klawiatury) wielkość. Mógłby pewnie zwyczajnie przeliczać wprowadzoną liczbę na liczbę kroków w jednej linii programu zamiast tego wielkiego case'a, ale to już szczegół.

@marek1707 - ja przynajmniej z pierwszego postu wywnioskowałem, że chodzi o przesunięcie od A do B... ale mogę się mylić. Poza tym przesunięcie do następnego położenia może wymagać różnej ilości kroków w zależności od tego, gdzie obrotnica akurat stoi...

Co do switcha to się zgadzam że jest niepotrzebny, ale może po kolei 🙂

 

No to kluczowa jest odpowiedź na pytanie: czy autor chce by to działało jak napisał słowami czy tak jak napisał program. Bo w pierwszym przypadku podawanie położenia początkowego (z 3 do 5) jest bez sensu - przecież stoimy w poł. 3 a z kolei podawanie jedynie położenia docelowego (jedź do 5) wymaga obliczania liczby kroków jakie nas od niego dzielą i de facto znania pozycji obecnej. W tym przypadku obrotnica powinna mieć albo enkoder absolutny albo jakiś czujnik położenia zero i do niego bazować się po włączeniu zasilania. Pomijam fakt ew. gubienia kroków przez silnik. To co obecnie robi program, czyli podawanie liczby kroków ruchu w przód lub w tył jest najprostsze, ale nie daje możliwości wykonania komendy np. skieruj się na północ (gdziekolwiek teraz jesteś).

24 minuty temu, marek1707 napisał:

obrotnica powinna mieć albo enkoder absolutny

Wyprzedzając nieco autora... wydaje mi się to najlepszym rozwiązaniem. Jeśli autor sam skonstruował obrotnicę - to nawet samodzielne zrobienie prostego enkodera byłoby dla niego fraszką. Ale poczekajmy, aż się autor wypowie.

Myślę, że wiem co autor chce zrobić. Nie ma problemu w wykonaniu fizycznym. Chodzi mu o pobranie przez program dwóch następujących po sobie cyfr, co razem ma dać liczbę dwucyfrową ze składowych np. x i y. Problem tkwi jak przekazać programowi aby zapisał pierwszą wprowadzoną cyfrę (dla przykładu "x") i jeśli w przeciągu "s" sekund (s = czas wybrany) zostanie podana inna cyfra, "y" która również zostanie zapisana. Potem w następnej formułce zostały by pobrane obie zmienne (x i y) i jeśli czas pomiędzy wprowadzeniem obu był by mniejszy lub równy "s" to za pomocą działania (x*10 + y) wyszła liczba "z" dwucyfrowa. Jeśli zaś czas był by większy od "s" wtedy została by wprowadzona tylko zmienna "x" (można w takiej sytuacji dać równanie "z = x").  Potem wynik zinterpretuje sobie jak tylko będzie chciał.

Witam

Po przeczytaniu postów najprecyzyjniej mój problem opisał Miolhar. Dokładnie o taką realizację mi chodzi. Ale jak poprzednio pisałem nie mam ani dostatecznej wiedzy ani praktyki w pisaniu programów. To co napisałem to efekt żmudnej pracy w poszukiwaniu wiedzy. Dlatego też prosze o uzupełnienie mojego programu bo wydaje mi się  ze dla osób wypowiadających się tak fachowo nie będzie to wielki problem.

Wiedziałem o co Ci chodzi bo mam mam podobny problem. W moim przypadku jest jak dla zmiennych X i Y przypisać kolejno wybrane wartości na pilocie podczerwieni. Jeśli uda mi się wymyślić sposób na rozwiązanie tego problemu dam znać. Tylko w moim przypadku chyba zrobię aby jeden z przycisków definiował wybór liczby dwucyfrowej więc pomijam sekwencję zapisu czasu pomiędzy przyciśnięciem itp.

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...