Umsetzung Potistellung zu PWM Werten, erbitte Hilfe

Hallo,
ich bin zwar ein recht versierter Analog- und Digitalelektroniker, in Sachen "Microcontroller" mache ich aber mit dem Arduino Uno gerade meine ersten Gehversuche. Und schon stolpere ich :slight_smile:

Die Problemstellung:

Ich habe am Arduino an einem Analogeingang ein Poti angeschlossen und an zwei PWM Ausgängen jeweils eine LED (über Vorwiderstände).

Ich möchte nun erreichen, dass beim Drehen des Potis für jede Stellung (0-1023) ein bestimmter, vorgegebener PWM Wert (0-255) ausgegeben wird.
Die LEDs sollen also "kontrolliert" unterschiedlich hell leuchten, wobei ich die erforderlichen Werte dazu in den sketch eintragen will.

Klar ist natürlich, dass bei 1023 Inputwerten und nur 255 PWM Werten einige Inputwerte den gleichen PWM Wert bekommen werden.

Mit meinen diversen if Anweisungen bekomme ich das irgendwie nicht hin, vermutlich mache ich auch einfach nur was falsch. Vielleicht gibt es einen ganz anderen Weg, und es wäre sehr nettl, wenn mir jemand dabei Hilfestellung geben könnte. Im Moment komme ich einfach nicht voran.

Vielen Dank im Voraus!

Hi stringwalker,

willkommen, mach Dich mal mit map vertraut: http://arduino.cc/en/Reference/Map

  1. Sensorwert einlesen
  2. umrechnen auf den gültigen Wertebereich: Sensorwert = map(Sensorwert, 0, 1023, 0, 255);
  3. korrigierten Sensorwert an PWM Ausgang senden

Grüße, Helmuth

edit:

Ich möchte nun erreichen, dass beim Drehen des Potis für jede Stellung (0-1023) ein bestimmter, vorgegebener PWM Wert (0-255) ausgegeben wird.

Du meinst schon linear, oder? Linksanschlag = aus, Rechtsanschlag = maximale Helligkeit? Wo genau ist das Problem?

Hallo Helmut,

vielen Dank für deine schnelle Hilfe!!

Im Moment verstehe ich das zwar noch nicht so richtig, aber wenn ich wenigstens mal weiß, wonach ich suchen muss und wo ich ansetzen kann, dann finde ich es auch heraus.

Mist, dass es schon so spät ist :slight_smile:

Grüße zurück, stringwalker

Dein Programm ist ähnlich. Nur daß Du Werte von 0 bis 255 brauchst und statt den Servo anzusteuern einfach ein analogWrite nimmst.

und an zwei PWM Ausgängen jeweils eine LED (über Vorwiderstände).

sehr Gut!!

Grüße Uwe

Hallo,

hast Du schon entdeckt, dass 255 * 4 = 1020 ist ?

Oder anders ausgedrückt:
Potiwert (0-1023) geteilt durch 4 = PWM_Wert (0-255)
ist eine Lösung die für Anfänger verständlich ist.

Eleganter ist natürlich der Map-Befehl.

Gruss
Kurti

Hallo,

oder einfach 2mal nach rechts schieben (einmal schieben teilt durch 2).

Grüße,
Jürgen

Hallo,
erst einmal herzlichen Dank an alle, die sich hier um mein Anfängerproblem kümmern! Für die Umsetzung eurer Hilfen brauche ich aber noch ein bisschen mehr Zeit und Durchblick.

Helmuth, zu deinem Nachtrag:

Nein, ich will k e i n lineares Potiwinkel-PWM Wert-Verhältnis erhalten.
Ich will eine individuelle PWM Ausgabe erreichen, die jedem Potiwinkel (bzw. mehreren Winkelbereichen) einen von mir vorgegebenen PWM Wert zuordnet. Als Analogelektroniker würde ich sagen: Ein Poti mit einer verbogenen und alles anderen als linearen Kennlinie.

Zum Beispiel:
Eingangswerte 550-700 bekommen PWM Wert 50, 701-720 bekommen Wert 250, 850 bekommt 600 etc.(das sind jetzt nur fiktive Werte zur Veranschaulichung).

Mit dem map Befehl habe ich mich inzwischen befasst, mir scheint aber, er regelt eher die lineare Verteilung der 1024 Eingangswerte des ADC auf die unterschiedlichen Gegebenheiten von Ausgabeobjekten wie LEDs, Servos u.a.

Könnte ich ihn denn auch für meine Anforderungen einsetzen?

Grüße stringwalker

Hallo,

das könntest mit:

if (poti < 250)
{

}
else if (....

usw.

lösen

stringwalker:
Nein, ich will k e i n lineares Potiwinkel-PWM Wert-Verhältnis erhalten.
Ich will eine individuelle PWM Ausgabe erreichen, die jedem Potiwinkel (bzw. mehreren Winkelbereichen) einen von mir vorgegebenen PWM Wert zuordnet. Als Analogelektroniker würde ich sagen: Ein Poti mit einer verbogenen und alles anderen als linearen Kennlinie.

Zum Beispiel:
Eingangswerte 550-700 bekommen PWM Wert 50, 701-720 bekommen Wert 250, 850 bekommt 600 etc.(das sind jetzt nur fiktive Werte zur Veranschaulichung).

Sind denn die Winkelbereiche alle gleich gross und ist das Poti ein lineares?
Falls ja, kannst DU vermutlich die map() Funktion verwenden.
Sagen wir mal Du willst 8 "Schaltzustände" abbilden, dann mappe einfach die Werte 0 bis 1023 auf 0 bis 7 ( int state = map(analogRead(A0),0,1023,0,7); )
Die dabei rauskommenden Werte von 0 bis 7 kannst Du dann z.B. als Index für ein Array verwenden, indem die PWM-Werte stehen.
Oder falls Du mehrere Dinge anhand des Schaltzustandes machen willst:

#define POTI A0
int state = map(analogRead(POTI),0,1023,0,7);

switch(state) {
  case 0:
               //hier alle Befehle für Zustand 0
               break;
  case 1:
               //hier alle Befehle für Zustand 1
               break;
  case 2:
               //hier alle Befehle für Zustand 2
               break;
...
  case 7:
               //hier alle Befehle für Zustand 0
               break;
}

Aufpassen musst Du allerdings an den Übergangsstellen von einem Wert zum anderen. Bei ungünstiger Position des Potis springt der Wert zwischen zwei Zuständen hin und her. Das Problem hatte ich bei meiner Lavalampe auch.

Danke, mkl0815, ich denke, du hast genau erkannt, worum es mir geht.

Die Switch/Case Lösung ist erst einmal durch ihre klare Struktur für mich leichter zu verstehen, und da ich zwei LEDs unterschiedlich mit dem Poti ansteuern will, vielleicht auch die richtige.

Die Lösung mit den Arrays hört sich natürlich schon sehr elegant an, ich fürchte aber, ich könnte sie mit meinem derzeitigen Wissen noch nicht umsetzen. damit befasse ich mich aber unbedingt noch.

Zu deiner Frage nach dem Poti und den Winkelbereichen:

Das Poti wird ein lineares sein, wäre aber im Prinzip auch egal, ich biege mir ja softwaremäßig ohnehin eine eigene Kennlinie zurecht. Ich will 64 Winkelbereiche haben, d.h. jeweils 16 Eingangswerte bekämen gleiche PWM Werte.

Ich hoffe, dass aufgrund dieser hohen Auflösung in Verbindung mit einem guten Poti das Springen zwischen zwei Zuständen nicht so störend sein wird.

Hier auch noch danke an JürgenR für die Idee mit if/ else Lösung.

Ein Anfänger sieht Land ! :slight_smile:

Grüße stringwalker

Wenn ich dich richtig verstehe, dann willst eine Poti kennlinie in eine (beliebige) PWM-Kennlinie umsetzten.

das geht auf alle Fälle mit den oben switch - case methode.

Du kannst aber auch mal nach "lineare Interpolation c++" im I-net suchen.
Das Verfahren wird z.B. verwendet um "krumme" kennlinien von Sensoren, die über Tabellen gegeben sind, in Ausgangswerte umzurechnen. Das läst sich einfach programmieren.
Gunther

Du kannst auch zum umrechnen ein Array definieren wie zB hier vorgeschlagen:

int loga[64] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 16, 18, 20, 22, 25, 28,
30, 33, 36, 39, 42, 46, 49, 53, 56, 60, 64, 68, 72, 77, 81, 86, 90, 95, 100, 105, 110, 116,
121, 127, 132, 138, 144, 150, 156, 163, 169, 176, 182, 189, 196, 203, 210, 218, 225,
233, 240, 248, 255};

int index = map(analogRead(POTI),0,1023,0,63);

int wert = loga[index];

Grüße Uwe

Hey, es funktioniert inzwischen ganz hervorragend!!
Danke an alle, die mir geholfen haben, ohne euch hätte ich es nämlich nicht hingekriegt.

Ich mache es mit der map/switch/case Methode - eigentlich doch ganz easy, wenn man das erst einmal kapiert hat.

Gunther:
"lineare Interpolation c++", danke noch für den Begriff, das ist auch sehr interessant, da tun sich für meine analogen Entwicklungen ungeahnte Möglichkeiten auf.

Uwe:
Ich ahne entfernt, dass sich mit deinem Vorschlag mein Projekt wesentlich weniger aufwändig gestalten würde... :slight_smile:

Jetzt habe ich (klar) auch noch eine Anschlussfrage zu meinem LED Projekt:

Z.Zt. erhalten doch, je nach Potistellung, meine beiden LEDs ihre unterschiedlichen, individuellen PWM Werte. Könnte man nun mit dem Arduino diese Werte mit dem Drücken eines Tasters dauerhaft abspeichern, um sie dann irgendwann durch Drücken eines anderen Tasters wieder an den gleichen Ausgängen auszugeben?

Bin nicht sicher, ob das jetzt hier noch her gehört oder besser in ein neues Thema. In der Suche finde ich nichts Passendes, vielleicht formuliere ich das Problem aber dort auch nur nicht richtig.

Grüße an alle

stringwalker

stringwalker:
Jetzt habe ich (klar) auch noch eine Anschlussfrage zu meinem LED Projekt:

Z.Zt. erhalten doch, je nach Potistellung, meine beiden LEDs ihre unterschiedlichen, individuellen PWM Werte. Könnte man nun mit dem Arduino diese Werte mit dem Drücken eines Tasters dauerhaft abspeichern, um sie dann irgendwann durch Drücken eines anderen Tasters wieder an den gleichen Ausgängen auszugeben?

Ja, kein Problem.
"Dauerhaft" meinst Du auch nach dem Wiedereinschalten des Arduino?

Du kontrollierst den Taster und wen dieser gedrückt wird (zB LOW-HIGH-Übergang) Speicherst Du den Analogwert ab un setzt eine Statusvariable auf 1. Beim Drücken des zweiten Tasters setzt Du die Statusvariable auf 0.
Solange diese Statusvariable 1 ist nimmst Du den gespeicherten Wert ansonsten den gelesenen Analogwert von den Potis.

Falls es Dauerhaft (als auch nach den Ausschalten, Stromausfall) sein soll dann mußt Du die Variablen ins interne EEProm schreiben. http://arduino.cc/en/Reference/EEPROM

Grüße Uwe

Du kontrollierst den Taster und wen dieser gedrückt wird (zB LOW-HIGH-Übergang) Speicherst Du den Analogwert ab un setzt eine Statusvariable auf 1. Beim Drücken des zweiten Tasters setzt Du die Statusvariable auf 0.
Solange diese Statusvariable 1 ist nimmst Du den gespeicherten Wert ansonsten den gelesenen Analogwert von den Potis.

Falls es Dauerhaft (als auch nach den Ausschalten, Stromausfall) sein soll dann mußt Du die Variablen ins interne EEProm schreiben.

Ja, die Werte sollen fest im EEProm gespeichert werden, nicht im RAM.

Ansonsten:
Ich habe jetzt erst einmal verstanden, dass mein Vorhaben mit dem Abspeichern und Reproduzieren der Werte grundsätzlich möglich ist. Sehr gut.
Wie ich das umsetze, was du schreibst, muss ich erst noch lernen, ich verstehe aber schon mal den Ansatz.

Danke Uwe

stringwalker