Hallo!
Ich will folgendes tun:
Kurz gesagt hab ich einen Taster, mit dem ich einen Verbraucher
einschalte, bei erneuter Betätigung schalte ich den Verbraucher wieder
ab.
Für diese Anwendung verwende ich einen Lithium-Ionen Akku mit 7,4V.
Bei Unterschreitung einer Spannung von 6,8V (ist momentan nicht so
wichtig), soll meine Anwengung nicht mehr starten können.
Deswegen will ich mit dem Analog Comperator die Akku-Spannung mit der
Ausgangsspannung des Spannungsreglers (5V als Referenzspannung)
vergleichen und ins Programm als "Einschaltvoraussetzung" einbinden.
- Akkuspannung >6,8 --> Anwendung wird fortgesetzt
- Akkuspannung <6,8 --> Anwendung darf nicht mehr Starten
??? Welche Bits am ACSR-Port muss ich setzen bzw. brauche ich den
Interrupt?
??? Wie kann ich den Wert des Vergleichs (0 oder 1) auslesen bzw. wo
steht dieser drin?
Wer kann mir helfen?
MFG
Chillxx schrieb:> des Spannungsreglers
Welcher Spannungsregler?
> (5V als Referenzspannung)
Ein "normaler" 7805 hat da gern mal +-5% Toleranz...
nicht gast schrieb:> Besonders der Teil "Absolute Maximum Ratings"
Und den Abschnitt "Common Mode Range".
Du solltest besser deine 5V Referenz auf 2,5V teilen und deine 6,8V über
einen Spannungsteiler ebenfalls auf diese 2,5V bringen...
BTW: es ist ein Comparator mit kleinem 'a'
...werd ich mir mal anschaun, der Vorgang ist hier aber nicht
beschrieben.
Muss ich für diesen Vergleich den Comperator oder den AD-Wandler nehmen?
mfg
Chillxx schrieb:> Muss ich für diesen Vergleich den Comperator oder den AD-Wandler nehmen?
Kannst du beides machen. Bei Comparator hast du halt nur gut oder nicht
gut (ACI = 1 oder 0), mit dem ADC kannst du die exakte Spannung
bestimmen und per Software quasi deine Grenzen festlegen.
Chillxx schrieb:> Muss ich für diesen Vergleich den Comperator oder den AD-Wandler nehmen?
Comp-A-rator... :-/
Seis drum:
Der Comparator könnte dir bei unterschreiten der Spannung einen
Interrupt auslösen, das kann der ADC nicht. Aber wenn du sowieso erst
beim Tastendruck nachschaust, ob die Spannung noch passt, kannst du auch
den Comparator nehmen...
Ich würde die Sache allerdings mit dem ADC machen, denn dann kannst du
messen, ob da eher 7,3V oder 6,9V da sind...
OK, sowas würde ich gerne machen 6,7V wäre ja meine Grenze.
Wenn die anliegende Spannung am Spannungsteiler der Referenzspannung und
der zu messenden Spannung (also Grenze 6,7V) gleich ist, könnte ich
damit auch einen Vergleich durchführen, oder?
Und welche Variante zieht mehr Strom oder ist das vernachlässigbar?
mfg
Am Li-Ion wohl eher vernachlässigbar, das liegt im µA-Bereich.
Wenn du richtig Strom sparen willst solltest du dir das Power Management
und Sleep-Modes ansehen.
Chillxx schrieb:> Wenn die anliegende Spannung am Spannungsteiler der Referenzspannung und> der zu messenden Spannung (also Grenze 6,7V) gleich ist, könnte ich> damit auch einen Vergleich durchführen, oder?
Wie meinst du das?
Wenn du den AD-Wandler nimmst, dann mußt du nur noch gegen einen
Zahlenwert vergleichen, denn den Vergleich (die Wandlung) gegen eine
Referenzspannung macht ja schon der AD-Wandler...
1. Du darfst die Akkuspannung nicht direkt auf den AVR geben.
Beitrag "Re: ATMEGA8: <<<Analog Comperator>>>"
Du kannst aber einen Spannungsteiler benutzen.
2. ADC hat den Charme, dass du den Ist-Wert messen kannst.
3. AC hat den Charme, dass du Interrupts bekommen kannst.
Und den Nachteil, dass du nur digital > oder < Referenzspannung
messen kannst.
4. Mit 2. und 3. kannst du auch während der Verbraucher läuft den Akku
vor dem Leersuckeln schützen. 2. kanppst dabei mehr Rechenzeit ab und
wechselwirkt u.U. mit anderen Programmteilen insbesondere anderen ADC
Messungen
5. Wenn nach 4. der Akkustand bei laufendem Verbraucher unter die
kritische Grenze fällt und du den Verbraucher abschaltest, rechne
damit, dass sich der Akku sofort erholt. Du könntest in die AUS-AN-
AUS... Falle tappen. Thema Hysterese nachlesen. Überlege wie deine
Schaltung das Einsetzen voll geladener Akkus handhabt.
6. Wenn der 7805 aus dem Akku versorgt wird:
Arbeitet der 7805 mit 7,4-6,8V Eingangsspannung oder muss da ein
Low-Drop-Regler verwendet werden? Kann die Eingangsspannung so
abgesenkt werden, dass der 7805 automatisch die komplette Schaltung
inkl. AVR (=> Brownout) ausschaltet z.B. durch Diode(n) (-0,7V).
@lkmiller
also zuert-als Spannungsregler nehme ich den MCP1703Lothar Miller schrieb:> Wie meinst du das?
Damit meinte ich die Spannungteiler für den Analog Converter (falls ich
den nehmen würde)
Nehm aber wahrscheinlich doch den AD-Wandler, nach deiner Empfehlung :).
Aber wie gehe ich dabei vor?
1.Analogeingan im ADMUX-Register festlegen
2.ADSCR-Register initialisieren
3.ADCW-Wert herausnehmen
4.diesen Wert mit dem gewünschten Wert vergleichen
-->ist das ansatzweise richtig??
MFG und DANKE schon mal für eure Antworten
@Stefan
also ich verwende einen MCP1703, der mindestens mit 6,5V betrieben
werden muss...da der LithiumIonen-Akku (lt.meinen recherchen)erst kurz
vor der totalen Entladung an Spannung verliert, hab ich 6,7V als
minimale Spannung angenommen, wobei noch alles funktionieren sollte.
Eigentlich will ich einfach nur verhindern, dass mein Verbraucher
betätigt werden kann, wenn der akku "leer" ist. Außerdem will ich, dass
der Verbraucher automatisch abschaltet, wenn die Akkuspannung nicht mehr
ausreicht.
MFG
Chillxx schrieb:> @Stefan> also ich verwende einen MCP1703, der mindestens mit 6,5V betrieben> werden muss...
Hmm, Laut Datenblatt geht der sogar tiefer: Vin typ. >5,330V max.
>5,650V.
Deine Aufgabe kannst du mit dem AC oder dem ADC lösen. Ich würde den AC
benutzen. Damit bist du nicht auf einen AVR angewiesen, der eine ADC
Einheit hat (OK, der Atmega8 hat eine).
Ich hab eine kurze Zwischenfrage (bin grad am programmieren):
Wenn ich nur den PC0 als Analogeingang verwende, sind dann alle anderen
Pins am PORT C als normale I/O`s verfügbar?
ich hab einfach mal was reingeschrieben....ist ja wegen dem
Spannungsteiler kleiner 5V.
Oder kann ich die 5V vom Spannungsregler bzw an AVCC direkt als
Referenzspannung hernehmen?
Code compiliert ohne Fehler...
Chillxx schrieb:> Hab hier einen kleinen Programmausschnitt...> Würde das so funktionieren??
Nein.
Du kriegst vom ADC keinen direkten Spannungswert.
Der ADC liefert dir das Verhältnis von gemessener Spannung zur
Referenzspannung.
(Ich vereinfache jetzt hier bewusst):
Der ADC liefert Werte zwischen 0 und 1023. Wenn dir der ADC 1023 als
Antwort liefert, dann ist die gemessene Spannung genauso groß wie die
Referenzspannung. Liefert er 512, dann ist sie genau die Hälfte der
Referenzspannung usw. usw.
Das heißt jetzt aber NICHT, dass du zuerst die Spannung ausrechnen
musst, auch wenn das ganz leicht geht
Messwert * Referenzspannung
Spannung = ----------------------------
1024
Tus trotzdem nicht. Rechne dir aus welchem Messwert deine Schaltschwelle
entspricht und vergleich dann auf der Basis der ADC Einheiten. Das spart
zum einen Rechenzeit, zum anderen erspart es dir das Kopfzerbrechen, wo
denn eigentlich die ganzen Nachkommastellen bei der Umrechnung bleiben.
Mal abgesehen davon, dass es ziemlich sinnlos ist, den ADC in jeder
Runde in der Hauptschleife erneut zu intialisieren und das hier
while (ADCSRA&(1<<ADSC))
ein ; fehlt
Ja, so würde das funktionieren. Wobei allerdings eine Mittelung über
mehrere Messwerte der Sache sicherlich nicht abträglich sein würde.
Aber warum in die Ferne schweifen, wenn das Gute im AVR-GCC-Tutorial so
nahe liegt :-) Dort gibt es fertige ADC Routinen. Du musst nur noch
deine Referenzspannung wie gewünscht einstellen.
Karl heinz Buchegger schrieb:> Mal abgesehen davon, dass es ziemlich sinnlos ist, den ADC in jeder> Runde in der Hauptschleife erneut zu intialisieren und das hier
Dann schieb ich die Initialisierung einfach an den Anfang?
Diese Merfachmessung hat aber nichts mit dem Free-running Modus zu tun?
Karl heinz Buchegger schrieb:> while (ADCSRA&(1<<ADSC))> ein ; fehlt
...steht glau ich in der 5.Zeile in der while-Schleife
Übrigens hab ich dabei mich eh ans AVR-GCC-Turotial gehalten :), sonst
wär wahrscheinlich garnichts rausgekommen...
Allerdings hab ich noch nicht verstanden, was es mit diesem "uint_t" auf
sich hat...ist das einfach eine Funktion bzw. wie ein Nebenprogramm?
MFG :)
Walter schrieb:>>> int Referenz=2.5;> das glaube ich dir nicht> (oder du hast einen kaputten Compiler)
Mein Compiler (Tiny C Compiler) schluckt das ohne murren. Referenz wird
halt mit 2 initialisiert und nicht wie vielleicht erwartet mit 2.5
@ Chillxx
Statt mit der Fließkommazahl 2.5 könntest du mit dem 1000 fachen Wert
als Ganzzahl rechnen, also in mV statt in V. Das gibt keine Probleme bei
der Zuweisung in ein int. Und statt int als Ganzzahl mit Vorzeichen
bietet sich eine Ganzzahl ohne Vorzeichen an, also unsigned int.
Chillxx schrieb:> Karl heinz Buchegger schrieb:>> Mal abgesehen davon, dass es ziemlich sinnlos ist, den ADC in jeder>> Runde in der Hauptschleife erneut zu intialisieren und das hier>> Dann schieb ich die Initialisierung einfach an den Anfang?> Diese Merfachmessung hat aber nichts mit dem Free-running Modus zu tun?
Nein, hat nichts mit dem Freerunning Mode zu tun.
Aber du stellst ja einen Ausgabeport auch nicht ständig auf Ausgabe. Du
machst das einmal und dann passt das.
Mit dem ADC ist das genauso
>> Karl heinz Buchegger schrieb:>> while (ADCSRA&(1<<ADSC))>> ein ; fehlt> ...steht glau ich in der 5.Zeile in der while-Schleife
Red dich nicht raus.
Da ist kein ; wo einer hingehört.
Du hast ihn vergessen und dabei die Semantik des Programms verändert.
Rein logisch gesehen macht
while (ADCSRA&(1<<ADSC))
Messwert = ADCW;
das genau Gegenteil von
while (ADCSRA&(1<<ADSC))
;
Messwert = ADCW;
und damit hast du dein Programm durch einen einzigen vergessenen ';'
zerstört (wenn alles andere stimmen würde). Dein Pech, dass sich durch
den vergessenen ';' wieder etwas ergeben hat, was gültiges C ist.
>> Übrigens hab ich dabei mich eh ans AVR-GCC-Turotial gehalten :), sonst> wär wahrscheinlich garnichts rausgekommen...> Allerdings hab ich noch nicht verstanden, was es mit diesem "uint_t" auf> sich hat...
Mehr Sorgfalt!
Das Teil heist nicht uint_t sonder uint16_t und ist ein Datentyp!
u wie unsigned, also ohne Vorzeichen
int wie INteger, also Ganzzahl
16 wie 16, und das ist die Anzhahl der Bits
_t wie underscore T, und das ist ein Anhängsel, damit der geneigte
Leser schnell erkennen kann, dass er es mit einem Datentyp zu
tun hat
uint16_t
Ein Datentyp: unsigned Integer mit 16 Bit
> ist das einfach eine Funktion bzw. wie ein Nebenprogramm?
Nebenprogramm gibt es nicht.
Ja, im Tutorial sind fix fertige Funktionen. Du musst sie nur benutzen.
Und wie das geht, ist dort ebenfalls angegeben. Wir haben da ja nicht
zum Spass ein Beispielprogramm abgedruckt
1
/* Beispielaufrufe: */
2
3
intmain()
4
{
5
uint16_tadcval;
6
ADC_Init();
7
8
while(1){
9
adcval=ADC_Read(0);// Kanal 0
10
// mach was mit adcval
11
12
adcval=ADC_Read_Avg(2,4);// Kanal 2, Mittelwert aus 4 Messungen
13
// mach was mit adcval
14
}
15
}
so verwendet man die Funktionen.
Ganz einfach und ganz simpel.
Vor der Hauptschleife wird die Funktion ADC_Init aufgerufen, die, oh
Wunder, den ADC initilisiert (also seine Parameter einstellt wie zb
Referenzspannung).
In der Hauptschleife ruft man entweder die Funktion ADC_Read oder die
Funktion ADC_Read_Avg (Avg steht für Average, engl. Durchschnitt) auf
und die liefert den aktuellen Messwert, der dann in der Variablen adcval
abgelegt wird. Und mit dem Wert kannst du dann tun was immer du damit
tun willst.
Vielleicht wäre ein Blick in ein C-Buch mal angebracht, wenn dir
Funktionen nichts sagen.
Karl heinz Buchegger schrieb:> Red dich nicht raus.
....ahh....sorry :)
alles andere les ich mir mal sorgfältig durch!!
Danke für die schnelle Antwort!
Karl heinz Buchegger schrieb:> adcval = ADC_Read_Avg(2, 4); // Kanal 2, Mittelwert aus 4 Messungen
Kanal 2:
ist damit der Pin am Mikrocontroller gemeint?
Ja
ADC0, ADC1, ADC2, ADC3, ADC4, ....
soviele Eingänge wie dein µC für den ADC eben hat. Findet sich im
Datenblatt, dort aufgeschlüsselt als die MUX Bits.
Kurze Vertändnissfrage:
Ist der average ADC Wert im ganzen Programm aktuell (also läuft die
Messung im Hintergrund und schreibt fortlaufend den neuen Mittelwert in
adcval) oder muss ich jedes mal, wenn ich was mit dem Wert machen will,
die Funtkion/Messung neu starten??
mfg