Hallo Leute.
Wie ihr in der Überschrift schon erkennen könnt benötige ich etwas Hilfe
bei der Fehlersuche in meinem kleinen Programm. Ich nehme es vorweg,
dass ich noch nicht viel Erfahrung in der Programierung habe und
deswegen vielleicht einiges umständlich oder falsch geschrieben habe.
Programiert habe ich in C/C++ und mein uC ist ein Atmega 16 mit einer
Taktung von 1MHz.
Hier die Beschreibung meines Programmes:
Es handelt sich um einen Empfänger für 5 Ziele die bei einem Treffer
einen PNP-Transistor ansteuern sollen. Des weiteren habe ich eine
Überwachung für meine Akkuspannung und die Ladespannung welche durch
LEDs signalisiert wird.
-Die Auswertung der Treffer erfolgt an PINA0 bis A5. Beim Treffen wird
eine Spannung von 1.1V von dem Ziel abgegeben und entsprechend vom ADC
registriert. Wurde zB Ziel_1 (PINA0) getroffen wird der Ausgang PIND2
von Hi auf Low geschaltet. Ausgangspins für die Trefferanzeige sind
PIND2 - PIND6.
-Wenn alle 5 Ziele getroffen sind, sollen diese noch 5 Sekunden
nachleuchten und dann alle wieder abgeschaltet werden.
-Die Akkuspannung wird mit Hilfe eines Spannungsteilers (1:1) auf max.
4.7V begrenzt. Liegt am Akku eine Spannung >= 6.6V an, wird eine Led an
PINB0 eingeschaltet.
Wird die Akkuspannung kleiner als 6.6V, wird die Led an PINB0
deaktiviert und eine andere an PINB1 aktiviert.
-Die Ladespannung wird auch wieder mit einem Spannungsteiler (1:2) auf
max. 4.7V begrenzt. Ist die Akkuspannung <6.6V und die Ladespannung >10V
schaltet die Led an PINB0 in den Blinkbetrieb.
Nun zu meinem Problem:
Ich habe meinen Quellcode Stück für Stück in Betrieb genommen.
-Der "Empfang" aller Treffer sowie die Anzeige des Treffers
funktionieren.
-Das Nachleuchten für 5Sek und anschließendes Abschalten aller 5 Ziele
funktioniert auch.
-Aktiviere ich die Akkuüberwachung gemeinsam mit dem Rest meines
Programmes, funktioniert diese, aber die ADC-Pins 0 bis 3 sind ohne
Funktion. Nur der PINA4 funktioniert.
Standardmäßig liegen PINA0 bis PINA5 an Masse.
Lege ich PINA0 bis PINA3 auf +5V, schalte dann erst die
Spannungsversorgung ein, und dann PINA4 auf +5V, funktioniert die
Messung des PINA4 sowie das Nachleuchten für 5Sek. Danach ist dieser
Teil des Programmes wieder ohne Funktion.
-Die Überwachung der Ladespannung funktioniert gar nicht, da meine LED
an PINB0 nicht blinkt. Ich vermute einen Fehler in meinem Timer, finde
aber auch diesen nicht.
Ich hoffe ich habe es verständlich erklärt und mit Hilfe meiner
Kommentare in der Programierung kann mir jemand weiter helfen und mir
sagen, wo ich meine Fehler mache.
MFG Alex
Du solltest hardwaremäßig sicherstellen, dass die Spannung an allen Pins
niemals höher ist, als VCC und niemals niedriger als GND. Denn dies wäre
ein nicht definierter Betriebszustand, indem fehlfunktionen zu erwarten
sind.
Erst Signale anlegen und danach VCC darf nicht passieren.
> die ADC-Pins 0 bis 3 sind ohne Funktion
Warum denkst du das? An welchen Sympromen hast du das erkannt?
Dein Quelltext ist schrecklich formatiert. Öffne die Datei mal in einem
Editor mit Auto-Format Funktion und wende diese dann an.
In der Prozedur Akkubetrieb() steuerst du die LED's nur dann an, wenn
Ladespannung=0 ist.
Aber in der Prozedur Ladekontrolle steuerst du die LED's immer an. Ich
denke, hier solltest du ebenfalls die Ladespannung berücksichtigen,
damit immer nur eine der beiden Prozeduren die LED's ansteuert und
niemals beide "gleichzeitig".
> if ((Ladespannung >= 860) && (Akkuspannung < 983)) // Ladespannung > 10 V LED
Für mich liest sich der Code eher so, als ob die LED's nur angesteuert
werden, wenn die Akkuspannung in einem kleinem Bereich liegt. Der
Kommentar ist ganz sicher falsch.
Deine LED blinkt möglicherweise nicht, weil die Akkuspannung mehr als
982 ist. Du solltest Dir mit Hilfe von Debug Meldungen oder einem
Hardware-Debugger mal die konkreten Werte anzeigen lassen, die der ADC
liefert.
Dann hast du hier noch einen Fehler:
1
if ((Ladespannung >= 860) && (Akkuspannung < 983)) // Ladespannung > 10 V LED
2
{
3
if(Timer_1_Sek == 970)
4
{
5
PORTB |= (1<<Akku_ok);
6
}
7
8
if(Timer_1_Sek == 1940)
9
{
10
PORTB &= ~(1<<Akku_ok);
11
Timer_1_Sek = 0;
12
}
13
}
Was ist, wenn dein Timer zum Beispiel den Wert 1941 erreicht hat während
die Ladespannung gerade <860 oder >=983 war? Dann wird der Timer
überlaufen und das Blinken der LED für diese Zeit ausbleiben.
selbiges für alle anderen Funktionen.
Einfach nur Code weiter zu kopieren und ein paar Konstanten austauschen
ist keine gute Idee, vor allen Dingen wenn die Funktionen umfangreich
sind. Man kommt dann schnell in die Situation, dass man vor lauter
(unwichtigem) Code die wesentlichen Dinge nicht mehr sieht.
Ganz abgesehen davon, dass dann massenhaft Code völlig unnötiger weise
zu Stande kommt.
> -Die Ladespannung wird auch wieder mit einem Spannungsteiler (1:2)> auf max. 4.7V begrenzt. Ist die Akkuspannung <6.6V und die> Ladespannung >10V schaltet die Led an PINB0 in den Blinkbetrieb.
Die Ladespannung und die Akkuspannung sind wie miteinander verschaltet?
> Programiert habe ich in C/C++ und mein uC ist ein Atmega 16 mit einer Taktung
von 1MHz.
Dann hast du dich verrechnet.
WEnn der µC mit 1Mhz läuft und du beim Timer einen Vorteiler von 1024
einstellst, dann erhält der Timer pro Sekunde 976 Pulse seinen Wert zu
erhöhen.
Da du den Interrupt auf den Overflow gelegt hast, erfolgt alle 256
Timererhöhungen ein Overflow. Pro Sekunde hast du also 976 / 256 gleich
3.8 (sagen wir 4) Overflows.
Damit ...
1
ISR(TIMER0_OVF_vect)
2
{
3
Timer_1_Sek++;
4
5
....
6
7
}
8
...
9
if(Timer_1_Sek==970)
10
...
... 970 Overflows zu stande kommen, müsstest du also 3698 Sekunden vor
der LED ausharren. Also eine knappe Stunde.
> ADC Pin 1-3 ohne Funktion:
- Ich habe eine Spannung angelegt und konnte keine Reaktion darauf
feststellen. Daher war ich der Annahme, dass mein Programm die an irgend
einer Stelle funktionslos macht.
> Die Formatierung:
- Ganz klar mein Fehler. Ich habe es mit dem programmers Notepad von
WinAVR geschrieben und da sah es noch schön übersichtlich aus mit der
Formatierung.
> blinkende Led:
- Der Zustand, dass die Ladespannung kleiner als 860 wird, passiert nur
wenn das Ladegerät aus ist und dann befinde ich mich ja wieder im
Akkubetrieb.
>Lade/Akkuspannung:
- Als Akku dient ein 8,4V (9V) NiMh Akku. Als Ladespannung habe ich ein
12V 600mA Ladegerät. Schaltbild ist im Anhang.
Spannungsteiler für den Akku habe ich am In vom 7805 und gegen Masse.
Spannungsteiler für die Ladespannung habe ich direkt zwischen +12V und
Masse von der Ladebuchse.
>Basisroutine:
-mit der kürzeren Schreibweise hast du schon recht. So wie es jetzt ist,
war es für mich als Anfänger noch am übersichtlichsten. Mit der Übung
und der Zeit entwickelt man sich weiter.
>Timer:
-So langsam wird es peinlich für mich....
Danke für die schnelle Hilfe!
Schau mal, ob du dem Editor die Verwendung von Tabulator-Zeichen
abgewöhnen kannst. Wenn du stattdessen mit Leerzeichen einrückst (die
meisten Text Editoren können die Tab Taste mit Leerzeichen belegen)
vermeidest du solche Probleme beim Dateiaustausch.
> Der Zustand, dass die Ladespannung kleiner als 860 wird, passiert> nur wenn das Ladegerät aus.
Sicher? Was ist, wenn der Akku ziemlich leer ist und dann erst geladen
wird. Die Spannung steigt doch nicht sprunghaft an, nur weil ein
ladegerät angeschlossen ist. Das dauert seine Zeit - denke ich.
> Als Akku dient ein 8,4V (9V) NiMh Akku.> Als Ladespannung habe ich ein 12V 600mA Ladegerät.
Falls es ein 9V Block in der üblichen Größe ist, lädst du ihn
hoffentlich nicht mit den vollen 600mA Ladestrom.
Wie stellst du denn eigentlich, dass der Akku nicht überladen wird? Ich
denke, dein Konzept, den Füllstand an der Spannung auszumachen, ist
grundsätzlich falsch.
Ein zuverlässiges und sicheres Ladegerät kombiniert das sogenannte
Delta-U Verfahren mit einer Temperaturüberwachung und einem Timeout.
Das hat alles nichts mit dem Programmcode zu tun, aber mich beschleicht
das Gefühl, dass hier die Funktionalen Mängel schon beim
Funktionskonzept beginnen. Wir helfen Dir gerne, das in ordnung zu
bringen.
Wegen dem Akku gebe ich dir gerne Recht. Es ist klar, dass moderne
(universal) Ladegeräte mit einer Temperaturüberwachung etc ausgestattet
sind. Bei LiPo Akkus (Modellbau) sind noch deutlich mehr Faktoren als
die Temperatur und die Spannung zu überwachen. Das ist ein kleiner
Vorteil von den NiMh Akkus. Die sind da etwas robuster und einfacher
gehalten, haben dafür aber auch eine geringere Spannung und einen
kleineren Strom. Die Angabe mit 8.4V ist schon richtig gewesen. Von der
Bauform her sind es normale 9V Blöcke aber aufgrund dessen, dass es NiMh
Akkus sind bestehen sie aus 7 Zellen á 1,2V was 8,4V bei max. 200mAH
macht. Ich habe mein Schaltbild gepostet. Darauf ist ersichtlich, dass
ich den LM317 durch den 9R3 Widerstand als Konstantstromquelle benutze
wodurch der Ladestrom auf 217mA begrenzt wird.
Während des Ladevorganges steigt die Ladespannung am Akku langsam auf
bis zu 9.6V an. Ist dieser Punkt erreicht ist der Akku auch voll
geladen. Deshalb sollte die Led in meinem Programm auch bei 9.6V
Ladespannung aufhören zu blinken.
>Ladespannung kleiner 860
-Es ist blöd ausgedrückt von mir. Es ist nicht die eigentliche
Ladespannung sondern die Spannung, direkt an der Ladebuchse. Also eine
Kontrolle ob das Ladegerät angeschlossen ist oder nicht.
Die eigentliche Kontrolle welche Spannung der Akku hat (Ladevorgang oder
Betrieb ist egal) wird von der Variable "Akkuspannung" gemessen.
Karl H. schrieb:> ... 970 Overflows zu stande kommen, müsstest du also 3698 Sekunden vor> der LED ausharren. Also eine knappe Stunde.
Äh. Da muss ich mich jetzt verrechnet haben.
Wenn pro Sekunde ca 4 Overflows auftreten, dann können 970 Overflows
nicht 1 Stunde brauchen. Es sind nur ca. 250 Sekunden (überschlagsmässig
gerechnet 1000 / 4). Also irgendwas um die 4 Minuten. Macht es aber auch
nicht besser, denn so lange hast du sicher nicht gewartet.
Alex schrieb:>>Basisroutine:> -mit der kürzeren Schreibweise hast du schon recht. So wie es jetzt ist,> war es für mich als Anfänger noch am übersichtlichsten. Mit der Übung> und der Zeit entwickelt man sich weiter.
Code zu duplizieren ist praktisch nie die übersichtlichere Variante.
Deinen jetzigen Code kann man von geschätzten 250 Zeilen auf vielleicht
60 oder 70 Zeilen (ebenfalls geschätzt) einstampfen. Wenn 2/3 vom Code
durch eine andere Organisation wegfallen, kann man nicht davon sprechen,
dass das Original übersichtlicher gewesen wäre.
3 Streichhölzer vor sich auf dem Tisch liegen haben ist übersichtlich.
Ein Haufen von 300 Streichhölzer vor sich zu haben ist nicht mehr
übersichtlich.
Der Schaltplan mit dem LM317 ist mistig.
Schau doch noch mal ins Datenblatt, da ist eine richtiges Beispiel drin.
Und die Diode (V2) ist als Verpolschutz gedacht? Wenns sein muß.
Eine Diode sollte aber auch hinter den LM317, für den Fall, daß die
12Volt mal nicht anliegen.
Stefan U. schrieb:> Du solltest hardwaremäßig sicherstellen, dass die Spannung an allen Pins> niemals höher ist, als VCC und niemals niedriger als GND. Denn dies wäre> ein nicht definierter Betriebszustand, indem fehlfunktionen zu erwarten> sind.
Eine Spannung von deutlich weniger als 0.5V bzw. mehr als VCC+0.5V
stellt ohne Strombegrenzung sogar ganz schnell einen sehr definierten
Betriebszustand her: Die Eingangsschutzdiode wird überlastet und die
Chancen stehen nicht schlecht, dass der Pin danach zu nichts
Vernünftigem mehr zu gebrauchen ist.
Ich hatte mal gelesen, dass I/O Pins häufig trotz defekter Schutzdiode
noch funktionieren. Aber sie werden dann sehr anfällig gegen hohe
Fremdspannung z.B. durch einfaches berühren.
Bin grade dabei eure Tips und Vorschläge umzusetzen, kann aber noch
etwas dauern bis ich damit fertig bin.
Um die Diskusion um defekte I/O Pins auszuräumen; bei meiner Schaltung
kommt keine Spannung vor die größer ist als VCC und präzise 5V hat.
Damit widersprichst du deiner vorherigen Information, dass Du Signale
angelegt hast, bevor die Stromversorgung (VCC) angelegt wurde.
Wen VCC Null Volt ist, und ein Signal 5V hat, dann ist das Signal um 5V
höher, als VCC. Dann ist es 10x höher, als zulässig.
> Lege ich PINA0 bis PINA3 auf +5V, schalte dann erst die> Spannungsversorgung ein ... Danach ist dieser> Teil des Programmes wieder ohne Funktion.