Go Down

Topic: Potentiometer auf unterschiedlichen Positionen unterschiedliche Funktionen (Read 326 times) previous topic - next topic

Det32

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...):

Code: [Select]
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!!!

dony

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().

Code: [Select]
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
Newsticker:
Die Änderung meines Abschied Grußes ist Teil meiner Corporate Identity/Design Anpassung.

Det32

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

Code: [Select]

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


pos2

Code: [Select]

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


pos3

Code: [Select]

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

SpaghettiCode

Hi,

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

Code: [Select]
if (position >= 0 && position <= 340)
{
...
}



Gruß André

ardubu

Quote
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
Code: [Select]
 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);

Det32

Code: [Select]
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 ;-)
Ich hatte vorher Stunden und Tagelang die Lösung gesucht... Danke Danke Danke!!!

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.

Det32

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

Det32

Macht es so Sinn?
Code: [Select]
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);
  }

dony

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

Code: [Select]

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
Newsticker:
Die Änderung meines Abschied Grußes ist Teil meiner Corporate Identity/Design Anpassung.

Det32

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

Go Up