Hallo,
ich möchte mit meinem Mega8 eine positive und negative Spannung messen.
Das ganze muss nicht extrem genau sein, daher hab ich hier aus dem Forum
einen Vorschlag mit Spannungsteilern gebaut. Das ganze läuft auch, ich
bekomme ordentliche ADC Werte und die Umrechnung in Volt funktioniert
auch großteils.
Ich habe allerdings noch ein Problem mit der negativen Berechnung,
sobald diese >0 wird. Ich bekomme dann immer den Wert -3835.0
angezeigt...
Hier die wichtigen Auszüge des Codes (AVR-GCC unter Windows):
1
intmain(void)
2
{
3
intn_volt0_adc=513;// ADC-Wert wenn Messpin für negative Spannung auf GND liegt
4
floatn_volt_val=-13.0;// negative Spannung in V (MIT Vorzeichen)
5
intn_volt_adc=291;// ADC-Wert bei negativer Spannung
Folgende Spannungen mit dazugehörigen ADC-Werten hab ich schon gemessen:
--------------------------------
Spannung in V | -13 | 0 | 2,67
--------------------------------
ADC Wert | 291 | 513 | 559
--------------------------------
Die +2,67 Volt bekomme ich, wenn ich den Messpin nicht angeschlossen
habe.
Wenn ich das ganze mit meinem Taschenrechner nachrechne, komme ich auf
die richtigen Ergebnisse, also vermute ich das Problem irgendwo im Code?
Wenn es ein bekanntes Problem ist dann umgeh ich das eben mit einer
if-Abfrage. Da an diesem Pin eigentlich nie positive Spannungen anliegen
werden ist das kein Problem. Mich würde nur interessieren, woran das
liegt?!
Wenn du den ADC so konfigurierst, dass die 10 Bits linksbündig im
Ergebnisregister liegen, dann lässt sich der Wert direkt als 16-Bit
Integer mit Vorzeichen auslesen (int16_t). Zerebrale Knotenbildung durch
Plus/Minus-Rechnerei entfällt, denn negative Werte sind schon negativ,
nut eben im Wertebereich +/-32K statt +/-512.
Ja, der µC lebt noch. Die Schaltung die ich verwende um die Spannungen
zu messen ist diese hier:
http://www.mikrocontroller.net/attachment/107327/Bild1.png (die untere
Z-Diode einfach ignorieren, die is falsch eingezeichnet...)
A. K. schrieb:> Zerebrale Knotenbildung durch Plus/Minus-Rechnerei entfällt
Ansich stört es mich ja nicht, wenn mit den +/- Werten gerechnet wird,
der Wertebereich ist auch unkritisch, die +/-512 würden ja locker
reichen.
Die Funktion ReadChannel() liefert mir auch schon einen uint16_t Wert,
aber ich kann mir trotzdem noch nicht erklären, warum beim Überschreiten
der 0,0V Grenzen auf einmal ein so seltsamer Wert rauskommt...
Christian Wächter schrieb:> Die Funktion ReadChannel() liefert mir auch schon einen uint16_t Wert,> aber ich kann mir trotzdem noch nicht erklären, warum beim Überschreiten> der 0,0V Grenzen auf einmal ein so seltsamer Wert rauskommt...
Genau deshalb. Weil ReadChannel ein uint16_t zurück gibt, erfolgt die
Berechnung in der Klammer als unsigned, und auch das Ergebnis der
Berechnung in der Klammer wird als unsigned interpretiert.
Stefan Ernst schrieb:> Weil ReadChannel ein uint16_t zurück gibt, erfolgt die> Berechnung in der Klammer als unsigned
Ah, verstehe. Was müsste ich dann ändern, damit es korrekt berechnet
wird? Für float, double etc. kann man ja ein
1
(float)
davor setzten, um es zu erzwingen. Gibt es das für (un)signed Zahlen
auch? Oder muss ich das Ergebniss aus (n_volt0_adc - ReadChannel(5))
nochmal in eine signed Variable zwischenspeichern?
Ah, sehr gut. Jetzt passt es, danke.
Eine kleine Frage zum Vorzeichen hätte ich aber noch: Kann ich es
"erzwingen", dass das Vorzeichen immer angezeigt wird? Bei negativen
Werten wird das "-" automatisch ergänzt, bei positiven wird aber das "+"
weggelassen?
A. K. schrieb:> sprintf kann das von Haus aus ("+" Option).
Die Funktion sieht ja gut aus, aber wie bekomme ich der folgendes
gesagt:
1) Vorzeichen immer anzeigen (+)
2) Insgesamt 6 Stellen : +00.00 (6)
3) 2 Stellen vor dem Komma (automatisch?)
4) 1 Stelle nach dem Komma (1)
5) Vorne evtl. mit einer Leerstelle auffüllen (blank?)
6) Es is ne Float-Zahl (f)
So geht's jedenfalls nicht, ich bekomme nichts angezeigt?!
Christian Wächter schrieb:> 1) Vorzeichen immer anzeigen (+)> 2) Insgesamt 6 Stellen : +00.00 (6)> 3) 2 Stellen vor dem Komma (automatisch?)> 4) 1 Stelle nach dem Komma (1)> 5) Vorne evtl. mit einer Leerstelle auffüllen (blank?)> 6) Es is ne Float-Zahl (f)
Also was jetzt? +00.00 sind 2 Stellen nach dem "Komma". +00.0 sind
insgesamt 5 Zeichen, nicht 6.
"%+5.1f" = immer Vorzeichen, Feldgrösse 5, eine Nachkommastelle,
Festpunktformat.
Du braucht ein Komma dazwischen, so wärens 61 Stellen vom Datentyp
blankf :P
"%+02.04f" gibt dir immer im selben Format, selbe länge aus:
+03.0100V
+03.0000V
-03.1234V
+00.0000V
...
A. K. schrieb:> Also was jetzt? +00.00 sind 2 Stellen nach dem "Komma". +00.0 sind> insgesamt 5 Zeichen, nicht 6.
Sorry, meinte schon 5 Zeichen
> "%+5.1f" = immer Vorzeichen, Feldgrösse 5, eine Nachkommastelle,> Festpunktformat.
Perfekt! 1000-Dank, genau so wollte ich es haben. Hätte ich mal lieber
hier gesucht, Google hat nur Müll gefunden, daher auch der Blödsinn mit
dem blankf...
> Du braucht ein Komma dazwischen, so wärens 61 Stellen vom Datentyp> blankf :P>> "%+02.04f" gibt dir immer im selben Format
Fast.
Die Zahl vor dem . ist die Gesamtbreite der Ausgabe. Es ist nicht
sinnvoll, wenn diese Zahl kleiner als die Anzahl der Nachkommastellen
ist. In diesem Sinne wäre deine Ausgabe
+3.0100
und nicht
+03.0100
wenn du vor dem Komma 2 Stellen haben willst, dann musst du eine
Feldbreite von 8 anfordern.
"%+08.04f"
Christian Wächter schrieb:> A. K. schrieb:>> Also was jetzt? +00.00 sind 2 Stellen nach dem "Komma". +00.0 sind>> insgesamt 5 Zeichen, nicht 6.> Sorry, meinte schon 5 Zeichen>>> "%+5.1f" = immer Vorzeichen, Feldgrösse 5, eine Nachkommastelle,>> Festpunktformat.> Perfekt! 1000-Dank, genau so wollte ich es haben. Hätte ich mal lieber> hier gesucht, Google hat nur Müll gefunden, daher auch der Blödsinn mit> dem blankf...
Jedes C-Buch hätte dir das sauber erklären können. Ziemlich am Anfang,
wenn es darum geht, den Leser mit printf bekannt zu machen.