Hi Leute,
ich bin ein ziemlich unerfahrener Mikrocontroller-Programmierer und mein
C-Programm soll ungefär folgendes machen:
- Der ADC liest eine Spannung ein
- Je nach ADC-Wertebereich sollen beliebige Ausgänge geschaltet werden
Es gibt insgesamt 2 verschiedene Tabellen mit je 30 Intervallen (z.B
if(200<ADC<225) {schalte port bla bla})
Das Ganze habe ich jetzt erstmal mit 60 if-else Verzweigungen
programmiert, was mir allerdings ziemlich primitiv erscheint, da im
schlimmsten Fall 29 Abfragen umsonst durchlaufen werden müssen. Wie
liese sich sowas denn eleganter lösen? (ich habe was von Lookup Tabelle
gelesen?)
Gibt es ausserdem eine Möglichkeit im Compiler (AVR Studio 4.19) noch
einen "Korrekturfaktor" auf meine Schaltschwellen (oder auf den
ADC-Wert) draufzurechnen ohne, dass am Ende eine eklige Kommazahl
herauskommt?
Besten Dank!
Gruß,
Philipp
Philipp schrieb:> Wie liese sich sowas denn eleganter lösen?
Das kommt drauf an, wie deine Schaltschwellen liegen.
Philipp schrieb:> Gibt es ausserdem eine Möglichkeit im Compiler (AVR Studio 4.19) noch> einen "Korrekturfaktor" auf meine Schaltschwellen (oder auf den> ADC-Wert) draufzurechnen ohne, dass am Ende eine eklige Kommazahl> herauskommt?
Rechne mit Ganzzahl, dann kann das nicht passieren.
Wie groß ist der Wertebereich Deiner Messung? Und sind das nur integer?
Wenn Du z.B. einen Wertebereich von 0-255 hast könntest Du ein Array
anlegen in der für jeden Wert drinsteht was auf den Port ausgegeben
werden soll...
Also z.B.:
0-9 => Port Pin 1 aktiv
10-19 => Port Pin 2 aktiv
20-255 => Port Pin 3 aktiv
Dann belegst Du Dein Array so vor:
Mal unterstellt deine Schaltschwellen sind linear aufsteigend dann
dividiere deinen ADC Wert durch 10 und du erhältst 102 Schaltpunkte.
Beispiel Pseudocode
Wolfgang schrieb:> Das kommt drauf an, wie deine Schaltschwellen liegen.Uli schrieb:> Wie groß ist der Wertebereich Deiner Messung? Und sind das nur integer?Bernd N. schrieb:> Mal unterstellt deine Schaltschwellen sind linear aufsteigend...
Die Tabelle fängt bei etwa ADC=200 an und geht bis etwa ADC=800. Das
sind direkt die integer Werte die aus dem ADC kommen. Die
Schaltschwellen sind aber NICHT linear aufsteigend sondern müssen
beliebig festgelegt werden können.
Am schönsten wäre es natürlich, wenn man die Schaltschwellen direkt als
Zahl eingeben könnte.
Wolfgang schrieb:> Rechne mit Ganzzahl, dann kann das nicht passieren.
Wie genau funktioniert das denn?
Ergänzung:
Alle Schaltschwellen die ich eingegeben habe sollen vom Compiler schon
bevor das Programm erstellt wird z.B. mit 1,04 multipliziert und dann
auf ganze Zahlen gerundet werden.
Philipp schrieb:> Die Tabelle fängt bei etwa ADC=200 an und geht bis etwa ADC=800. Das> sind direkt die integer Werte die aus dem ADC kommen.
sind dann alle werte durch 4 Teilbar?
wenn ja dann passt es schon mal gute in ein byte rein. Das spart dann
platz im speicher.
Philipp schrieb:> Wie genau funktioniert das denn?
Das kommt drauf an, was du genau vor hast.
z.B.
a = (b * c - d) * 2^-d
Wobei 2^-d eine Shift-Operation um d Stellen ist.
abc123 schrieb:> Ist nur schnell hingeschmiert. Wenn die Tabelle länger ist kann man sie> in den Flash verbannen.
Vielen Dank! Das gefällt mir jetzt schon recht gut. Da wär ich nie drauf
gekommen.
abc123 schrieb:> Wenn der letzte Eintrag im Array 1023 = "uint10_max" enthält kann man> sich die if-Abfrage sparen.
Wegen der Abbruchbedingung der for-Schleife oder?
Wolfgang schrieb:> Das kommt drauf an, was du genau vor hast.
Wenn ich jetzt z.B. die uint16_t max Werte in dem Array aus dem Beispiel
von "abc123" alle mit einem Korrekturfaktor multiplizieren möchte. Aber
ohne, dass der Compiler mir dann Kommawerte daraus macht und in den
Atmega programmiert. Quasi so als würde ich die Werte alle manuell mit
dem Korrekturfaktor multiplizieren und dann den gerundeten Wert in das
Array reinschreiben.
Gruß,
Philipp