suche Spanungsüberwachung

Vermutlich letzteres :)

Du hast einen Eingangsbereich von 0..Vref, also 0..2,55V die du an den ADC Pin(s) anlegen darfst.
Dieser spiegelt sich als Werte 0..1023 wieder.
Also 0 = 0V, 1023 = Vref, also 2,55V.

Der Rest ist simpler Dreisatz.
Pseudo-Code (ich hab zu lang nichts mehr in Bascom gemacht):
Wert = GetADC(0)
Volt = Wert / 1023 * 2,55 ' ergibt Messwerte 0,00V .. 2,55V

Wenn du jetzt Spannungen größer als Vref messen möchtest kommst du um einen Spannungsteiler vorm ADC Pin nicht drum herum. Ich nehme hier meistens 10K Potis (oder Trimmer), das ist aber Geschmackssache. Dann muss die Formel natürlich dementsprechend angepasst werden. Beispielsweise du teilst die Eingangsspannung des ADC durch 2 (mit 2x 4,7K Widerständen z. B.), dann könntest du doppelt so viel Spannung anlegen. Also:
Wert = GetADC(0)
Volt = Wert / 1023 * 5,10 ' ergibt Messwerte 0,00V .. 5,10V

und so weiter :)
 
So wie ich das verstanden habe, interessiert ihn die tatsächliche Spannung gar nicht. Er will nur wissen, zwischen welchen diskreten vorgegebenen Werten sie liegt.
Also kann er die diskreten Werte in die entsprechenden digitalisierten Zahlen umrechnen (mit demselben Dreisatz), und braucht dann im Programm nur noch words vergleichen lassen.
 
So wie ich das verstanden hatte soll es wie eine Art Akku Voltmeter werden.
Klar, deine Methode geht selbstverständlich auch und ist zweifelsohne auch performanter (kein Fließkomma und so), aber so ist es vielleicht etwas leichter zu verstehen.

Fehlt eigentlich nur noch ein Select Case (falls Bascom beim Select auch Bereiche zulässt) oder mehrere If Abfragen :)

Select Case Volt
Case 0 To 10 ' Ieks! Batterie tot!
Case 10 To 11 ' LED1 an
...

Bzw.:
If Volt < 10 Then
' Ieks
ElseIf Volt < 11 Then
' LED1 an
...
 
Hi,

ich danke Euch erst einmal für Eure Hilfe.
Ich erkläre noch einmal was ich vor habe und wie meine Hardware aussieht.

Ich möchte die Akkuspannung eines Gerätes überwachen, dass heißt:
Spannung-normal 12V - optisch per LED1 anzeigen;
Spannung- 11V - optisch per LED2 anzeigen;
Spannung- 10V - optisch per LED3 anzeigen;
Spannung- 9V - optisch per LED4 anzeigen;
Spannung- 8V - optisch per LED5 anzeigen(blinken);

Mein Spannungsteiler von 12V auf 4,662V besteht aus 2 Widerständen von 9,76k und 6,2K.
Der Spannungsteiler liegt an Pin (ADC0)PF0 am Mega2560 .

und das ist mein bisheriger Code:

$regfile = "m2560def.dat" 'Atmega 2560 einstellen
$loadersize = 512
$hwstack = 100
$framesize = 64
$swstack = 100
$crystal = 16000000 'Quarzfrequenz


Config Adc = Single , Prescaler = Auto , Reference = Internal_2.56
Start Adc

Gruß Andreas
 
Hallo Andreas,

wenn es dir nur um die Spannungsüberwachung geht, dann ist der Atmega2560 sicher total unterfordert. Wenn die Akkuüberwachung alles ist, geht das auch viel einfacher (LM3914).
Ok, ist ein Analogschaltkreis und hat nichts mit MC zu tun, ist aber eine preiswerte und zuverlässige Lösung.
http://www.google.de/imgres?imgurl=...fPU_mOJrDP4QT7yICICA&ved=0CDIQ9QEwAw&dur=6382

http://www.reichelt.de/LM-3914-DIL/...ARTICLE=10504&artnr=LM+3914+DIL&SEARCH=LM3914

- gp177 -

Hi,

das ist für mich ein Testprojekt. Und auf meinem Test-Board sitzt ein Mega2560.

Gruß Andreas
 
Ahh,

dass heißt, der Spannungsteiler ist falsch errechnet. Ich benötige ca. 2V Teilerspannung. Oder kann man es noch anders lösen?

Hier mal mein Code:

Code:
$regfile = "m2560def.dat"                                  'Atmega 2560 einstellen
 $loadersize = 512
 $hwstack = 100
 $framesize = 64
 $swstack = 100
 $crystal = 16000000                                        'Quarzfrequenz

Led1 Alias Porth.5
Led2 Alias Porth.4
Led3 Alias Porth.6

Config Led1 = Output                                        ' LED  12 V
Config Led2 = Output                                        ' LED  10 V
Config Led3 = Output                                        ' LED   8 V

Config Adc = Single , Prescaler = Auto , Reference = Internal_2.56

Dim W As Word
Dim Channel As Byte
Channel = 0

Do
Start Adc

W = Getadc(0)                                               ' messen des Analogwertes
Stop Adc

 If W > 1200 Then                                            ' Spannung > 12 V
     Led1 = 1
     Led2 = 0
     Led3 = 0

End If
If W < 1200 And W > 1000 Then                                 ' Spannung 10 V
     Led1 = 0
     Led2 = 1
     Led3 = 0

End If
If W < 800 Then                                             ' Spannung < 8 V
     Led1 = 0
     Led2 = 0
     Led3 = 1

End If
Loop

End



Gruß Andreas
 
Als Referenz könntest du auch VCC nehmen (vermutlich 5V?) statt die 2,56V.
Ich persönlich rate davon aber eher ab, da man mit diesem Weg stark auf die Betriebsspannung achten muss (Stabilität. Wenn sich VCC ändert ändern sich dementsprechend auch die Messwerte). Ich würde den Teiler ersetzen dass der ungefähr 2,0 - 2,3V ausgibt bei max. Spannung.

Die Werte hab ich jetzt nicht nachgerechnet, der Code sieht aber auf den ersten Blick ok aus.
 
Na du kennst doch den Nullpunkt. Also Wert 0 = 0V
Und du kennst Vref (oder kannst diesen messen). Also Wert 1023 = Vref

Sagen wir jetzt mal, da es übersichtlicher ist, Vref = 4,00V.
Das heißt GetADC gibt dir bei 0V am ADC Pin 0 zurück. Bei 4,00V (oder mehr) gibt es dir 1023 zurück.
Würden wir jetzt 2,00V am ADC Pin anlegen würdest du den Wert 511 bekommen. Ist halt die Hälfte von Vref, also auch die Hälfte von den 1023 (+- n bissl Toleranz).

Also ergibt sich (mein Weg): Volt (als Single oder Float) = GetADC / 1023 * Vmax
So kannst du im Code direkt nach der Spannung auswählen und musst bei einer Änderung ggf. nur die Formel ändern wenn sich Vref oder der Spannungsteiler ändern sollte. Dafür rechnet hier der Microcontroller für dich. Bei zeitkritischen Anwendungen ist das aber weniger geeignet, da Single / Float auf den Controllern in Software berechnet werden (keine hardwareseitige Unterstützung). Für deinen Zweck sind diese Nachteile aber irrelevant.

Versus LotadaC's Weg (performanter): Wert (als Word) = (Vadc / Vmax) * 1023
Aber hier musst du halt selber rechnen und die Werte direkt im Quelltext eingeben (wie du es jetzt machst) und sollte sich Vref oder der Spannungsteiler ändern alle neu berechnen. Dafür hat der Controller aber mehr Resourcen über für andere Dinge.

Vmax ist hierbei die Spannung die du an dem Spannungsteiler anlegen musst damit Vref identisch ist mit der Spannung von dem ADC Pin (Vadc).

Nix kompliziertes, nur Dreisatz :)
 
Wobei eben (Vadc/Vmax)*1023, oder genauer gesagt (Vadc/Vref)*1023 exakt der Wert ist, den getadc liefert. Der AVR muß also gar nicht mehr rechnen, nur noch vergleichen.
Wenn man'n Sekundenzähler braucht, implementiert man doch auch nicht erst 'ne Uhr mit Schaltjahrsynchronisation und allem drum und drann (Fließkomma etc...) um dann aus den Differenzen verstrichene Sekunden zu berechnen wähend die Uhr in Software tickt...

Klar, dafür muß man vorher einmal die diskreten Werte die der ADC bei den Schwellspannungen liefert ausrechnen, und in den Code mitreincompilieren - in ASM könnte man dazu 'ne Kompilervariable (Konstante) derzeugen lassen, die das selbst berechnet (aus vorgegebenen Werten wie der Referenzspannung, dem Teilerverhältnis), so wie wir das mal mit der Baudrate oder so gemacht hatten - gibt es in Bascom auch die Möglichkeit solche immediates in der IDE berechnen zu lassen, die eben keine Variablen im SRAM etc des AVR werden?

Nochmal zum Code:
getadc liefert 'ne 10-bit-Zahl, also irgendwas zwischen 0 und 1023. Nie 1200 oder mehr.(*)
Der ADC arbeitet folgendermaßen:
Er versucht die anliegende analoge Spannung sukzessiv durch vielfache eines 1023stels der Referenzspannung mithilfe eines DAC zu approximieren.
0b11_1111_1111 entspräche der Referenz, 0b00_0000_0000 ist 0
Von links nach rechts werden jetzt einfach die Bits "ausprobiert", im ersten Schritt wird also 0b10_0000_0000 auf den DAC gelegt, wodurch der die halbe Referenzspannung ausgibt (Uref*(512/1023)). Diese wird mit tatsächlichen Eingangsspannung verglichen.
Ist die tatsächliche Spannung größer, bleibt die 1, sonst 'ne 0. Danach gehts mit der nächsten Stelle weiter. Nehmen wir an, die 1 ist stehengeblieben - jetzt wird 0b11_0000_0000 auf den DAC gelegt - der gibt foglich dreiviertel der Referenz raus... wieder wird verglichen usw., sind alle 10 Bits durch, hat man das digitalisierte Ergebnis dazustehen.
Diese Zahl liest getadc nach erfolgter Konversion aus den beiden ADC-Ergebnis-Registern aus.

(*)Hmm... strenggenommen könnte man natürlich nach dem config ADC... ADLAR setzen (ADLAR steht AFAIK im ADMUX, getadc sollte nur auf eines der ADCSRx wirken) - dann wären die 10bits linksorientiert in den ADC-Result-Registern, also die Werte vervierundsechzigfacht...
 
Hi,

das mit der Referenzspannung, dem ADC-Wert und der Eingangsspannung ist doch nicht so schwer :rolleyes:

Wert 0 bis Wert 1023 sind genau 1024 Werte (so wie 0-9 10 Werte sind ... 0,1,2,3,4,5,6,7,8,9)

Deine Referenzspannung ist 2,56V. Deine Eingangsspannung darf also auf keinen Fall höher sein!

Der ADC teilt nun deine Referenzspannung in diese 1024 gleichen Teile auf.
Also 2,56V / 1024 = 0,0025V oder 2,5mV

Wenn der ADC 0 ausgibt entspricht das 0V am ADC-Eingang
Wenn der ADC 1 ausgibt entspricht das 2,5mV am ADC-Eingang
Wenn der ADC 2 ausgibt entspricht das 5mV am ADC-Eingang
3 = 7,5mV
4 = 10mV
5 = 12,5mV
6 = 15mV
bis ...
1023 = 2560mV = 2,56V = deine Referenzspannung

Der ADC sagt dir also nur wie viele Teile der Referenzspannung deine Eingangsspannung entspricht.

Da du deine zu messende Spannung auch noch unter die Höhe der Referenzspannung bekommen mußt hast du also zusätzlich noch den Faktor des Spannungsteilers drin.

Wenn du also auf maximal 2,4V kommen willst und deine zu messende Spannung 12V ist dann ...
12V / 2,4V = 5

Wenn du nun 10V anlegst dann sind also am ADC-Eingang ...
10V / Faktor 5 = 2V (das liegt am Eingangspin an)

Das vergleicht der ADC nun mit dem Referenzwert (also den 1024 Teilen der Referenzspannung)
2V / 2,5mV = 800 = dein Wert vom ADC

Deine 10V die du messen willst ergeben im ADC-Register also den Wert 800.

Anders herum ...
800 * 2,5mV * Faktor5 = 10V
Wenn im ADC-Register also 800 stehen, dann kannst du davon ausgehen das du 10V an deinem Spannungsteiler anliegen hast.

Warum packst du dein Programm eigentlich nicht einfach mal auf den Atmel und probierst damit rum? Damit lernt man am schnellsten wie das zusammenhängt ;)

Noch besser wäre nen LCD mit anschließen und die Werte anzeigen lassen oder auf dem UART an ne serielle Schnittstelle des PCs liefern um sie auf nem Terminalprogramm zu sehen.

Gruß
Dino
 

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)