Go Down

Topic: Tasterschaltung (Read 10453 times) previous topic - next topic

Mendel13

#45
Jun 26, 2015, 10:35 am Last Edit: Jun 26, 2015, 10:49 am by Mendel13
Sooo ... hier mal der redundante Code, der soweit funktioniert ...


Code: [Select]



int t01 = LOW; // setze die Variable mit Namen "t01" und gib ihr den Wert LOW
int t02 = LOW;
int t03 = LOW;
int t04 = LOW;
int t05 = LOW;
int t06 = LOW;
int minus = LOW;
int plus = LOW;
int man = LOW;

void setup() {
  //pinMode(14, INPUT); // Pin 14 = A0 ist Eingang für Taster, PullDown
  //pinMode(15, INPUT);
  //pinMode(16, INPUT);
  //pinMode(17, INPUT);
  pinMode(13, OUTPUT); // Pin13 .. als Ausgang
  pinMode(12, OUTPUT);
  pinMode(11, OUTPUT);
  pinMode(10, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(8, OUTPUT);
  pinMode(7, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(5, INPUT);
  pinMode(4, INPUT);
  digitalWrite(13, HIGH); // Programmstart Pin 13 auf HIGH


}

void loop() {
  t01 = digitalRead(14); // setze Var. t01-04 gleich dem Eingangspegel
  t02 = digitalRead(15);
  t03 = digitalRead(16);
  t04 = digitalRead(17);
  t05 = digitalRead(18);
  t06 = digitalRead(19);
  man = digitalRead(8);
  minus = digitalRead(5);
  plus = digitalRead(4);


  if (t01 == HIGH)  { // wenn t01 gleich HIGH dann...
    digitalWrite(13, HIGH); // setze Pin 15 auf HIGH ... und alle anderen auf LOW
    digitalWrite(12, LOW);
    digitalWrite(11, LOW);
    digitalWrite(10, LOW);
    digitalWrite(9, LOW);
    digitalWrite(8, LOW);
  }
  else if (t02 == HIGH)
  {
    digitalWrite(13, LOW);
    digitalWrite(12, HIGH);
    digitalWrite(11, LOW);
    digitalWrite(10, LOW);
    digitalWrite(9, LOW);
    digitalWrite(8, LOW);
  }
  else if (t03 == HIGH)
  {
    digitalWrite(13, LOW);
    digitalWrite(12, LOW);
    digitalWrite(11, HIGH);
    digitalWrite(10, LOW);
    digitalWrite(9, LOW);
    digitalWrite(8, LOW);
  }
  else if (t04 == HIGH)
  {
    digitalWrite(13, LOW);
    digitalWrite(12, LOW);
    digitalWrite(11, LOW);
    digitalWrite(10, HIGH);
    digitalWrite(9, LOW);
    digitalWrite(8, LOW);
  }
  else if (t05 == HIGH)
  {
    digitalWrite(13, LOW);
    digitalWrite(12, LOW);
    digitalWrite(11, LOW);
    digitalWrite(10, LOW);
    digitalWrite(9, HIGH);
    digitalWrite(8, LOW);
  }
  else if (t06 == HIGH)
  {
    digitalWrite(13, LOW);
    digitalWrite(12, LOW);
    digitalWrite(11, LOW);
    digitalWrite(10, LOW);
    digitalWrite(9, LOW);
    digitalWrite(8, HIGH);
  }

  if ((man == HIGH) && (minus == HIGH))
  {
    do
    {
      //delay(50);
      digitalWrite(7, HIGH);
    }
    while (minus == LOW);
    delay(20);
    digitalWrite(7, LOW);
  }
  if ((man == HIGH) && (plus == HIGH))
  {
    do
    {
      //delay(50);
      digitalWrite(6, HIGH);
    }
    while (plus == LOW);
    delay(20);
    digitalWrite(6, LOW);
  }

}







edit:

Nochmals zur verwünschten Funktion:
Mit 6 Tastern sollen 6 Funktionen angeschaltet werden (Im Versuch LEDs), die sich gegenseitig löschen ("Röhrenradio"). Pin13 soll als Start gleich eingeschaltet sein.

die 6. Funktion hat ne Sonderstellung. Ist sie aktiviert sollen LED 7 oder 8 leuchten, solange die Taster 7 oder 8 gedrückt werden, zusammen mit LED (Funktion) 6 . Sind andere LEDs an (1-5) sind 7, 8 ohne Funktion.







Mendel13

#46
Jun 26, 2015, 10:39 am Last Edit: Jun 26, 2015, 10:50 am by Mendel13
... und hier der Aufbau ...

Hab dat janze auf nen 168er geladen, funzt mal soweit super.

TelosNox

Code: [Select]

  if ((man == HIGH) && (minus == HIGH))
  {
    do
    {
      //delay(50);
      digitalWrite(7, HIGH);
    }
    while (minus == LOW);
    delay(20);
    digitalWrite(7, LOW);
  }

Erklär mal bitte kurz, was dieser code machen soll (also was du damit vorhast). Ich vermute nämlich, dass er nicht das macht, was du willst.

1. Willst du, dass MAN gleichzeitig gedrückt werden muss oder willst du, dass man den manuellen Modus aktiviert (1x tastern) und dann die plus und minus tasten funktionieren. Aktuell muss der Button gleichzeitig gedrückt sein.

2. Soll der Ausgang für Minus so lange auf HIGH sein, bis man den Taster loslässt (so interpretiere ich deine do/while Schleife)? Das funktioniert so nicht.
Du liest am Anfang einmal den Status für minus aus. Der ist jetzt auf HIGH.
Du kommst an der oben zitierten Codestelle an und man ist auch auf HIGH. Also geht er in den if block. Dann führt er so lange digitalWrite(7, HIGH) aus, wie minus auf LOW ist (minus ist aber auf HIGH). Weil du ein do/while gemacht hast, führt er die Schleife genau 1x aus, das garantiert ein do/while (das Gegenstück wäre die while/do Schleife, die gar nicht ausgeführt würde).
Danach wartet er 20ms und setzt den Ausgang dann wieder auf LOW.

Das heißt: Egal wie lange dein Taster gedrückt ist, der Ausgang ist immer für genau 20ms auf HIGH. Du könntest die Schleife einfach weglassen.
Code: [Select]

  if ((man == HIGH) && (minus == HIGH))
  {
    digitalWrite(7, HIGH);
    delay(20);
    digitalWrite(7, LOW);
  }

Das führt zum exakt selben Ergebnis.

Also berichte mal, was du denn eigentlich bezweckst, dann können wir dir helfen, das richtig zu realisieren.

Mendel13

wird taste 6 aktiviert geht "man" auf high ... solange bis taste 1-5 gedrückt wird.

taste 6 triggern: led 6 leuchtet und "man" ist high. wenn jetzt taste 7 oder 8 gedrückt wird, leuchtet zusätzlich entsprechend led 7 oder 8 solange taste 7 oder 8 gedrückt. wird 1-5 gedrückt geht "man" auf low, 7 und 8 sind sind deaktiv.

also ... schaltungsaufbau im arduino und auch extern gelötet funzt genau so.


TelosNox

#49
Jun 26, 2015, 11:58 pm Last Edit: Jun 26, 2015, 11:59 pm by TelosNox
Gemäß dem Code machen Taster 7 und Taster 8 nichts, wenn nicht auch Taster 6 zugleich gedrück ist.

Ebenso bleiben Led7 und Led8 nicht an, sondern sie flackern. Das sieht man vermutlich aber nicht, weil der Pin 20ms auf HIGH bleibt, dann auf LOW geht und dann der loop von vorne beginnt und du somit sofort wieder auf HIGH bist. Solange du einen trägen Verbraucher dran hast, ist sowas machbar aber korrekt ist es nicht.

Ich würde jetzt erwarten:
Ich drücke kurz auf Taster 6 (und lasse wieder los). Das Ding schaltet jetzt auf manuellen Modus und solange ich keinen anderen Taster (1-5) drücke, bleibt der manuelle Modus an. Solange der manuelle Modus drin ist, kann ich Taster 7 oder 8 drücken, um damit dann LED 7 bzw. 8 auszulösen. Die LEDs sollen so lange an bleiben, wie ich den jeweiligen Taster gedrück halte.

Entspricht das dem, wie dein Programm funktionieren soll? (ich will nicht wissen, was es aktuell macht, sondern wohin du am Ende damit willst)

Mendel13

#50
Jul 01, 2015, 07:11 am Last Edit: Jul 01, 2015, 07:13 am by Mendel13
Quote
Gemäß dem Code machen Taster 7 und Taster 8 nichts, wenn nicht auch Taster 6 zugleich gedrück ist.
hm ... im aufbau machen sie aber das was ich will ... ich tippe auf taster 6 , led 6 geht an. ich drücke taster 7 und led 7 leuchtet zusätzlich auf, solange gedrückt. ebenso 8 .... weil: "man" wird  HIGH wenn ich die taste 7 oder 8 drück  ... es wird ja die bedingung
Code: [Select]
if ((man == HIGH) && (minus == HIGH))
bzw.
Code: [Select]
if ((man == HIGH) && (plus == HIGH))
erfüllt ...


Quote
ch würde jetzt erwarten:
Ich drücke kurz auf Taster 6 (und lasse wieder los). Das Ding schaltet jetzt auf manuellen Modus und solange ich keinen anderen Taster (1-5) drücke, bleibt der manuelle Modus an. Solange der manuelle Modus drin ist, kann ich Taster 7 oder 8 drücken, um damit dann LED 7 bzw. 8 auszulösen. Die LEDs sollen so lange an bleiben, wie ich den jeweiligen Taster gedrück halte.

Entspricht das dem, wie dein Programm funktionieren soll?
jepp genau so. und das tuts auch ... ob die LED 7/8 "flackern" will ich noch mitm oszi anschauen.

TelosNox

Arfff.. Fehler meinerseits. Man ist nicht der Tasterzustand, sondern da liest du den LEDKanal aus. Ja, dann funktionierts so, aber deine + und - LEDs flackern halt (was du aber nicht siehst).

Mendel13


ok .... denke so ists einfacher:


Code: [Select]
if ((man == HIGH) && (minus == HIGH))
  {
    digitalWrite(7, HIGH);
  }
  else
  {
    digitalWrite(7, LOW);
  }
  if ((man == HIGH) && (plus == HIGH))
  {
    digitalWrite(6, HIGH);
  }
  else
  {
    digitalWrite(6, LOW);
  }

TelosNox

Jupp, so is besser.
Und wenn du noch redundantes HIGH bzw. LOW setzen des Pins vermeiden willst, dann speicherst du dir den Zustand in einer Variablen ab.

Code: [Select]
if (man == HIGH && minus == HIGH && !minusActive)
  {
    digitalWrite(7, HIGH);
    minusActive = true;
  }
  else if (minusActive)
  {
    digitalWrite(7, LOW);
    minusActive = false;
  }


Natürlich must du irgendwo noch minusActive als boolean deklarieren.

Das Gleiche dann analog für plus. So schaltest du den Pin immer nur dann, wenn er nicht schon in dem Zustand ist.

Mendel13

So, nun hab ich gesehen, dass led7 und 8 was blödes machn, wenn ich minus und plus (versehentlich) gleichzeichzeitig drück. ist das der fall sollen 7 und 8 aus bleiben:

Code: [Select]
if ((man == HIGH) && (minus == HIGH) && (plus == LOW))

    /*Sonderfall: Wenn man (gesetzt durch Pin8 durch t06 getriggert)
     * zusammen mit minus (gesetzt durch Pin5) HIGH sind dann ...
     * sind plus und minus auf HIGH bleiben pin 6 und 7 LOW
     */

  {
    digitalWrite(7, HIGH); // Pin7 auf HIGH zusammen mit Pin8 = t06 ...
    delay(200); // Pin7 bleibt 200ms auf HIGH

  }
  else
  {
    digitalWrite(7, LOW); // ansonsten auf LOW belassen
  }


  if ((man == HIGH) && (plus == HIGH) && (minus == LOW)) //dito mit plus
  {
    digitalWrite(6, HIGH);
    delay(200);
  }
    else
    {
      digitalWrite(6, LOW);
    }


Mendel13

soo da nun alles so funktioniert wie ichs verstehe lass ich das jetzt nicht so stehen ...

ich nix kapier:


Code: [Select]

struct LedZustand   
{
  bool Led00: 1;
  bool Led01: 1;
  bool Led02: 1;
  bool Led03: 1;
  bool Led04: 1;
  bool Led05: 1;
  bool Led06: 1;
  bool Led07: 1;
};
LedZustand Leds ;

void setup() {
  pinMode(14, INPUT); // Pin 14 = A0 ist Eingang für Taster, PullDown
  pinMode(15, INPUT);
  pinMode(16, INPUT);
  pinMode(17, INPUT);
  pinMode(13, OUTPUT); // Pin13 .. als Ausgang
  pinMode(12, OUTPUT);
  pinMode(11, OUTPUT);
  pinMode(10, OUTPUT);
  digitalWrite(13, HIGH); // Programmstart Pin 13 auf HIGH
}

void loop() {
  Leds.Led01 = digitalRead(14);
  Leds.Led02 = digitalRead(15);
  Leds.Led03 = digitalRead(16);
  Leds.Led04 = digitalRead(17);


  if (Leds.Led01 || Leds.Led02 || Leds.Led03 || Leds.Led04)  { // wenn irgend ein Button auf HIGH ist
    digitalWrite(13, Leds.Led01);
    digitalWrite(12, Leds.Led02);
    digitalWrite(11, Leds.Led03);
    digitalWrite(10, Leds.Led04);
  }
}



was macht:

struct LedZustand   <= struct?
{
  bool Led00: 1;       <=    ... : 1; ?? wie verstehe ich den doppelpunkt?

LedZustand Leds ;  <= ??

Leds.Led01 = digitalRead(14); <= ?? punkt operator sagt mir leider noch nix

 if (Leds.Led01 || Leds.Led02 || Leds.Led03 || Leds.Led04)  {
    digitalWrite(13, Leds.Led01);  <= wieder punkt operator




michael_x

Quote
wie verstehe ich den doppelpunkt
Gute Frage! (relativ ungewöhnliche Syntax))
Gibt die Anzahl Bits eines Bitfelds an. Hier besteht die ganze struct Ledzustand aus 8 Bit, die einzeln als Led00 usw. angesprochen werden können.

Code: [Select]
struct Ledzustand {bool Led00; /* ... */}; // definiert den Datentyp Ledzustand

Ledzustand leds; // definiert leds als Variable vom Typ Ledzustand

leds.Led00 = true; // setzt das struct-Element Led00 der Variable



Das ist Standard C/C++, nix Arduino-spezifisches, und es gibt jede Menge Informationen darüber, sicher auch einfacher als dies hier

Zu Bitfeldern hier

combie

#57
Jul 03, 2015, 09:31 am Last Edit: Jul 03, 2015, 11:13 am by combie
Ich habe hier auch noch eine Variante, allerdings mit 2 Problemen:
1. Es ist völlig ungetestet
2. Es wird die Verwirrung optimieren

Code: [Select]

#define ForEach(array,var) for(int var=0;var<(sizeof(array)/sizeof(array[0]));var++)

const byte sonderfunktion = 5; // 6te Taste im Block

byte RadioTastenBlock[] = {14,15,16,17,18,19};
byte RadioLedBlock[]    = {13,12,11,10,9,8};
byte ManTastenBlock[]   = {4,5};
byte ManLedBlock[]      = {7,6};

byte Tastenspeicher;

void initRadio()
{
  ForEach(RadioTastenBlock,i)
  {
    pinMode(RadioTastenBlock[i],INPUT); 
    pinMode(RadioLedBlock[i],OUTPUT); 
  }
  ForEach(ManTastenBlock,i)
  {
    pinMode(ManTastenBlock[i],INPUT); 
    pinMode(ManLedBlock[i],OUTPUT); 
  }
  setRadioTaste(0); // default setzen, erste Taste ist gedrückt
}

void setRadioTaste(byte taste)
{
  Tastenspeicher = taste; 
  ForEach(RadioLedBlock,i) digitalWrite(RadioLedBlock[i],i==taste); 
}


void tastenauswertung()
{
  ForEach(RadioTastenBlock,i)
    if(digitalRead(RadioTastenBlock[i]))
    {
       setRadioTaste(i);
       exit;
    };
   
  int count = 0;
  ForEach(ManLedBlock,i)
  {
    count += digitalRead(ManTastenBlock[i])?1:0;
    digitalWrite(ManLedBlock[i],(1 == count)&&(sonderfunktion == Tastenspeicher)); 
  }
}

void setup()
{
  initRadio();
}

void loop()
{
  tastenauswertung();
}


Leicht um weitere Taster erweiterbar.
Ich habe versucht auf Bitfelder und . Operatoren zu verzichten.
Auch das durchnummerieren von Tasten und LED ist mir nicht genehm gewesen.
In beiden Tastenblocks wird jeweils nur eine Taste ausgewertet. Weitere gedrückte Tasten werden ignoriert.

Der nächste Schritt wäre:
Die Datenstruktur überarbeiten und in Klassen gießen.

Säge kein Sägemehl.

Mendel13

hallo .... ich wieder ...

hab den versuch gestartet, den sketch auf nen attiny 2312 zu laden, die pins natürlich entsprechend umgemappt.
nun hab ich das phänomen, dass die Funktionen (=LEDs) nur solange an sind, wie getastet wird.

Hat der Attiny ne andere Interpretation?

Was überhaupt nicht zu funktionieren scheint, sind die internen pullups an den eingängen. Die Inputs sind zwar messbar HIGH, aber der sketch geht überhaupt nicht (auf dem 168er hingegen ja; selbstverständlich ist der sketch entsprechend umgeschrieben auf pullup).

grüssle -der mendel

agmue

1. attiny 2312

2. Hat der Attiny ne andere Interpretation?

3. Was überhaupt nicht zu funktionieren scheint, sind die internen pullups an den eingängen.
Zu 1.: Du meinst 2313?

Zu 2.: Natürlich gibt es Unterschiede, für den Sketch in #45 sollten die aber nicht relevant sein.

Zu 3.: Bei ATtiny85 und 4313 funktionieren die Pullups wie beim UNO. Mach mal digitalWrite(13,digitalRead(2));, dann sollte es klar werden.
Die Vorstellungskraft ist wichtiger als Wissen, denn Wissen ist begrenzt. (Albert Einstein)

Go Up