Forum: Mikrocontroller und Digitale Elektronik Umrechnung von ADC-Werten


von Hendrik M. (nicksput)


Lesenswert?

Hallo zusammen,

nachdem mir hier das letzte mal so schnell geholfen wurde, hoffe ich 
auch dieses mal auf Euren professionellen Input.

Ich bin nach wie vor dabei ein Steuerungstestgerät zu bauen und zu 
programmieren. Das Ganze basiert auf einem PIC18F23K20 und ich 
programmiere in C da mir offensichtlich die Gene fehlen, die für die 
ASM-Programmierung nötig sind.

Nachdem inzwischen technisch alles zu funktionieren scheint, habe ich 
jetzt eine eher mathematische Frage. Ich verwende ein lineares Trimmpoti 
(10kOhm) an einem analogen Eingang und möchte in einem Programmschritt 
eine Zeit zwischen 0 und 60 Sekunden einstellen können. Hier der Code:
1
case start:
2
  initADC();    // AD-Wandler initialisieren
3
  SetChanADC(11);           // Kanal einstellen, der für die
4
        // AD-Wandlung verwendet werden soll
5
  ConvertADC();    // Startet die Wandlung
6
  while (BusyADC());  // Warten, bis Wandlung beendet ist
7
  result = ReadADC();  // Auslesen des AD-Wertes
8
  CloseADC();    // AD-Wandler ausschalten
9
10
         // Wartezeit ganzzahlig berechnen:
11
12
  wartezeit=(int)(result/(1024/60));
13
         
14
         // ganzzahligen Rest der Division ermitteln:
15
16
  sekunden_einer=wartezeit%10;    
17
18
         // Zehneranteil der Sekunden ermitteln:
19
20
         sekunden_zehner=((wartezeit-sekunden_einer)/10);  
21
  break;

Die einer/zehner-Geschichte hängt mit der 4x7-Segment-Anzeige zusammen 
auf der ich das ausgebe.

Jetzt habe ich das Problem, dass sich das Ganze alles andere als linear 
verhält. Die kleinen Werte sind mit menschlicher Motorik kaum 
einzustellen.

Gibt es eine bessere Möglichkeit die ADC-Ergebnisse in 60 
Sekundenschritte einzuteilen?

Ich bin um jeden Tipp dankbar!

Hendrik

von Helmut S. (helmuts)


Lesenswert?

Mach die Kennlinie quadratisch.

x = adc_wert/1023

x = x*x

Wartezeit = x*60

Damit geht x immer noch von 0 bis 1. Bei 10% am Eingang bekommst du dann 
x=0,01. Das ergibt dann am Ende 0,6s. Wie du siehst hast du damit eine 
sehr angenehme Auflösung im unteren Sekundenbereich.

von Karl H. (kbuchegg)


Lesenswert?

Quadratische Kennlinie ist eine gute Idee.

Allerdings orte ich beim TO noch ein Missverständnis bezüglich 
Datentypen

>  wartezeit=(int)(result/(1024/60));
>  sekunden_zehner=((wartezeit-sekunden_einer)/10);


beides weißt darauf hin, dass du der Ansicht bist, dass hier Kommazahlen 
im Spiel sind.

Das sind sie nicht!

1024/60 ist gleichwertig zu 17.
Und zwar zur ganzen Zahl 17 und nicht etwa zu den rechnerischen 
17.066666

Und aus dem gleichen Grund brauchst du auch die sekunden_einer nicht 
abziehen. Denn 23 / 10 ergibt 2. Und zwar 2 gerade aus.

Da wird nichts mit Kommazahlen gerechnet. Links von der Division steht 
ein Integer. Rechts von der Division steht ein Integer. Und damit wird 
die Division selbst als Integer Division ausgeführt und liefert auch ein 
Integer Ergebnis.

Wenn du da eine Fliesskomma-Division erzwingen willst, dann musst 
mindestens einer der Teilnehmer an der Division eine Fliesskommazahl 
sein. Daher wirst du zum ändern der Kennlinie hier

   x = x / 1024.0;

entweder x oder die 1024 zu einer Gleitkommazahl (float oder double) 
machen müssen. Ein einfacher

   x = result / 1024;

reicht da nicht. Denn result ist ein Integer und 1024 ist ein Integer. 
Ergo wird eine Integer Division gemacht und die liefert in deinem Fall 
dann immer 0.

Also darauf achten! Datentypen können enorm viel ausmachen.


Die andere Frage ist es, wie schlau es ist, für derartige Dinge mit 
vielen vom Benutzer zu unterscheidenden und einstellbaren Abstufungen 
ein Poti als Eingabeinstrument zu nehmen. Da eignen sich Drehencoder, 
die man dann auch ein paar mal rundum drehen kann und die eine deutliche 
Rastung besitzen, viel besser. Zusammen mit einer 
Geschwindigkeitssteuerung (wird schnell gedreht, dann erhöht/erniedrigt 
sich der Wert nicht um 1 sondern beispielsweise um 5) ist das eine sehr 
komfortable Möglichkeit der Eingabe.

von Hendrik M. (nicksput)


Lesenswert?

Hallo da draußen,

ich bin immer noch beeindruckt wie schnell man hier im Forum kompetente 
und ausführliche Antworten bekommt. Vielen Dank!

Dass ich hier immer mit ganzzahligen Ergebnissen gerechnet habe, ist mir 
in der Tat nicht bewusst gewesen.
Einen Drehencoder kannte ich bisher noch gar nicht, das werde ich mir 
auf jeden Fall mal ansehen. In diesem Fall übernimmt das Poti allerdings 
noch ganz andere Funktionen und ich will es für ein paar Einstellungen 
einfach "missbrauchen". Ich werde mal die Quadriervariante versuchen und 
Bericht erstatten.
Nochmal vielen Dank für die Mühe!

von Philipp K. (numeriusnegidius)


Lesenswert?

Auch von mir ein Dankeschön für die Erklärungen.

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.