Pages: [1] 2   Go Down
Author Topic: Auswahltaster für Programmabschnitt  (Read 1405 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Newbie
*
Karma: 1
Posts: 24
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hallo!

Ich will mit einem Arduino verschiedene PC Programme steuern. Da diese aber nicht die selben Befehle benutzen brauch ich für jedes Programm extra Steuerbefehle. Ich müsste also irgenwie auwählen können welches Programm ich steuern will. Oder ander gesagt, ich müsste auswählen können welchen Teil der Programmierung ich gerade verwenden will.

z.b.
ich drücke Taster 1, dann leuchtet LED 1 und das Programm berücksichtigt nur den Abschnitt der Programmierung, welcher zu Programm 1 gehört.
oder
Drückt man Taster 2, leuchtet LED 2 und es wird nur der Programmabschnitt benutzt, welcher für Programm 2 zuständig ist.

Hab irgendwann mal mit programmierbaren Taschenrechnern rumgespielt, da gab es eine goto Funktion, hab aber gelesen das man sowas vermeiden soll.
Logged

Offline Offline
Sr. Member
****
Karma: 8
Posts: 272
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ich finde es da immer am besten, das Programm "auf Deutsch" zu programmieren, und dann spaeter die Details hinzuzufuegen:

Code:
#define MAX_PROGRAMME 3

uint8_t aktuellesProgramm = 0;

void setup()
{
}

void loop()
{
    if (taster1Gedrueckt())
    {
        sendeSteuerbefehl(aktuellesProgramm);
    }

    if (taster2Gedrueckt())
    {
        ++aktuellesProgramm;
        if (aktuellesProgramm > MAX_PROGRAMME)
            aktuellesProgramm = 0;
    }
}

void sendeSteuerbefehl(uint8_t programm)
{
    switch (programm)
    {
        case 0:
            // Sende befehl fuer programm 0
            break;
        case 1:
            // Sende befehl fuer programm 1
            break;

        // usw.
    }
}
Logged

Offline Offline
Faraday Member
**
Karma: 96
Posts: 3495
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Noch schöner geht das mit enums:

Code:
enum programme { PROGRAMM1, PROGRAMM2 };

void loop()
{
    if (taster1Gedrueckt())
    {
        sendeSteuerbefehl(PROGRAMM1);
    }
    else if (taster2Gedrueckt())
    {
         sendeSteuerbefehl(PROGRAMM2);
    }
}

void sendeSteuerbefehl(uint8_t programm)
{
    switch (programm)
    {
        case PROGRAMM1:
            // Sende befehl fuer programm 0
            break;
        case PROGRAMM2:
            // Sende befehl fuer programm 1
            break;

        // usw.
    }
}

Man kann natürlich auch für jedes Programm eine Methode schreiben und diese direkt aufrufen wenn ein Taster gedrückt wird.
Logged

Offline Offline
Sr. Member
****
Karma: 8
Posts: 272
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Noch schöner geht das mit enums:

Er moechte mit Taster 2 das Programm wechseln.
Enums machen "++programm" schwer....
#define's machen das programm mehr lesbar.

Aber wir lenken hier vom Thema ab smiley
Logged

Offline Offline
Faraday Member
**
Karma: 96
Posts: 3495
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Da steht nicht explizit da, dass er mit den Tastern Programme praktisch als Plus/Minus schalten will. Ich habe das als "Ein Taster pro Programm" gelesen. Kann man aber so oder so sehen smiley

Man kann aber auch enums über einen kleinen Umweg inkrementieren:
Code:
typedef enum { PROGRAMM1, PROGRAMM2 } programme;
programme aktuellesProgramm = PROGRAMM1;

aktuellesProgramm = (programme)(aktuellesProgramm + 1);
« Last Edit: October 17, 2013, 01:39:08 pm by Serenifly » Logged

Germany S-H
Offline Offline
Faraday Member
**
Karma: 134
Posts: 2849
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

z.b.
ich drücke Taster 1, dann leuchtet LED 1 und das Programm berücksichtigt nur den Abschnitt der Programmierung, welcher zu Programm 1 gehört.
oder
Drückt man Taster 2, leuchtet LED 2 und es wird nur der Programmabschnitt benutzt, welcher für Programm 2 zuständig ist.

Warum willst Du es kompliziert machen und "Taster" verwenden?

Warum nicht einfach mit Kippschaltern, die zwei stabile Schaltlagen haben?
Sagen wir Schalter hoch = 1 und Schalter runter = 0

Dann machst Du eine große Hauptloop, in der die Stellung der Kippschalter abgefragt wird, und je nachdem rufst Du dann Deine verschiedenen Unterprogramme auf. Mit zwei Kippschaltern hast Du insgesamt vier Schaltmöglichkeiten:

Pseudo-Programmablauf:
Code:
// Pins für 2 Kippschalter
#define S1 4
#define S2 5

void setup()
{
  pinMode(S1,INPUT);
  pinMode(S2,INPUT);
}

void loop00()
{}

void loop01()
{}

void loop10()
{}

void loop11()
{}

void loop()
{
  if (digitalRead(S1)==0 && digitalRead(S2)==0) loop00();
  if (digitalRead(S1)==0 && digitalRead(S2)==1) loop01();
  if (digitalRead(S1)==1 && digitalRead(S2)==0) loop10();
  if (digitalRead(S1)==1 && digitalRead(S2)==1) loop11();
}

Wenn die Schalter 0 und 0 liefern, wird immer die loop00 aufgerufen.
Wenn die Schalter 0 und 1 liefern, wird immer die loop01 aufgerufen.
Und so weiter. 2 Kippschalter steuern 4 Programme, 3 Kippschalter 8 Programme, 4 Kippschalter 16 Programme etc., alles je nach Stellung der Kippschalter.

Mit Tastern, die beim Betätigen wieder in die Ausgangslage zurückfedern, kann man vergleichbares programmieren.
Das ist aber für Anfänger nicht ganz so einfach zu programmieren, weil Du Statusänderungen an den Tasten verwalten mußt.
Logged

0
Offline Offline
Newbie
*
Karma: 1
Posts: 24
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Oh Danke, sind ja schon ein paar Antworten da.

Es soll schon 1 Taster pro Programm werden. Ich denke maximal 4 Programme, also 4 Taster.
Mit Schalter wärs sicher einfacher, aber mit Taster ist es besser zu bedienen und sieht auch viel besser aus.  smiley

Als Anfänger muß ich mir eure Vorschläge aber erst mal duch den Kopf gehen lassen und rumprobieren, ist ja nicht so einfach...
Logged

Offline Offline
Faraday Member
**
Karma: 96
Posts: 3495
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Du kannst auch das von jurs für Taster abwandeln. Das ist am einfachsten.

Die Taster nacheinander abfragen und dann für jeden Taster eine eigene Methode aufrufen. Entprellen der Taster nicht vergessen.
Logged

Germany S-H
Offline Offline
Faraday Member
**
Karma: 134
Posts: 2849
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Es soll schon 1 Taster pro Programm werden.

Ah, zum Glück hat sich der Hersteller meines Satelliten-Receivers nicht dasselbe überlegt, sonst hätte ich hier für einen SAT-Receiver mit 4000 Programmen wahrscheinlich eine Fernbedienung mit 4000 Tasten auf dem Tisch liegen.

Anderes Codebeispiel (Code UNGETESTET):
Code:
// INPUTTYPE kann auf INPUT oder INPUT_PULLUP gesetzt werden
// Mit INPUT_PULLUP werden die internen PullUp-Widerstände aktiviert
#define INPUTTYPE INPUT_PULLUP

byte taster[]={4,5,6,7};
byte leds[]={8,9,10,11};

void setup()
{
  for (int i=0;i<4;i++)
  {
    pinMode(taster[i],INPUTTYPE);
    pinMode(leds[i],OUTPUT);
  }
  setProgram(0); // Erstes Programm einstellen
}

void setProgram(byte b)
// Schaltet die LED des zugeordneten Programms ein
// Parameter b: zu setzendes Programm
{
  for (int i=0;i<4;i++)
  {
    if (i==b)  // bei gesetztem Programm LED ein
      digitalWrite(leds[i],HIGH);
    else  // sonst LED aus
      digitalWrite(leds[i],LOW);
  }
}

void handleButton()
// Funktion setzt die LED, die der zuletzt gedrückten Taste zugeordnet ist
{
  for (int i=0;i<4;i++)
  {
    byte pressed=digitalRead(taster[i]);
    if (INPUTTYPE==INPUT_PULLUP) pressed=!pressed; // vertauschte Logik
    if (pressed) setProgram(i);
  } 
}

void loop0()
{}

void loop1()
{}

void loop2()
{}

void loop3()
{}

void loop()
{
  byte program=0;
  for (int i=0;i<4;i++)
  { // das gerade gesetzte Programm aus der gerade leuchtenden LED abfragen
    if (digitalRead(leds[i])) program=i;
  } 
  switch(program)
  {
    case 0: loop0();break;
    case 1: loop1();break;
    case 2: loop2();break;
    case 3: loop3();break;
  }
}

Ich habe den Code gleich für die Aktivierung der internen PullUp-Widerstände vorgesehen, dann brauchst Du keine externen PullDown-Widerstände an den Tastern. Und LEDs werden auch bereits geschaltet.
Logged

0
Offline Offline
Newbie
*
Karma: 1
Posts: 24
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Sei lieber froh das dir dein Sat-Hersteller nicht 12 Kippschalter eingebaut hat. smiley-grin

Mit einem Taster 4 LED duchschalten würde auch funktionieren, egal.
Danke, werd das mal durchprobieren.
Logged

Germany S-H
Offline Offline
Faraday Member
**
Karma: 134
Posts: 2849
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Danke, werd das mal durchprobieren.

Wie mir beim nochmaligen Überfliegen des geposteten Codes gerade auffällt, habe ich zwar eine Funktion "handleButton()" geschrieben, aber diese wird nirgends aufgerufen. Der Aufruf gehört irgendwo in die loop-Funktion rein, z.B. am Anfang oder am Ende der loop():
handleButton();
Logged

0
Offline Offline
Newbie
*
Karma: 1
Posts: 24
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ok, werd ich noch einfügen.
Hab schon etwas rumprobiert, aber noch nicht zum laufen gebracht.
Bin grad am "entschlüsseln" von dem Code.


Code:
void setProgram(byte b)

versteh ich noch nicht so ganz.
Was sagt das aus?
b soll dann gleich i sein, aber wo wird die Größe von b angegeben?
Logged

Offline Offline
Faraday Member
**
Karma: 96
Posts: 3495
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Beim Aufruf der Funktion:
Code:
setProgram(i)

Da wird dann i nach b kopiert
Logged

Germany S-H
Offline Offline
Faraday Member
**
Karma: 134
Posts: 2849
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Bin grad am "entschlüsseln" von dem Code.

Die Funktion "handleButton()" geht alle vier Buttons mit Laufindex i durch.
Wenn eine Taste gedrückt ist, wird "setProgram(i)" aufgerufen.

In der Funktion setProgram ist der übergebene Parameter als "b" benannt. Das ist eine Kopie des Parameters i, der beim Funktionsaufruf an die Funktion übergeben wurde.

Die Funktion setProgram(byte b) geht nun alle vier LEDs durch, wenn die Nummer des übergebenen Buttons mit der Nummer der LED identisch ist, wird die LED eingeschaltet. Andernfalls ausgeschaltet.

Und in der loop werden nun reihum alle LEDs ausgelesen, ob sie ein- oder ausgeschaltet sind: Und entsprechend der eingeschalteten LED wird nun entweder loop0, loop1, loop2 oder loop3 immer wieder aufgerufen.

So dass Du nun vier verschiedene Loop-Funktionen hast, die immer wieder aufgerufen werden, abhängig davon, welche LED leuchtet. Und welche LED leuchtet ist davon abhängig, welcher Button zuletzt gedrückt wurde.

noch nicht zum laufen gebracht.

Je nachdem, ob Du die Buttons mit PullDown- oder PullUp-Widerständen angeschlossen hast, mußt Du im Programm entweder
#define INPUTTYPE INPUT
oder
#define INPUTTYPE INPUT_PULLUP
setzen, damit die Buttons bei der Abfrage das erwartete Ergebnis zurückliefern.
Logged

0
Offline Offline
Newbie
*
Karma: 1
Posts: 24
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Es tut sich was!

Aber erst als ich duch rumprobieren die Taster Massegeschalten gemacht habe.
War das Absicht?  Sowas bin ich nicht gewohnt.  smiley

Mir ist jetzt aufgefallen das das umschalten ja nur dann funktioniert, wenn der gerade aktive Loop am Ende ist und von vorne beginnt. (ist irgendwie logisch wo ich jetzt darüber nachdenke)
Ich weis noch nicht genau ob das bei dem was ich vorhab relevant ist.
Könnte man sowas noch umgehen?
Logged

Pages: [1] 2   Go Up
Jump to: