Hallöche,
ich möchte gern mit einen AVR eine Akkuverbrauchsanzeige programmieren.
Es handelt sich um einen Blei-Gel-Akku mit 80 Ah und einen Bootsmotor
mit 12 V/ 36 A
(http://www.amazon.de/Elektromotor-Watersnake-34lb-1100kg-Schubkraft/dp/B003JVJ0MG)
Nun dachte ich an eine Atmel Mega 8, LCD-Display und eine Stromsensor.
Spannung und Strom wird über AD-Wandler erfasst. Die Werte dann
auswerten und über Display ausgeben.
Wie würdet Ihr das Problem angehen ?
Wie würde ein Programmablaufplan aussehen ?
Welche Zeiten/Timer würdet Ihr wählen ?
Hab im Netz nach Projekten gesucht, die man zum Vergleich ran ziehen
könnte, hab aber nix gefunden.
Für Eure Bemühungen vielen Dank im voraus.
Mfg
Maxo
Maxo75 schrieb:> Wie würdet Ihr das Problem angehen ?
Wie immer: In einzelnen Schritten.
Zuerst mal bring ich das LCD zum laufen. Kann ich dort Texte ausgeben,
ist das schon mal die halbe Miete.
Dann bau ich mir noch ein paar Hilfsfunktionen auf jeden Fall aber eine
Funktion, die einen Zahlenwert ausgeben kann. Denn ich will ja Messwerte
ausgeben.
Erst mal nur die Spannung laufend messen und anzeigen.
Dann nur den Strom laufend messen und anzeigen.
Dann beides laufend messen und anzeigen
Dann einen Timer einführen, der einen Zeittakt ins Programm bringt. Zb 1
Sekunde oder 1 Milisekunde.
Dann die Messungen so ändern, dass sie im Zeittakt gemacht werden
Dann die Ströme in diesem Zeittakt aufsummieren und anzeigen
Eventuell noch Bedienelemente hinzufügen, falls das notwendig ist
Unnötig zu sagen, dass natürlich jeder Schritt ausgiebig getestet wird,
ehe es zum nächsten Schritt weiter geht.
> Wie würde ein Programmablaufplan aussehen ?
1
Timer-ISR
2
3
Flag 'Es ist Zeit zu messen' setzen
4
5
end
6
7
8
main()
9
10
Hardware initialisieren
11
12
Verbrauch = 0
13
14
while dauernd
15
16
if( 'Es ist Zeit zu messen' ist gesetzt )
17
18
messe Spannung
19
messe Strom
20
21
Verbrauch = Verbrauch + Strom
22
23
Spannung am LCD ausgeben
24
25
Strom am LCD ausgeben
26
27
Verbauch am LCD ausgeben
28
29
'Es ist Zeit zu messen' zurücksetzen
30
31
end if
32
33
end while
34
35
end
wahnsinnig schwierig.
Wer schon jemals ein Programm für einen AVR geschrieben hat, dem sollte
diese Struktur (die praktisch immer mehr oder weniger identisch ist)
bekannt vorkommen.
Hinweis: das ist das Ziel. Man attackiert aber nicht gleich dieses Ziel,
sondern bewegt sich in Schritten auf dieses Ziel zu. So wie oben
skizziert. Das ist der schnellste und auch der erfolgversprechendste Weg
um sich nicht irgendwo zu verzetteln. Ausserdem lernt man bei jedem
Schritt eine Menge und kann sich auf das in diesem Schritt zu machende
bzw. zu verändernde konzentrieren. Ein Haus baut man auch nicht, indem
alle Handwerker inklusive Baggerfahrer an einem Tag gemeinsam
auftauchen.
> Welche Zeiten/Timer würdet Ihr wählen ?
Den Timer den ich verfügbar hab.
Die Zeiten, die machbar sind, die meinen Forderungen nach Messauflösung
entsprechen und bei denen ich nicht umständlich rumrechnen muss. Messe
ich jede Millisekunde, dann ist es simpel den Verbrauch in eine
vernünftige Masseinheit zu bringen. Messe ich alle 0.74239
Millisekunden, dann muss ich umrechnen. Ist zwar kein Beinbruch, aber
man ist ja auch faul.
> Hab im Netz nach Projekten gesucht, die man zum Vergleich ran ziehen> könnte, hab aber nix gefunden.
Och du armer.
Sowas schreibt man doch selbst!
Jeder der seine Hausaufgaben gemacht hat und seine Grundlagen beherrscht
sollte damit absolut keine Probleme haben.
Aber wie immer gilt natürlich: "Ich möchte" ist zu wenig. Wenn du etwas
möchtest, dann musst du es auch lernen.
Hallo,
danke für die ausführliche Antwort.
Programmiert wird in Assembler.
Da ich totaler Anfänger bin, noch mal wegen der Zeiten.
Ich meine, kann die Spannung/Strom aller 1 ms abfragen - aber macht das
Sinn ?? Was ist mit 1 s oder 10 s. Wo liegen da die Vor- und Nachteile.
Des weiteren ist ja dann auch die Auswahl des Quarzes entscheidend, oder
??
Ich dachte an 20 Mhz. Da die Befehle ja bestimmte Zeiten in Anspruch
nehmen, wie ist es mit der Berechnung ??
mfG
maxo
Maxo75 schrieb:> Ich meine, kann die Spannung/Strom aller 1 ms abfragen - aber macht das> Sinn ?? Was ist mit 1 s oder 10 s. Wo liegen da die Vor- und Nachteile.
Die periodische Messung ist ein Abtastsystem. Abhängig von der
Änderungsgeschwindigkeit (quasi von der höchsten Frequenz) muss man die
Abtastrate wählen.
Wenn du 10s wählst, dann kann der Motor schon 9,x Sekunden an oder aus
sein.
Aber auch das mittelt sich teilweise aus und die Genauigkeit der ganzen
Angelegenheit ist vermutlich stärker davon abhängig, wie gut du den
Strom messen kannst.
Maxo75 schrieb:> Des weiteren ist ja dann auch die Auswahl des Quarzes entscheidend, oder> ??
Eher nicht. Deine Timer müssen eben so eingestellt sein, dass sie dir
den Sekunden (oder Millisekundentakt) aus der Quarzfrequenz generieren
können. Da gibt es aber bestimmte Vorzugsfrequenzen, mit denen das
einfacher möglich ist, Stichwort Zweierpotenz.
Maxo75 schrieb:> Ich dachte an 20 Mhz.
Geht natürlich, aber ich vermute stark, dass es auch mit 1MHz gehen
würde.
Ich persönlich würde das ganze vermutlich sogar mit dem internen
Oszillator laufen lassen bei 1MHz oder 8MHz.
Maxo75 schrieb:> Programmiert wird in Assembler.
Das geht in C viel einfacher.
Hi,
danke @HildeK.
Ich hab versucht, mich mit C zu beschäftigen, im Internet hab ich mir
diverse HowDo`s angeschaut. Ich kapiere es einfach nicht.
Im Assembler sage ich z.B.
- schalte Ausgang/Port 1 auf low/high (ldi ...)
- warte 5 sek. und schalte auf low/high
- springe dorthin (rjmp ...)
- verschiebe Bit x nach links/rechts (lsl ...)
Das ist durch die Assembler-Befehle für mich nachvollziehbar.
Aber in C ist das einfach nur kryptisch für mich.
Hast du eine gute Dokumentation, wo das nachvollziehbar ist, was da
programmiert wird ??
Mfg
maxo
Maxo75 schrieb:> Hast du eine gute Dokumentation, wo das nachvollziehbar ist, was da> programmiert wird ??
Leider nicht. Ich habe hier in Buchform den Kernighan/Ritchie, das
Basiswerk, und als Kopie das Werk A Book on C.
Ansonsten gibts hier im Forum das AVR-GCC-Tutorial.
Ansonsten als Beispiel:
Schalte Ausgang B1 ein: PORTB = (1<<PB1);
warte 5s: gibt es in Assembler nicht, in C: _delay_ms(5000);
springe dorthin (rjmp ...): nimmt man in C nicht, da hat man Schleifen,
for, while
verschiebe Bit x nach links/rechts (lsl ...): wert = wert<<x; oder wert
= wert>>x;