Menüsteuerung mit Joystick Modul?

Hallo zusammen,

ich entschuldige mich falls es schon einen ähnlichen Thread gibt, allerdings habe ich zwar bereits ein paar Sketches zu JoyStick Modulen gefunden, allerdings ging es da vorrangig darum Spiele- oder Maussteuerungen zu emulieren.

Bei meinem Projekt (mal wieder ein Auqariuencomputer) gebe ich gewisse Parameter über ein 20x4 LCD Display aus, welche ich dann ebenfalls per LCD ändern möchte. Vorher habe ich dies mit einem einfachen Keyboard Modul gemacht, aber so ein Joystick Modul fände ich viel komfortabler. Eins vorweg , das Grundgerüst meines Sketches stützt sich auf die Arbeit eines anderen Aquariencomputer OpenSource Projektes. Daher möchte ich den Sketch auch nicht komplett hier hochladen (wenn es sich vermeiden lässt), obwohl nur noch weniges an den Urcode erinnert.
Die Menüsteuerung ist allerdings noch zur Gänze von dem vorherigen Coder übernommen worden, weshalb ich dies auch selbst noch nicht ganz durchblicke und wohl deshalb die Umstellung auf Joystick noch schwerer fällt.

Also bisher wurde es etwa wie folgt gelöst:

//Hier werden die Tasten des Keyboards festgelegt und müssen je nach Keypad angepasst werden
#define RIGHTKEY 0
#define UPKEY 1
#define DOWNKEY 2
#define LEFTKEY 3
#define SELECTKEY 4

// Tasten
int adc_key_val[5] ={ 
  50, 200, 400, 600, 800 };
int NUM_KEYS = 5;
int adc_key_in;
int key=-1;
int oldkey=-1;

Dann im loop:

  key = 0;
  adc_key_in = analogRead(0);
  key = get_key(adc_key_in);
  if (key != oldkey)
  {
    delay(50);
    adc_key_in = analogRead(0);
    key = get_key(adc_key_in);
    if (key != oldkey)
    {
      oldkey = key;

      if (key >=0)
      {
        MenuWerteAuswahl();
        MenuWerteSetzen();       
      }
    }

Also wenn ich das richtig verstehe gibt das Keyboard je nach Tastendruck einen gewissen Wert zurück, dieser wird mit adc_key_in gelesen und adc_key_val ordnet diese Werte dann der gewünschten Aktion zu (UPKEY, RIGHTKEY usw.) welche unter define festgelegt wurden.
So ganz verstehe ich aber noch nicht wo da die Verknüpfung zwischen den integer Werten in adc_key_in und den 5 Werten in adc_key_val sein soll???

Kann mir vllt jemand helfen, wie man den Code so umschreiben könnte, dass er mit dem Joystick funktioniert. Der Joystick soll nur die 5 Tasten widerspiegeln (hoch, runter, links, rechts, select) und es handelt sich um diesen:[Discontinued] SainSmart JoyStick Module + Free 10 Dupont wires for Ar – SainSmart.com.
Der Joystick wird zudem mit 3 verschiedenen Leitungen angesteuert. Einmal VRx (links/rechts) auf PIN 0, VRy (oben/unten) auf PIN 1 und SW (wahrscheinlich Select?) auf PIN 4.

Vielen Dank schonmal im Vorraus.

lG
MoonPie

/edit
Habe jetzt die fehlende Verknüpfung im Sketch "functions" gefunden

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;
}

Wenn ich das richtig interpretiere gibt er je nach input Wert den Wert welcher der gedrückten Taste (0 - 4) entspricht zurück. Dieser ist im Hauptprogramm dann in der Variable key gespeichert. Nun steht aber in key z.B. der Wert 0 (für RIGHTKEY), woher weiss aber das Programm nun dass dieser Wert RIGHTKEY ist?!

Nun steht aber in key z.B. der Wert 0 (für RIGHTKEY), woher weiss aber das Programm nun dass dieser Wert RIGHTKEY ist?!

#define RIGHTKEY 0

Dadurch wird schon vor dem Compilieren durch den Parser jedes auftauchen von RIGHTKEY durch 0 ersetzt.

Alternativ kannst du auch schreiben:
const byte RIGHTKEY = 0;

Hallo,

Vielen Dank habe es jetzt glaube ich soweit verstanden und die Joystick Steuerung auch soweit zusammengeschustert.
Ich muss nun einfach 3 key Werte abfragen (X, Y und Select) und je nachdem welcher gerade zutrifft wird der eigentliche key Wert auf diesen gesetzt.

//JoyStick
  keyX = 0;
  keyY = 0;
  keyS = 0;
  valueX = analogRead(JoyPinX);
  valueY = analogRead(JoyPinY);
  valueS = analogRead(JoyPinS);
  keyX = get_keyX(valueX);
  keyY = get_keyY(valueY);
  keyS = get_keyS(valueS);
if (keyX != -1 || keyY != -1 || keyS != -1)
{
  if (keyX >= 0)
    {
      key = keyX;         
    }
  if (keyY >= 0)
    {
      key = keyY;       
    }
  if (keyS >= 0)
    {
      key = keyS;       
    }
  if (key != oldkey)
    {
    oldkey = key;
    MenuWerteAuswahl();
    MenuWerteSetzen();
    }
}
else
{
  key = -1;
  oldkey = key;
}
int get_keyX(unsigned int input)
{
  int k;
  if (input <= 10)
   k = 3;
  else if (input >= 1010)
   k = 0;
  else 
   k = -1;
   
  return k;
}

int get_keyY(unsigned int input)
{
  int k;
  if (input <= 10)
   k = 1;
  else if (input >= 1010)
   k = 2;
  else 
   k = -1;

  return k;
}

int get_keyS(unsigned int input)
{
  int k;
  if (input <= 5)
   k = 4;
  else
   k = -1;
  
  return k;

}

Ich habe auch wieder den Umweg über "oldkey" genommen, was bedeutet ich muss den Stick immer erst in Mittelstellung zurück bringen ehe er den key Wert wieder setzt. Dadurch springt er nicht im Millisekunden Takt durch die Menüs.

Jetzt aber noch die Frage. Gäbe es eine Möglichkeit, dass die Werte (valueX, valueY, valueS) nur alle X ms abgefragt werden? Somit könnte man auf oldkey verzichten und wenn man den Joystick in die gewünschte Richtung gedrückt hält springt auch das Menü alle x ms weiter. Ich wüsste jetzt nur den Weg über delay(x), allerdings würde ich das gerne vermeiden.

lG
MoonPie

msTimer2 wäre da eine bequeme Option:
http://playground.arduino.cc/Main/MsTimer2

Ansonsten gibt es noch millis():

Damit kannst du den aktuellen millis Wert in loop abfragen und mit dem alten vergleichen. Wenn dann eine bestimmte Zeit vergangen ist macht man was.