dynamische Zuweisung für While Anweisung

Hallo Zusammen, bei einer While Anweisung ist es mir nicht möglich, die Variable für den Vergleich zur Laufzeit dynamisch zuzuweisen. Wird die Variable aber direkt zugewiesen tut es. Im Beispielcode habe ich die beiden Zeilen entsprechend kenntlich gemacht.

Das eigentliche Ziel ist es die Variable "taster" zur Laufzeit zu ermitteln (die IF Anweisung) und dann später an die While Anweisung zu übergeben. Und genau das tut nicht.

Gunther

int taster1=0;
int taster=0;
int LED=0;
void setup()
{
pinMode(48, OUTPUT);
pinMode(38, OUTPUT);
pinMode(39, INPUT);
}
void loop()
{
if(digitalRead(39)==HIGH){LED=48;taster=39;}                  //abfragen des Tasters
//taster1=taster;                                               //Testzuweisung       --> tut NICHT
taster1=39;                                                   //Testzuweisung       --> TUT
while(digitalRead(taster1)==HIGH){digitalWrite(LED,HIGH);}    //solange man drückt Licht an
digitalWrite(LED,LOW);                                        //Licht wieder aus

digitalWrite(38,HIGH);                                        //Blinken nur um zu sehen ob das Programm läuft
delay(200);
digitalWrite(38,LOW);
delay(200);

LED=0;                                                        //alles wieder auf Null
taster=0;
}

Ganz mies gelöst würde ich mal sagen.
Warum while? Verstehe den ganzen Grund dahinter nicht.

void loop()
{
int state_taster = digitalRead(39);

if(state_taster) state_led = 1;
else state_led = 0;

digitalWrite(LED, state);
}
}
//taster1=taster;                                               //Testzuweisung       --> tut NICHT
taster1=39;                                                   //Testzuweisung       --> TUT

Das macht doch genau das, was du geschrieben hast! taster1 wird erst mit dem Wert von taster gesetzt, sobald while(0) ← Taste nicht gedrückt
Somit ist das einzig plausible Ergebnis, dass taster1 = 0 ist. Des weiteren setzt du bei zweiten Teil nicht den Status vom Taster, sondern lediglich die Zahl 39.

Irgend wie nicht ganz. Die 39 ist der Pin. Sinn der Übung ist, später zur Laufzeit mit der IF Anweisung mehrere Taster abzufragen und den der gerade betätigt wird an die While Anweisung zu übergeben. Das Gleiche gilt natürlich für die LED. Es sollte dann also so aussehen:

void loop()
{
if(digitalRead(39)==HIGH){LED=48;taster=39;}                       //abfragen des Tasters
while(digitalRead(taster)==HIGH){digitalWrite(LED,HIGH);}    //solange man drückt Licht an
digitalWrite(LED,LOW);                                             //Licht wieder aus

LED=0;                                                        //alles wieder auf Null
taster=0;
}

die beiden Zeilen die Dich erschüttern (taster1=taster; und taster1=39;) habe ich nur eingebaut um den Haken zu finden. Die Zeilen so wie oben laufen nicht durch. Es bleibt in der While Anweisung stecken.

Aber was soll die while-Schleife? loop() ist im Prinzip eine while-Schleife. Deshalb reichen da i.d.R. if-Abfragen

Wenn du das richtig machen willst, entprelle den Taster und schalte die LED mit eine if-Abfrage ein wenn er gedrückt wurde.

bastelheini: Die Zeilen so wie oben laufen nicht durch. Es bleibt in der While Anweisung stecken.

Wenn die if-Bedingung nicht erfüllt ist, behält die Variable taster ihren Wert und wird nicht auf 39 gesetzt.

Und wenn immer noch taster=0; gesetzt ist, fragst Du in der nachfolgenden while-Schleife ab, ob Pin-0, also der RX-Pin der Serial Schnittstelle auf HIGH steht.

Dein Problem scheint aber eher zu sein, einen ordentlich strukturierten Code zu schreiben. So wie das aussieht ist das wild zusammengwürfelt. Copy und paste und nichts wissend wie man es richtig anpasst, sorry, anders sieht das aber nicht aus.

Warum deklarierst du oben die Aus-und Eingänge nicht int button1 = 39; oder

define BUTTON1 39

if(digitalRead(39)==HIGH){LED=48;taster=39;}                       //abfragen des Tasters

Warum liest du hier die Variable ein?? Das macht keinen Sinn! Da fragt man besser mit (while(taster) { } ab,

while(digitalRead(taster)==HIGH){digitalWrite(LED,HIGH);}    //solange man drückt Licht an

Der Rest des Codes ist ebenfalls absolut überflüssig Es hätte void loop () {digitalWrite(LED, digitalRead(BUTTON));} vollkommen ausgereicht und macht genau das, was du umständlich geschrieben hast.

Und wenn immer noch taster=0; gesetzt ist, fragst Du in der nachfolgenden while-Schleife ab, ob Pin-0, also der RX-Pin der Serial Schnittstelle auf HIGH steht.

Und dann sollte er doch die While Schleife ignorieren.

Habe ich eben kurz getestet. Wenn die Variable durch die direkte Eingabe "digitalRead(0)" ersetzt wird bleibt Sie auch stecken. Es scheint also am nicht vorhandenen Eingang zu liegen. Danke. Ich geh der Sache nach.

Mit IF klappt es nicht wirklich so wie ich will. Das war mein erster Ansatz.

if(digitalRead(39)==HIGH){LED=48;taster=39;} if(digitalRead(taster)==HIGH){digitalWrite(LED,HIGH);} else{digitalWrite(LED,LOW);}

Wird eine ziemlich aufwendige Steuerung mit über 20 Tastern. Da will ich nicht alles 100 mal schreiben.

Im meinem ersten Post sind die Ein- und Ausgänge deklariert. Ich habe nur den Teil aus dem Code rauskopiert der Probleme bereitet und nicht alles bei jedem Post wiederholt.

Da will ich nicht alles 100 mal schreiben.

Musst du doch auch nicht. Man kann Pins in einem Array anlegen. Dann kann man über das Array iterieren und jeden Pin testen.

Sowas in der Art:

const byte pins[] = { 20, 21, 22 };

for(int i = 0; i < sizeof(pins); i++)
{
    if(digitalRead(pins[i]) == HIGH)
        ...
}

Funktionen sind an andere Stelle auch eine Möglichkeit Code der sich wiederholt nur einmal zu schreiben.

Auf diese Art wollte ich den Wert für die Variable taster ermitteln und dann die folgenden Zeilen viel allgemeiner halten.

Danke sschultewolter. Ich habe die Variable jetzt auf 2 festgelegt und obwohl der Pin nicht dekleriert ist läuft es jetzt.

int taster1=0;
int taster=0;
int LED=0;
void setup()
{
pinMode(48, OUTPUT);
pinMode(38, OUTPUT);
pinMode(39, INPUT);
}
void loop()
{
taster=2;
if(digitalRead(39)==HIGH){LED=48;taster=39;}
while(digitalRead(taster)==HIGH){digitalWrite(LED,HIGH);}    //solange man drückt Licht an
digitalWrite(LED,LOW);                                        //Licht wieder aus

LED=0;                                                        //alles wieder auf Null
taster=0;
}

Also noch eine sinnvolle Definition für "alle Taster aus" finden

Natürlich kann man auch direkt den Port als Zahl schreiben, wenn diese auch bei pinMode verwendet wurde.
Warum machst du es nicht so, wie Serenfly geschrieben hat?

 const byte input[] = { 20, 21, 22 };
byte state_output[] = { 0, 0, 0 };	
const byte output[] = { 20, 21, 22 };

void setup()
{
	for(int i = 0; i < sizeof(input)) pinMode(input[i], INPUT);
	for(int i = 0; i < sizeof(output)) pinMode(output[i], OUTPUT);
}

void loop()
{
	// Taster einlesen
	for(int i = 0; i < sizeof(input); i++) state_output[i] = digitalRead(input[i]);
}

“Also noch eine sinnvolle Definition für “alle Taster aus” finden” Wie meinst du das?
Wird doch garnicht benötigt.

Hallo jurs, entschuldige der entscheidende Tip mit dem RX Pin kam von Dir.

Hallo sschultewolter, natürlich werde ich die For Anweisung verwenden. Hatte ich Serenifly schon gepostet.

Aber ich brauch doch For nicht einzubauen bevor nicht klar ist warum die Anweisung dahinter nicht klappt.

Doch die sinnvolle Definition wird benötigt. Man verwendet doch keine "offenen" Eingänge. Da ist doch nicht gewährleistet, daß die einen definierten Zustand haben. Über die Hardware will ich das nicht machen. Das wäre dann ein Pin weniger. Aber man könnte z. B. den Teil im Code in dem das PIN2 verwendet wird überspringen. Z. B. auf die Schnelle mit goto Ende.

bastelheini: Aber man könnte z. B. den Teil im Code in dem das PIN2 verwendet wird überspringen. Z. B. auf die Schnelle mit goto Ende.

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA goto

Vergiß goto! aber schnell!

anstatt

if (bedingung) {goto Ende} mach irgentwas label Ende

funktionier auch

if (negierte bedingung) {mach irgentwas}

Grüße Uwe

Organisiere dir bitte ein ordentliches C Buch. Du schmeißt da einen ganzen Haufen durcheinander. Ich weiß nicht, von welcher Sprache du die goto Variante kennst, aber solch einen SpaghettiCode will niemand sehen oder debuggen!

Goto kommt von Basic da konnte man ohne Label zu definieren Zeilen nach Nummern anspringen, ich hab Basic nie gemocht. Pascal konnte es damals schon viel besser.

rudirabbit: Goto kommt von Basic da konnte man ohne Label zu definieren Zeilen nach Nummern anspringen, ich hab Basic nie gemocht. Pascal konnte es damals schon viel besser.

Da brauchte man auch unbedingt Zeilennummern. Wenn Du mal etwas dazwischenklemmen mußtest dann waren alle Zeilennummern zu ändern und alle Sprünge auf die veränderten Zeilen. Basic kann auch Labbel.

Grüße Uwe

Ich will ja hier keine philosophische Diskussion vom Zaun brechen. Goto gabs schon unter MS DOS (und gibt es noch in der CMD) nicht nur unter Basic. Und ja ich nutze es z. B. um verschachtelte Schleifen zu verlassen oder um den Code abzubrechen und direkt ans Ende zu springen. Aber immer vermeiden zurück zu hüpfen. Dann wirds schnell unübersichtlich. :D

bastelheini: Und ja ich nutze es z. B. um verschachtelte Schleifen zu verlassen

Und das ist auch eine von vielleicht zwei legitimen Verwendungen dafür. Aber schon um eine einzelne Schleife vorzeitig abzubrechen gibt es break.

Alternativ, wenn du dich in einer Funktion befindest, kannst du auch return zum vorzeitigen Abbrechen nutzen. Wie das in der loop aussieht, kann ich nicht sagen. Wenn es wie folgt aussieht, sollte das auch gehen. Bin mir da jetzt aber nicht sicher, ob die loop so eingebunden wird.

int main(void) {

while(1) {
loop();
}
return 0;
}