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.
Tu dir selbst einen Gefallen und hol dir von hier https://www.mikrocontroller.net/articles/AVR-GCC-Tutorial/Analoge_Ein-_und_Ausgabe#Der_interne_ADC_im_AVR erst mal die ADC Basisroutinen. Das ist doch unsinnig, wenn du die ADC Ansteuerung immer wieder in jeder Funktion neu in allen Details ausführst. Das schreibt man sich einmal als Funktion und benutzt die dann. Deine 'Treffer' Auswertungen könnten zb so aussehen
1 | void Treffer1 (void){ |
2 | |
3 | if( ADC_Read( Ziel_1_hit ) > 190 ) |
4 | PORTD &= ~(1<<Treffer_1); |
5 | }
|
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.
:
Bearbeitet durch User
> 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.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.