Potentiometer auf unterschiedlichen Positionen unterschiedliche Funktionen

Hallo,
ich versuche verzweifelt mit einem Potentiometer auf drei unterschiedlichen Positionen drei verschieden Funktionen abzuspielen.
Das heißt: Ich stelle das Potentiometer mit ausgeschaltetem Arduino auf den linken Anschlag und schalte dann den Arduino ein, jetzt soll der in dem Beispiel unten redled 9 Sekunden leuchten und dann ausgehen.
Beim nächsten Mal stelle das Potentiometer mit ausgeschaltetem Arduino auf den rechten Anschlag und schalte dann den Arduino ein, jetzt soll der in dem Beispiel unten greenled 9 Sekunden leuchten und dann ausgehen.
In der ungefähren Mittelstellung die yellowled...
Ich habe keine Ahnung wie ich dies bewerkstelligen kann.

Ein einfaches (und für mich hoffentlich verständliches) Beispiel ist dieses (funktioniert aber so nicht, aber so weit bin ich...):

int redled = 3;
int yellowled = 4;
int greenled = 5;
int position;

// the setup function runs once when you press reset or power the board
void setup() {

  pinMode (3, OUTPUT);
  pinMode (4, OUTPUT);
  pinMode (5, OUTPUT);

}

// the loop function runs over and over again forever
void loop() {

  position = analogRead(A0);
  map (position, 0, 1023, 1, 3);

  if (position == 1)
  {
    digitalWrite (redled, 1);
    delay(9000);
    digitalWrite (redled, 0);
  }
  else if (position == 2)
  {
    digitalWrite (yellowled, 1);
    delay (9000);
    digitalWrite (yellowled, 0);
  }
  else
  {
    digitalWrite (greenled, 1);
    delay (9000);
    digitalWrite (greenled, 0);
  }
}

Danke fürs anschauen!!!

Hallo,

Du speicherst den gemappten Wert nicht. Ich hab das eingefügt und ne Serielle Ausgabe dann tust Du dir leichter beim debuggen. Und diese 9 sekunden delay's sind keine Gute Idee.

Schau Dir mal blinkWithoutDelay an bzw millis().

int redled = 3;
int yellowled = 4;
int greenled = 5;
int position;

// the setup function runs once when you press reset or power the board
void setup() {
  Serial.begin(9600);
  pinMode (3, OUTPUT);
  pinMode (4, OUTPUT);
  pinMode (5, OUTPUT);

}

// the loop function runs over and over again forever
void loop() {

  position = analogRead(A0);
  position = map (position, 0, 1023, 1, 3); // <- so speicherst Du das in ner Variable
  Serial.print("pos: ");
  Serial.println(position);

  if (position == 1)
  {
    digitalWrite (redled, 1);
    delay(9000); // So einen großes Delay... nogo! aber zum testen ist derweil ok.
    digitalWrite (redled, 0);
  }
  else if (position == 2)
  {
    digitalWrite (yellowled, 1);
    delay (9000);
    digitalWrite (yellowled, 0);
  }
  else
  {
    digitalWrite (greenled, 1);
    delay (9000);
    digitalWrite (greenled, 0);
  }
}

Nachtrag: Das ist eigentlich eine State Machine, also ein endlicher Automat. Hier im Forum steht sehr viel darüber und im Netz sicher auch. Das ist dann der nächste Schritt. Bzw. Ne State Machine ohne delay programmieren.

Nachtrag2 (sorry): Der Variablenamen position wird in der IDE sofort rot, im gegensatz zu qwertz oder blabla. Da sollte schon die Alarmglocken leuten und man den Namen doch lieber ändern. Reference/FilePosition.

Grüße,
Donny

Dony, Danke für Deine Antwort!
Deine Änderung funktioniert und so sehe ich im Serialmonitor auch, wann bei welchen Potentiometereinstellungen welches Signal kommt.
Wie kann ich den Bereich einstellen, da im Moment komplett nach links drehen zwar pos1 ergibt, ein Millimeter nach rechts aber schon pos2. Ideal wäre z.B (bei den Werten 0-1024) 0-340 -> pos1, 341-682 -> pos2, 683-1024 ->pos3

Wegen Deiner Anmerkung betreff delay:

Am Ende möchte ich es ohne delay einsetzen, dachte aber als Beispiel besser verständlich.. (den funktionierenden Code habe ich schon, setze aber im Moment drei verschiedene Arduinos dafür ein (brauche aber je Anwendungsfall nur einen).
Durch das Potentiometer erhoffe ich mir nur noch einen zu benötigen, der für alle drei Anwendungsfälle gerüstet ist...

pos1

 wait.Begin();
rot (2000ul);
gelb (4000ul);
grün (6000ul);
blau (8000ul);
aus(12000ul);

pos2

 wait.Begin();
rot (4000ul);
gelb (6000ul);
grün (10000ul);
blau (18000ul);
aus(120000ul);

pos3

 wait.Begin();
beispiel (2000ul);
rot (4000ul);
grün (6000ul);
blau (8000ul);
aus(12000ul);

Hi,

Du kannst die Position (0-1024) auch direkt, ohne die map-Funktion auswerten.

 if (position >= 0 && position <= 340)
{
...
}

Gruß André

Wie kann ich den Bereich einstellen, da im Moment komplett nach links drehen zwar pos1 ergibt, ein Millimeter nach rechts aber schon pos2. Ideal wäre z.B (bei den Werten 0-1024) 0-340 -> pos1, 341-682 -> pos2, 683-1024 ->pos3

 position = analogRead(A0);
  if(position<=340) position =1;
  if(position >340 && position<683) position = 2;
  if position >=683) position = 3;
  Serial.print("pos: ");
  Serial.println(position);

ardubu:

 position = analogRead(A0);

if(position<=340) position =1;
  if(position >340 && position<683) position = 2;
  if (position >=683) position = 3;
  Serial.print("pos: ");
  Serial.println(position);

DANKE!!!!!!
So ist es sogar auch für mich noch besser, da ich im Notfall auch noch um eine oder mehr Positionen erweitern kann und auch verstehe :wink:
Ich hatte vorher Stunden und Tagelang die Lösung gesucht... Danke Danke Danke!!!

Ich finde, für das Ergebnis von analogRead (0...1023) und die davon abgeleitete Funktion (1..3) dieselbe Variable zu verwenden, ist am falschen Ende gespart. Es funktioniert hier zwar, würde mich aber verwirren.

michael_x:
Ich finde, für das Ergebnis von analogRead (0...1023) und die davon abgeleitete Funktion (1..3) dieselbe Variable zu verwenden, ist am falschen Ende gespart. Es funktioniert hier zwar, würde mich aber verwirren.

Verstehe ich nicht ganz, aber mach gerne einen Vorschlag

Macht es so Sinn?

int redled = 3;
int yellowled = 4;
int greenled = 5;
int position;
int setposition;
// the setup function runs once when you press reset or power the board
void setup() {
  Serial.begin(9600);
  pinMode (3, OUTPUT);
  pinMode (4, OUTPUT);
  pinMode (5, OUTPUT);

}

// the loop function runs over and over again forever
void loop() {

  position = analogRead(A0);
 // position = map (position, 0, 682, 1, 3); // <- so speicherst Du das in ner Variable
  if(position<=340) setposition =1;
  if(position >340 && position<683) setposition = 2;
  if (position >=683) setposition = 3;
  Serial.print("pos: ");
  Serial.println(position);

  if (setposition == 1)
  {
    digitalWrite (redled, 1);
    delay(9000); // So einen großes Delay... nogo! aber zum testen ist derweil ok.
    digitalWrite (redled, 0);
  }
  else if (setposition == 2)
  {
    digitalWrite (yellowled, 1);
    delay (9000);
    digitalWrite (yellowled, 0);
  }
  else
  {
    digitalWrite (greenled, 1);
    delay (9000);
    digitalWrite (greenled, 0);
  }

Det32:
Macht es so Sinn?

Das war nur auf map() bezogen, da Du allerding diese Funktion nicht mehr verwendest ist es hinfällig.

position = analogRead(A0);
setposition = map (position, 0, 682, 1, 3);

In so einem Fall hast Du 2 Variablen und kannst sowohl die gemappte also auch den analogenWert auslesen. Allerdings schließe ich mich hier auch der Meinung an das ein direktes auslesen, ohne map() sinnvoller ist.

Grüße,
Donny

dony:
Das war nur auf map() bezogen, da Du allerding diese Funktion nicht mehr verwendest ist es hinfällig.

Danke!