Skocz do zawartości

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


Pomocna odpowiedź

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

 

Link to post
Share on other sites

@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
Link to post
Share on other sites

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
Link to post
Share on other sites

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
Link to post
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

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ół.

Link to post
Share on other sites

@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 🙂

 

Link to post
Share on other sites

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ś).

Link to post
Share on other sites
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.

Link to post
Share on other sites

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ł.

Link to post
Share on other sites

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.

Link to post
Share on other sites

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.

Link to post
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!

Anonim
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.