Forum: Mikrocontroller und Digitale Elektronik Problem mit Joystick an AVR


von tubbu (Gast)


Lesenswert?

Hallo, ich habe meinen Joystick an den A/D Wandler meines uCs
angeschlossen. der Jostick ist intern folgendermaßen verschaltet:
Ein poti mit etwa 100KOhm, der aber nicht als Spannungsteiler
geschaltet
ist, sondern gegen 5V. (Danke liebe Leute, die sich diesen Standart
haben einfallen lassen)

Das bedeutet, dass ich extern einen Spannungsteiler bilden Muss, um
eine Variable Spannung zu erhalten.
Ich verwende Hierzu einen gegen Masse Geschalteten 100K Widerstand.
Ich hoffe auf dem "Bild" kann man was erkennen.

5V
 |
| |Widerstand im Joystick
| |---|----------> Zum A/D Wandler
| |  | |
 |   | |  Mein Widerstand (100K)
     | |
      |
      GND

Ich bekomme also eine Spannung zwischen 5 und 2,5 Volt.
Allerdings ist die Abhängigkeit nicht linear.
Ich bräuchte also einen Algorithmus, der das irgendwie ausgleicht.
Hab mir schon ansatzweise Gedanken gemacht, mir ist aber nichts
gescheites eingefallen.

Die Spannung am Wandler lässt sich jedenfalls durch die Gleichung

U= 100K * 5V
   ---------
   R1  + 100K

Beschreiben.

kann ich jetzt, wenn ich den Wert am A/D Wandler ablese, über die
Gleichung

R1 = 100K *5V
     -------- - 100K
        U

Auf den ursprünglichen Widerstandswert zurückschliessen?

Soweit so gut (danke, dass du bis hierhingelsen hast).

Leider verwenden die meisten Joysticks nciht den ganzen bereichen des
Potis. Die meisten haben soger noch eine Stellschraube o.Ä. pro Poti um
den verwendeten Bereich zu verschieben.
Und an dieser Stelle weiß ich jetzt wirklich nciht mehr weiter.
Wie kann man das miteinbeziehen?
Bei der Kalibration könnte man die Maximal-, die Minimal- und die
Mittelstellung abfragen.

Kann mir da jemand weiterhelfen?

Danke schonmal

von ...HanneS... (Gast)


Lesenswert?

Hi...

Tja, analoge PC-Joysticks wurden zum Ansteuern von (Vierfach-) 555ern
konstruiert, also als R für das RC-Glied. Daher diese doofe Schaltung.

Was hältst du von einer Tabelle im Flash, mit der du die gemessenen
Werte (am besten nur 8 Bit) umsetzt?

...HanneS...

von tubbu (Gast)


Lesenswert?

Nicht so viel, da es sicherlich relativ aufwendig wäre, diese Tabelle zu
erstellen.
Zudem müsste man sie jedesmal, wenn man den Joystick wechselt neu
ausmessen + anlegen.
Das ist nicht gerade anwenderfreundlich ;-)

4-Fach 555 will ich mir eigendlich auch nicht umbedingt antun

von Andi (Gast)


Lesenswert?

Ähm, hat das Poti im Joy nicht 3 Pins oder sind nicht alle 3 Pins
verlötet?
Ich denke da an Plus an den einen, minus an den anderen und den
Schleifer als Ausgang.
Wenn das so verschaltet ist, dann ist das Poti doch schon ein variabler
Spannungsteiler.
Mit dem 100K-Widerstand beeinflußt Du dann die Ausgangsspannung so, das
die Ausgangsspannung bei wenig Widerstand am Schleifer des Potis weniger
beeinflußt wird und bei hohem Widerstand des Schleifers eben mehr.
Dadurch vielleicht dann das nicht lineare?

Gruß
Andi

von tubbu (Gast)


Lesenswert?

Nein, an dem Poti ist eben nur 5V und der Schleifer angeschlossen.
Ich möchte das ganze eben gleich so konzipieren, dass man jeden
beliebigen Joystick anschliessen kann, den kurz kalibrieren (mit einer
taste) und los gehts.


Btw.: Weiß jemand, oder hat jemand einen Link für das Protokoll von
digitalen Potis (Sidewinder, etc)?

von Tassilo (Gast)


Lesenswert?

Hi,

leg halt 100K in die 5V ub!? - Geht das nicht??

LG
Tassilo

von tubbu (Gast)


Lesenswert?

> leg halt 100K in die 5V ub!? - Geht das nicht??

ähm, hab ich jetzt nicht so ganz verstanden, was du meinst...:-)

von Alexander Höller (Gast)


Lesenswert?

Hey tubbu!

du hast als fixe Größen:

.) die Spannung über den fix Wid. (100k) - gemessen mim ADC
.) den fix. Wid. (100k)
.) die Spannung über beide Wid. - 5V

Was du suchst is nur der var. Widerstand.


Spg. über var. Wid. = 5V - Spg. über fix. Wid.

Spg. über var. Wid / Spg. über fix Wid. = var. Wid / fix. Wid.

-->

var. Wid = (Spg. über var. Wid. * fix Wid.) / Spg. über fix Wid.


----------

Zum Kalibrieren kannst du dir dann die beiden Endpunkte ausmessen. Und
der Wid. zwischen den beiden Punkten ändert sich ja direkt prop. zur
Joystick Stellung - musst also nichts linearisieren!


mfG
aleX

von Alexander Höller (Gast)


Lesenswert?

Weil da sganez bissal überübersichtlich geworden ist (g) ein kleines
Rechenbeispiel:

Var Wid. = 50k
-> Spg. über var. Wid = 1,666V

5V - 1,666V = 3,334V

Rvar = (1,666V * 100kOhm) / 3,224V

Rvar = 51,67kOhm


der Fehler von 1,67kOhm liegt wohn an den Rundungsfehlern ;p


mfG,
aleX

von Alexander Höller (Gast)


Lesenswert?

Hmm ... hab bei dem Rechenbeispiel die Spannung über den var. Widerstand
als gegeben angenommen ... das is natürlich flasch ... aber die nicht
gemessene Spannugn musst du eben asurechnen - is eigentlcih ja egal wo
du misst!

mfG,
aleX

von Tobi T. (tubbu-)


Lesenswert?

Hi, ist schon etwas länger her, dass ich obigen Algorithmus
implementiert habe, aber irgendwie hat er nie richtig funktioniert.
Kürzlich ist mir auch eingefallen warum.
Der Grund ist/war, dass ein Joystick nie den gesammten Bereich des
Potis ausnutzt, sondern immer nur einen Teil. Dadurch hat die Gleichung
nie etwas wirklich lineares zurückgeliefert.

Der Schaltplan müsste also eigendlich so aussehen: R1 und R2 Bilden den
Poti im Joystick nach, R3 ist der 100K Widerstand, R1 ist der Bereich
des Potis, der nicht genutzt wird.

    VCC
     +
     |
     |
    .-.
    | |
    | | R1
    '-'
     |
     |
    .-.
 R2 | |<--|---|Out
    | |   |
    '-'   |
     |    |
          |
          |
          |
          |
     | ---|
    .-.
    | |
R3  | |
    '-'
     |
     |
    ===
    GND
(created by AACircuit v1.28.6 beta 04/19/05 www.tech-chat.de)

Um den Wert von R2 zu erhalten muss man das System erst kalibrieren.
Dazu bewegt man den Joystick im gesammten Bereich und speichert den
größten und den kleinsten gemessenen Spannungswert. Der größte
Spannungswert entspriht einenm R2 von 0.

Man kann also folgende Formel anwenden:

R1 = R3* (5V - Umax) / Umax

Jetzt hat man R1 in Abhängigkeit von R3.
Dieser Wer wird jetzt in Folgende Formel eingesetzt, um den aktuellen
Wert von R2 zu erhalten:

R2 = (R3 - Ugemessen*(R1 + R3)) / Ugemessen

Wenn ich das ganze richig hergeleitet habe, dann erhalte ich nun einen
Wert, der proportional zur Joystickstellung ist.

Nun Setzt man in die Gleichung Umax und Umin ein und erhält somit einen
Wertebereich innnerhalb dessen sich der Joystick bewegt.
Diesen kann man dann auf den gewünschten Wertebereich (z.B. 8Bit)
transformieren.

-------------------

Soweit so gut, mein Vorschlag. Ich habe keine Ahung, ob das ganze
richtig ist, der Grund ist unter Anderem der, dass ich keine Ahung
habe, wie ich das ganze effizient implementieren soll (muss ich
wirklich float verwenden?)

Ich hoffe der obige Text ist einigermaßen verständlich

Vielleicht kann sich irgendjemand meinen Vorschlag mal anschauen und
verbessern, wäre sehr nett, danke.

von Sebastian Voitzsch (Gast)


Lesenswert?

Hallo,

wo ist denn das Problem? Bei der Kalibrierung wird Max, Min und 0
abgefragt. Dann ist der aktuelle Wert

pos = (adc - min) / (max - min)

adc ist der vom AD-Converter ermittelte Wert. Pos ergibt einen Wert
zwischen 0 und 1 als Bruchteil der Stellung (Mitte: 0,5, Max = 1, Min =
0). Wenn Du´s auf eine andere Bezugsgröße haben willst, einfach damit
multiplizieren:

pos = ((adc-min) / (max-min)) * 100

gibt 0 <= pos <= 100. 0 ist min, 100 ist max.

Den Nullpunkt würde ich dann bei der Auswertung berücksichtigen und
z.B. den Bereich zwischen 0,4 und 0,6 als "null" werten, wenn der
gemessene Wert bei 0.5 liegt. Damit wird der Nullpunkt stabiler und Du
vermeidest ein Zittern durch das Rauschen des Potis.

Sebastian

PS: Achte auf die Klammern beim Programmieren, Punkt vor Strich!!

von Tobi T. (tubbu-)


Lesenswert?

Das Problem ist, und das habe ich schon weiter oben erwähnt, dass die
gemessene Spannung am ADC NICHT linear proportional zum Wert des Potis
ist.

Die Spannung über R3 errechnet sich nämlich wie folgt:

U = Uges * (R3 / (R1 + R2 + R3)

Es muss also eine linearisierung vorgenommen werden.
Die obigen Gleichungen sollen dies erreichen.

Die Algorithmus, den du gepostet hast ist im Prinzip das, was ich mit

>Nun Setzt man in die Gleichung Umax und Umin ein und erhält somit
>einen Wertebereich innnerhalb dessen sich der Joystick bewegt.
>Diesen kann man dann auf den gewünschten Wertebereich (z.B. 8Bit)
>transformieren.

umschrieben habe und ist ganz sicher der einfachste Teil der ganzen
Berechung.

PS.: Wo bitte habe ich keine Klammern gesetzt, oder Punkt vor Strich
nicht beachtet?

von Hannes L. (hannes)


Lesenswert?

Das erste Problem wird wohl sein, dass der ADC zuwenig Auflösung hat.
Also dass der minimal und maximal erreichbare Wert (Spannungsteiler mit
PC-Joystick und Widerstand oder Konstantstromquelle) zu dicht
beieinander liegt.

Sollte das nicht der Fall sein, also sollte dir die Anzahl der Stufen
reichen, dann bietet sich eine Tabelle im Flash an (Anzahl der Einträge
entspricht Anzahl der verfügbaren Stufen, als Inhalt den gewünschten
Wert). Dies erfordert zwar etwas Flash, erspart aber die
Rechenfunktionen.

Wenn es nicht unbedingt ein (formschöner) PC-Joystick sein muss:
Es gibt beim blauen C und bei www.mikroantriebe.de (oder so ähnlich,
mal googeln) Mini-Kreuzknüppel, deren Potis als Spannungsteiler von
Anfang bis Ende reichen. Damit erreicht man ganz einfach den gesamten
Bereich des ADC, und das sogar halbwegs linear.

Muss es unbedingt der PC-Joystick sein, dann würde sich eine
Timerschaltung mit NE556 anbieten, wie sie auch im PC verwendet wird
(dort aber mit 4-fach-555). Statt ADC wird dann die Impulsbreite der
Timer gescannt.

...

...

von Karl heinz B. (heinzi)


Lesenswert?

Ich hab deine Formeln mal im Excel durchgespielt.

Mit angenommenen 10k fuer R1
sieht es so, aus, dass du die groesste Spannungsdifferenz
bei R3 = ~65k erreichst. Das sind dann ca 1.73V
im Bereich von ~2.1V bis 3.8V (bei 5V Versorung des Joysticks)

von Tobi T. (tubbu-)


Lesenswert?

Das Ziel war handelsübliche Joysticks anschliessen zu können, weshalb
alternative Lösungen wegfallen.

Auch soll jeder Joystick (nach einer Kalibration) funktionieren,
weshalb  die Lösung mit einer Tabelle nicht Möglich ist (oder hab ich
das falsch verstanden)

So eine Timerschaltung währe tatsächlich eine Möglichkeit, an die aich
auch schon gedacht, aber wieder verworfen habe, da sich dadurch
zusätzliche Bauelemente ergeben. Solange man etwas in Software lösen
kann, würde ich das auch gerne machen.

achja, ich brauche die Joystick Position in relativ geringer Auflösung,
geht man davon aus, dass R3 und (R1 + R2) in etwa gleich sind (und das
sind sie in etwa, dann liegt der Bereich der Messwerte ETWA zwischen
512 und 1023, reel wahrscheinlich etwas unter 9 Bit, das sollte
ausreichend sein.

Ich finde es nur etwas unpraktisch, dass ich die Gleichungen als float
implementieren muss, damit ich eine ausreichende Genauigkeit erhalte (
hab da schon etwas rumprobiert und habe es nciht geschafft mit 16Bit
integer auszukommen)

Aber vieleicht kennt da jemand einen Weg das in 16Bit zu bekommen....

thx

von Tobi T. (tubbu-)


Lesenswert?

@Karl Heinz

du hast natürlich Recht, ich hab grad geschrieben, während du gepostet
hast....

von Karl heinz B. (heinzi)


Angehängte Dateien:

Lesenswert?

Uebrigens:
Ganz sooo schlimm ist die Nichtlinearitaet gar nicht.
Aber mach dir selbst ein Bild

von Sebastian Voitzsch (Gast)


Lesenswert?

Der benutzte Bereich - und damit die Werte von R1 und R3 haben absolut
nichts mit der Linearität der Spannungsänderung zu tun. Wenn wir von
Uges = 5V ausgehen, bestimmen R1 und R3 nur, ob sich die Spannung
zwischen 0V und 5V oder zwischen 3V und 4V bewegt. Diese Offsets werden
mit min und max in der Gleichung berücksichtigt.

Ob die Änderung linear erfolgt, hängt einzig vom verwendeten Poti ab.
In meiner Formel bin ich von einem linearen Poti ausgegangen. Solltest
Du ein logarithmisches verwenden, sollte man für die Umrechnung des
pos-Wertes tatsächlich eine Tabelle verwenden, um sich die Hantiererei
mit log-Funktionen zu ersparen. Diese ist auch fix, da pos in jedem
Fall zwischen 0 und 1 liegt. Allerdings verwenden Joysticks lineare
Potis - logarithmische werden z.B. für Lautstärkeregelungen verwendet.

Wenn allerdings Dein ADC nicht linear (genug) arbeitet, mußt Du sowieso
erstmal dessen Kennlinie herausfinden, um sie entsprechend
berücksichtigen zu können. Vielleicht hast Du aber auch ganz einfach
ein Problem mit der Spannungsversorgung oder mißt andere Störungen, die
Du als mangelnde Linearität wertest.

Der Hinweis auf Punkt vor Strich bezog sich nur auf die Umsetzung im
Programm, dabei geht mir zumindest sowas schnell mal daneben, und ich
suche dann ewig nach dem Fehler.

Sebastian

von Tobi T. (tubbu-)


Lesenswert?

Sebastian,

einer von uns beiden hat irgendwas nicht verstanden.

Schau dir nochmal den Schaltplan genau an, der Poti ist nicht als
einfacher Spannungsteiler geschaltet, da dies aufgrund der Kontruktion
eines Joysticks nicht Möglich ist.

Deshalb gilt für die gemessene Spannung die Gleichung (steht aber auch
oben):

U = Uges * (R3 / (R1 + R2 + R3))

Siehe "unbelasteter Spannungsteiler"

von Hannes L. (hannes)


Lesenswert?

Wenn man den Joystick (statt Spannungsteiler) an eine
Konstantstromquelle anschließt, dann dürfte die Kennlinie linear
werden. Man kann den Strom so einstellen, dass in Mittelstellung etwa
die Mitte des ADC-Bereichs erreicht wird (128 bei 8-Bit ADC).

Für die Konstantstromquelle benötigt man aber eine höhere
Betriebsspannung als 5V. Daher sollte der ADC-Eingang mit einer
zusätzlichen Z-Diode und einem Vorwiderstand geschützt werden.

...

von Tobi T. (tubbu-)


Lesenswert?

@karl heinz

du hast recht, im exel sieht das wirklich nicht besonders unlinear aus,
aber ich hab das am anfang auch mal ohne linearisierung ausprobiert und
es hat sich schon merklich geäussert.

von Sebastian Voitzsch (Gast)


Lesenswert?

Arrggghhhh....

ich Depp habe natürlich übersehen, daß sich der Gesamtwiderstand eben
auch ändert...

Für R1 komme ich auch auf R3(Uges * Umax) / Umax.

Allerdings ergibt sich bei mir für R2:

R2 = R3 * Uges / Umess - R3 - R1

Ich habe die Werte in einer Tabelle durchgespielt und mal auf 2
Nachkommastellen begrenzt. Wenn man dann auf ganze Werte rundet,
bekommt man immer die Ausgangswerte - das wäre in Deinem Fall
kOhm-genau. Dann kannst Du mit long int rechnen und vor der Berechnung
jeden einzelnen Wert mit 100 multiplizieren - das Ergebnis dann
natürlich durch 100 teilen.

Sebastian

von Tobi T. (tubbu-)


Lesenswert?

@HanneS

Die Idee mit der Konstantstromquelle finde ich gut, ich habe aber nur
5V zur Verfügung, aber das sollte doch zur Not ausreichen. Wieso
benötigen Konstantstromquellen denn eine höhere Spannung?

Der Widerstand in einem Joystick hat 100K, dass heisst man müsste die
Stromquelle auf 0,05mA einstellen, damit man alle Werte zwischen 0 und
5V erhält, oder?


@Sebastian

Deine Gleichung ist eigendlich die gleiche, wie meine oben, nur
umgeformt ;-)

long hat ja 32 Bit und wie gesagt 16 Bit sind nicht genau genug.
float hat auch 32 Bit.
Gibt es einen Geschwindigkeitsunterschied zwischen der Berechnung mit
long und der mit float?

von Hannes L. (hannes)


Lesenswert?

>schnipp
Der Widerstand in einem Joystick hat 100K, dass heisst man müsste die
Stromquelle auf 0,05mA einstellen, damit man alle Werte zwischen 0 und
5V erhält, oder?
schnapp<

Du kannst den Widerstand nicht ja bis auf 0 Ohm reduzieren
(Vorwiderstand am Poti, Vorwiderstand am Schleifer).
Also geht die Spannung auch nicht bis 0V herunter.
Vernünftig wäre ein Abgleich, der bei Mittelstellung des Joysticks 2,5V
am ADC ergibt (bei 5,0V Vcc). Dann hast du nach oben und unten den
gleichen "Hub".

>schnipp
Wieso benötigen Konstantstromquellen denn eine höhere Spannung?
schnapp<

Die Konstantstromquelle soll den Strom konstant halten, auch wenn sich
der (Last-) Widerstand ändert. Dazu muss sich ja der Spannungsabfall
der Konstantstronquelle ändern.
Als "Stromsensor" nutzt eine (Transistor-) Konstantstromquelle den
Emitterwiderstand bzw. den Spannungsabfall darüber. Als Referenz dient
eine Z-Diode zwischen Basis und Bezugspotential (in diesem Falle +).
Damit noch etwas Regelbereich bleibt, muss die Spannung um mindestens
Z-Spannung + Basis-Emitter Spannung + etwas Reserve höher sein, als die
höchste zu erwartende Spannung am Lastwiderstand. Mit 10 bis 12V würde
das gut klappen.

Die Stromquelle besteht aus
- PNP-Transistor,
- Z-Diode 3V9...5V1 (bei 12V) zwischen +12V und Basis,
- Widerstand (hochohmig) zwischen Basis und GND,
- Widerstand (niederohmiger) und Trimmpoti (in Reihe) zwischen +12V
  und Emitter.
Der Joystick wird dann zwischen Kollektor und GND geschaltet, Kollektor
geht dann über einen Schutzwiderstand an den ADC. Ein Kondensator von
10nF zwischen ADC und GND stabilisiert den Wert während der
kurzzeitigen Belastung durch die Sample&Hold-Schaltung des ADC.


...

von TravelRec. (Gast)


Lesenswert?

Was wäre denn jetzt, wenn man sich einen R/C-Timer am µC nachbildet,
indem man über einen Portpin einen bekannten C nach Masse anschließt.
Man schaltet den Portpin auf Low und entläd den C, dann schaltet man
den Portpin auf Eingang und wartet und zählt dabei eine Variable hoch,
bis der Pin High wird. Interrupt-Pins eignen sich dazu hervorragend
(beim ATTiny2313 z.B der komplette PortB). Dann braucht man keinen A/D,
lediglich einen Timer, eine schnucklige ISR und ein paar Kondensatoren
(pro abgefragtes Poti 1x).

von Karl heinz B. (heinzi)


Lesenswert?

> Deine Gleichung ist eigendlich die gleiche, wie meine oben, nur
> umgeformt ;-)

Yep. Nur hast Du die Gesamtspannung unter den Tisch fallen
lassen. Ist aber kein grosses Problem.

> long hat ja 32 Bit und wie gesagt 16 Bit sind nicht genau genug.
> float hat auch 32 Bit.
> Gibt es einen Geschwindigkeitsunterschied zwischen der Berechnung
> mit long und der mit float?

Aber massig!
float ist eine andere Welt.

von Sebastian Voitzsch (Gast)


Lesenswert?

Moin,

also das

R2 = (R3 - Ugemessen*(R1 + R3)) / Ugemessen

ist mit Sicherheit nicht gleich diesem hier

R2 = R3 * Uges / Umess - R3 - R1

Einfach daran zu sehen, daß bei Dir immer negative Werte rauskommen -
Ugemessen*(R1+R3) wird immer größer als R3 sein.

Interger-Berechnungen sind immer schneller als Float. Nicht zuletzt
deshalb, weil float ja per Software gemacht wird - die AVRs haben
schließlich keinen math. Coprozessor.

Mit 2 Nachkommastellen bekommst Du den Widerstandswert kOhm-Genau. 100
Schritte pro Achse - das reicht nicht? Und der ADC wird wohl auch auf
10mV genau sein...  Was willst Du mit einer 16Bit-Joystick-Position?

Wenn der verwendete AVR einen Komparator mit int. Referenz hat, gibts
noch eine Möglichkeit: Poti direkt an den Komparator-Eingang, einen
100nF-Folien*(!)-kondensator über 1K vom Eingang nach Masse.

Zur Messung schaltest Du den Eingang als Ausgang und legst ihn auf low
für ein paar ms (=Kondensator entladen). Dann beschaltest Du ihn als
Eingang ohne Pullup und mißt die Zeit, bis der Kondensator auf 1.1V
geladen ist (also das Komparator-Flag gesetzt ist). Diese Zeit steigt
proportional zum Widerstand.

Das ist so genau, daß es bei mir zum Auswerten des Ladezustandes eines
LiIon-Akkus reicht(4.2-2.9V). Für 0-5V beim 100k-Poti sollte das locker
reichen.

Grüße,
Sebi

*Folie ist wichtig wegen der Temperaturkonstanz!

von Sebastian Voitzsch (Gast)


Lesenswert?

TrevelRec:

da hab´ ich wohl zu lange zum Schreiben gebraucht ;-)

Mit einem normalen Portpin wird das sehr ungenau, weil Du nie weißt, ob
der jetzt bei 3.4V, 3.8V oder erst 4.2V "high" erkennt. Du mußt aber
einen präzisen Referenzpunkt haben.

Sebi

von TravelRec. (Gast)


Lesenswert?

Ja, mag sein ;-), Komparator ist schon genauer - jetzt wo Du´s sagst. Da
bekommt man ja auch ´nen schönen Interrupt. Wenn man mehr Pins braucht,
kann man ja mit externen Komparatoren (OVs) an die Pins gehen. Ist
jedenfalls einfacher, als sich mit der Programmierung die Finger zu
brechen...

von Karl heinz B. (heinzi)


Lesenswert?

> also das
>
> R2 = (R3 - Ugemessen*(R1 + R3)) / Ugemessen
>
> ist mit Sicherheit nicht gleich diesem hier
>
> R2 = R3 * Uges / Umess - R3 - R1

Die exakte Formel 1) lautet

R2 = (R3*Uges - Umess*(R1+R3)) / Umess

wenn Du das ein bischen umformst, kommt Formel 2) raus

von Tobi T. (tubbu-)


Lesenswert?

Das mit dem Portpin laden und entladen hab ich ganz am Anfang auch mal
probiert.
Es hat entweder viel zu lange gedauert, oder war viel zu ungenau, je
nachdem, wie groß ich den Kondensator gewählt habe.

Ich bin bei meiner Formel davon ausgegangen. dass U=1, statt 5 ist,
deshalb sieht sie anders aus.

@Sebastian
Ich brauche keine 16Bit Joystick Position, tatsächlich brauche ich nur
eine 7-Bit Joystickposition. Während der Berechung mit 16Bit treten
aber massig Rundungsfehler auf, vorallem an Stellen in der Berechung,
an denen Division durchgeführt wird.
Zudem muss man bei einer Multiplikation darauf achten, dass die 16it
nicht überschritten werden, man kann eben nicht einfach zwei 16Bit
Zahlen miteinander multiplizieren.


@HanneS:

man kann ja eine Stromquelle auch aus einem FET und einem Widerstand
bauen. Muss hier die Spannung auch (deutlich) höher liegen?


Danke euch

Tubbu

von Hannes L. (hannes)


Lesenswert?

> man kann ja eine Stromquelle auch aus einem FET und einem Widerstand
> bauen. Muss hier die Spannung auch (deutlich) höher liegen?

Im Prinzip ja...

Man könnte aber mal Folgendes probieren:

- Als Referenz die interne Referenz (etwa 2,56V) verwenden.
- Damit muss der Stron so gewählt werden, dass die Spannung am in
  Mittelstellung stehenden Joystick etwa 1,28V beträgt (50% ADC).
- Statt der Z-Diode (am PNP-Transistor) eine LED mit 2V
  Spannungabfall einsetzen. Eine LED reicht für mehrere Transistoren,
  sie dient ja nur als konstante Referenzspannung.
- Den (trimmbaren) Emitterwiderstand so dimensionieren, dass sich
  der gewünschte Strom einstellt. Es müssten etwa 1,5V daran abfallen.


Das könnte geradeso noch mit 5V funktionieren...

Da ich kein "Joysticktomteur" bin, habe ich mit den Dingern wenig
Erfahrung. Ich besitze zwar welche, die wurden aber kaum benutzt.

Ich weiß daher nichtmal, wie stark sich der Widerstand (von Endanschlag
zu Endanschlag) ändert, ich weiß nur, dass die Fertigungstoleranzen
enorm sind.

Denn wir hatten anfang der 90er Jahre arge Probleme mit der
Kalibrierung, als wir PC-Joysticks an die Analogeingänge des
C64-Soundchips (SID) anschlossen. Der Soundchip war mittels
Erweiterungskarte (Eigenentwicklung eines Freundes) in das System des
Commodore Plus/4 eingebunden, wo er nun eigentlich garnicht hingehört.
Eigentlich funktionierte das gut, nur bei jedem Joystickwechsel wurden
andere Werte eingelesen. ;-(

...

von A. D. (ad1)


Lesenswert?

Also in meinem USB-Joystick-Adapter habe ich das so gemacht:
-Beschaltung genau so wie in Deinem ersten Beitrag + 100nF parallel zu
den 100k
-Einlesen der Spannung mit 10bit AD-Wandler ==> x = 0..1023
-Limiter bzw. Erkennung ob Joystick angeschlossen:
 wenn (x<256) dann kein_Joystick_angeschlossen,
 sonst x = max( 512, x ) - 512   (jetzt ist x = 0..511)
- x addressiert eine Tabelle mit 512 Einträgen, die ich mit Matlab
folgendermaßen erzeugt habe (sollte aber auch für nicht Matlab-Kenner
verständlich sein). Ziel ist, die Poti-Stellung aus der Spannung zu
ermitteln.
------------- Matlab-Code ------------------------
x = [0:511];
y = (1024./(x+512)-1)*254 - 127;
y_int8 = floor( y + 0.5 );
y_int8 = min( 127, max( -127, y_int8 ) );
for (n=1:64)
   fprintf(1,'.db %5i, %5i, %5i, %5i, %5i, %5i, %5i, %5i\n', y_int8(
(n-1)*8 + [1:8] ));
end
--------------------------------------------------
Der Zurückgewonnene Wert y_int8 liegt jetzt zwischen -127 und +127 und
ist linear zur Potistellung. Bei mir wird jetzt der Rest
(Mittelpunktsstellung, Aussteuerung)vom Betriebssystem gemacht.

Wenn Du jetzt diesen Wert entsprechend mit Offset skalierst, sollte das
auch mit 16bit-Integer-Arithmetik gut funktionieren.

Gruß, Andreas

von Sebastian Voitzsch (Gast)


Lesenswert?

Tobi:

Du bekommst genau an einer Stelle den Rundungsfehler - eben bei der
Division. Wie ich oben geschrieben und per Tabelle nachgerechnet habe,
wirkt der sich erst in der ersten Nachkommastelle des Poti-Wertes aus -
also nicht, weil man das Poti sowieso nur "ungenauer" einstellen
kann.

Wegen der 16Bit-Multiplikation sollst Du ja mit long int rechnen - das
ist 32 Bit lang und verkraftet das Ergebnis locker.

Zur anderen Methode: um einen 100nF-Kondensator per 100k-Widerstand zu
laden, benötigt man 0.05 Sek. Dazu kommen 1-2ms zum Entladen des
Kondensators, Timer auslösen etc. Sagen wir also max. 100ms. Für welche
Bewegung ist das denn nicht schnell genug? Gegen die Ungenauigkeit hilft
vor allem der richtige Kondensator, s.o.
b.t.d.t.

Sebastian

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.