-
        

Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 11

Thema: bräuchte hilfe zu sporadischen fehlern

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    22.02.2007
    Beiträge
    26

    bräuchte hilfe zu sporadischen fehlern

    Anzeige

    Morgen leute!!!!

    also, ich fang am besten mal von vorne an. Ich habe für meinen vater und dessen Hühner eine automatische klappe gebastelt, die auf Helligkeit reagiert und die Klappe entsprechend bewegt. hat seit rund 2 monaten alles wunderbar funktioniert, kein huhn war bisher unter der klappe o.ä.
    nun seit geraumer zeit, macht die klappe allerdings komische gestalten. Immer (nicht immer, geht mal 2-5 tage gut, aber immer in der herabbewegung) beim herabfahren, reagiert der ATmega8 nichtmehr. der motor dreht munter weiter und nur ein ausschalten der schaltung bringt diesen zum stoppen. Ich hab mittlerweile den µC, den LDR und die komplette Schaltung getauscht, ohne erfolg.

    zum aufbau am besten mal ein Schaltplan:
    http://img44.imageshack.us/img44/4396/huehnerklappe.png
    ich denke, die anschlussbelegung sollte klar sein, Motor, LDR und Endschalter als abschaltende begrenzung.

    zum Programm:
    ich erkläre mal kurz, was ich mir dabei gedacht habe
    also, ich setze den C für rund 4 min schlafen, und überprüfe dann den Spannungswert am ADC. sollte eine änderung eingetreten sein, wird entsprechend reagiert.
    haupt:
    in "haupt" wird die Spannung abgefragt und bei einer änderung entsprechend verzweigt.
    slep:
    legt den C für 4 min schlafen.
    auf/ab:
    setzt die ausgänge entsprechend fürs hinauf/abfahren und wartet bis ein schalter auslöst oder die zeit für die bewegung beendet ist (sicherheit).
    entprellen:
    entprellt die mechanischen Endschalter. hierfür wird auch die software-warteschleife ms10 benötigt.
    zeitaktiv_auf/ab:
    hier wird der Timer gesetzt, solange die bewegung maximal dauern darf (für hoch und runter unterschiedliche zeiten, weil der auffahren länger dauert)
    timer0:
    ist die reaktion auf die abgelaufene zeit ( ausgänge abschalten, und timer rücksetzen)

    daher kommt auch meine annahme das der µC abschmiert, weil er weder auf die zeit, noch auf die endschalter reagiert. und die ausgäng bleiben tatsächlich bis zum abschalten gesetzt, ich habe entsprechend LED´s dran gelötet.
    habe das programm nun schon nach nem überlaufenden stack hin untersucht, leider nichts gefunden. vielleicht schaut mal schnell ein profi drüber ob er einen fehler findet, bzw. ob er eine andere vermutung hat.
    ich danke deshalb schonmal im voraus für eure hilfe, bin gerade leicht am verzweifeln =P

    Code:
    .equ zeit = 1700					;für die MS10 routine, 10ms warteschleife
    .equ schleife_durch = 10 ;10				;für entprellroutine durchläufe
    .equ schleife_sleep = 4	 ;4			;schleifendurchläufe für timer. 1 durchlauf = 67 sekunden.
    .equ slep_tcnt_vorladen = 1		 	;zum vorladen des register tcnt des timers 1, um feiner abstufungen zu erreichen. Normal=0
    .equ adc_wert = 130		;100		;vergleichswert für adc und lichtsensor
    .equ Zeit_hochfahren = 33 ;33		;Wert zur einstellung der Zeit, die für das hochfahren der klappe verantwortlich ist.
    .equ Zeit_runterfahren = 24 ;24		;wert zur einstellung der Zeit für das Herunterfahren
    									;4 => 1 sec. (1zyklus = 261,1 ms)
    
    ; = 4.22V am LDR = 21.14Uhr am 24.07.09
    ;   4.66V am LDR = 21.23Uhr
    ;	differenz rund 0.44 V
    
    ;***definitionsdatei***
    
    .include "m8def.inc"
    
    ;***interrupt adressen***
    
    .org 0x000	rjmp reset		;Programm start
    ;.org 0x001	rjmp stop		;Näherungsschalter
    ;.org 0x002	rjmp aus		;Interrupt schalter
    .org 0x008  rjmp timer		;Timer für sicherheit, wird aktiviert nach dem schalten der ausgänge
    .org 0x009  rjmp timer0		;Timer0 für das hoch/runterfahren der tür
    
    		; Stack initialisieren
    reset:
    		ldi 	r16, LOW(RAMEND)
    		out 	SPL, r16
    		ldi 	r16, HIGH(RAMEND)
    		out 	SPH, r16
    
    		;Ein/Ausgänge konfigurieren
    
    		ser		r16			;ausgang
    		out		DDRB, r16
    		clr 	r16			;Eingang
    		out 	DDRC, r16	
    		out 	DDRD, r16
    
    		;sleep mode aktivieren
    		
    		ldi		r16, 0b10000000;	0b10001111
    		out		MCUCR, r16
    		;ldi		r16, 0b00000001
    		;out		GICR, r16
    
    		;variable für ersten durchlauf ins register kopieren
    		ldi		r16, 1
    		mov		r2, r16
    
    		sei					;interrupts frei
    
    Haupt:	
    
    		;ADC konfig, ADC0 
    
    		ldi 	r16, 0b01100000 
    		out 	admux, r16
    		ldi		r16, 0b11000011
    		out		adcsra, r16
    	adcrun:	
    		in		r10, adcsra
    		sbrc	r10, 6
    		rjmp 	adcrun
    
    		;adc werte in reg. schreiben
    
    		in		r17, ADCL
    		in		r18, ADCH
    
       ;ACHTUNG, unteren WERT ebenfalls ändern
    		cpi		r18, adc_wert    ;hier einstellwert für sreg
    		in		r16, SREG ;SREG speichern
    		andi	r16, 0b00000001
    		mov		r1, r16
    		eor		r1, r0
    		mov		r0, r16
    		sbrc	r2, 0
    		rjmp	erstedurchgang
    		breq	slep		
       ;ACHTUNG, oberen Wert ebenfalls ändern
    		cpi		r18, adc_wert 	;hier einstellwert
    		brlo 	ab1			;hier tor zu
    		brsh	auf1		;hier tor auf
    		rjmp 	slep
    ;unterprogramme
    
    slep:							;schlafen legen, und alle 10 min wieder wecken
    		ldi		r16, 0b00000101		;teiler 
    		out		TCCR1B, r16
    		ldi		r16, 0b00000100
    		out		TIMSK, r16
    		ldi		r30, schleife_sleep			;schleifendurchläufe für wartezeit
    		clr		r31
    	slep1:	
    		;wdr									;watchdog reset
    		ldi		r16, low(slep_tcnt_vorladen)		 		;63535 ins register laden = 2 sekunden
    		ldi		r17, high(slep_tcnt_vorladen)					
    		out		TCNT1H, r17
    		out		TCNT1L, r16
    		sleep
    		nop
    		tst		r30
    		brne	slep1
    		rjmp	haupt 
    		
    erstedurchgang:
    
    		clr		r2
    		rjmp	haupt
    
    auf1:
    		ldi		r16, 0b00000101
    		out		PORTB, r16
    		rcall	zeitaktiv_auf			;Timer1 für Sicherheitszeit aktivieren
    		;warten bis schalter betätigt
    	warten1:	
    		sbrc	r31, 0				;wenn timer1 interrupt fahrt beendet
    		rjmp 	slep				;dann springt wieder nach slep zurück
    		in		r16, PIND
    		sbrc	r16, 3
    		rjmp	entprellen
    		rjmp	warten1
    		
    ab1:	
    		ldi		r16, 0b00000110
    		out		PORTB, r16
    		rcall	zeitaktiv_ab			;Timer1 für Sicherheitszeit aktivieren
    		;warten bis schalter betätigt
    	warten2:	
    		sbrc	r31, 0				;wenn timer1 interrupt fahrt beendet
    		rjmp 	slep				;dann springt wieder nach slep zurück
    		in		r16, PIND
    		sbrc	r16, 2
    		rjmp	entprellen
    		rjmp	warten2
    
    ;entprell routine
    entprellen:
    		push	r16
    		ldi		r17, schleife_durch			;schleifendurchläufe
    		in 		r16, PIND
    		mov		r3, r16
    	aus1:
    		in		r16, PIND
    		mov		r2, r16
    		eor		r2, r3
    		mov		r3, r16
    		push	r16
    		rcall	ms10
    		pop		r16
    		dec		r17
    		tst		r17
    		brne	aus1		
    		sbrc	r16, 3
    		rjmp	aus2
    		sbrc    r16, 2
    		rjmp	aus2
    		rcall	ms10
    		clr		r17
    		pop		r16
    		rjmp	slep
    	aus2:
    		clr		r16
    		clr		r17
    		clr		r19
    		out		PORTB, r16
    		out		TCCR0, r16		;timer deaktivieren
    		out		TCNT0, r16		;timer0 zählregister nullen
    		pop		r16
    		rjmp 	slep
    
    ;timer0 fürs bewegen der Tür aktivieren
    zeitaktiv_auf:
    		;r29 zum herunterzählen beladen.
    		ldi		r29, zeit_hochfahren
    		ldi		r16, 0b00000101		;teiler 
    		out		TCCR0, r16
    		ldi		r16, 0b00000001		;interrupt starten
    		out		TIMSK, r16
    		ret
    zeitaktiv_ab:
    		;r29 zum herunterzählen beladen.
    		ldi		r29, zeit_runterfahren
    		ldi		r16, 0b00000101		;teiler 
    		out		TCCR0, r16
    		ldi		r16, 0b00000001		;interrupt starten
    		out		TIMSK, r16
    		ret
    	
    
    ;***********Warteschleife*********
    
    ms10:							;taster entprellen
    		;wdr
    		push	r17
    		push	r18
    		ldi 	r16, low(zeit)
    		ldi 	r17, byte2(zeit)
    		ldi 	r18, byte3(zeit)
    	ms101:
    		subi 	r16, low(1)			;1 Takt
        	sbci 	r17, byte2(1)		;1 Takt
        	sbci 	r18, byte3(1)		;1 Takt
    		sbrs 	r18, 0				;1 takt
    		breq 	ms102				;
    		rjmp	ms101				;2 takte
    	ms102:	
    		pop		r18
    		pop		r17
    		ret
    	
    
    ;*************************interrupt handler***************************
    ;sleep-timer, 16 bit
    timer:
    		dec		r30
    		reti
    
    ;nach abgelaufener zeit motor aus, timer0, 8bit	
    timer0:
    		dec		r29
    		tst		r29
    		breq	timer0_stop
    		reti
    	timer0_stop:
    		push	r16
    		clr		r16
    		out		PORTB, r16
    		out		TCCR0, r16
    		out		TCNT0, r16
    		sbr		r31,1
    		pop		r16
    		reti

  2. #2
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    28.10.2004
    Ort
    Baoding
    Alter
    37
    Beiträge
    687
    Ohne das Programm zu sehr angeschaut zu haben : Wenn das nur passiert wenn der Motor lauft : brown out dedector und Watchdog aktivieren....kann nen Programmfehler nicht verhindern aber verhindert das sich der µC aufhängt

    Was hat das Ding für ne Spannungsversorgung? Batterien?
    Signatur??? kann ich mir nicht leisten!!!

  3. #3
    Erfahrener Benutzer Robotik Visionär
    Registriert seit
    26.11.2005
    Ort
    bei Uelzen (Niedersachsen)
    Beiträge
    7.942
    Bei der Schaltung ist die Versorgung von AVCC (Pin20) falsch:

    Hier sollte AVCC direkt mit VCC verbunden sein, also auch +5 V vom Regler kriegen. Dazu noch ein 2 ter Enkoppelkondensator.

    Der Widerstand R2 ist ganz fasch, der zieht noch extra Strom aus dem Pin. Der Kondensator C5 ist so auch eher Schädlich, denn Störungen vor dem Regler werden so nach AVCC eingekoppelt. Der Kondensator gehört da hin wo R2 ist.

    Gerade beim Mega8 kann das so gut gehen, muß es aber nicht.

    An die Versorgung vor den Regler gehört noch ein Elko. Je nach Motor wären so etwa 1000-2200 µF angebracht.
    Wenn der Motor stark stört, wäre ein extra RC Glied (z.B. 100 Ohm, 100 µF) vor dem Spannungsregler angebracht, ggf. statt dem Widerstand auch eine Diode.

    EDIT:
    Bei der Software ist auch noch ein Fehler drin:
    Bei den Interrupts muß man noch das Status-register (SREG) retten. Wenn man das nicht mancht, kann man leicht selten Auftretende Fehler bekommen, weil gelegentlich das Hauptprogramm nicht so läuft wie es soll, weil sich unerwarte das Statusregister ändert. Auch mit den anderen Registern muß man ggf. aufpassen, daß man nicht Registser verändert, die auch im Hauptprgramm benutzt werden für etwas anderes als ein "globale Variable".

  4. #4
    Neuer Benutzer Öfters hier
    Registriert seit
    22.02.2007
    Beiträge
    26
    hmm, ich habe versuche mit dem wdr durchgeführt, allerdings bei 4 min wartezeit wieder vorworfen, weil ich es nicht hinbekommen habe.
    aber wenn ich den wdr nur bei einer bewegung starte, könnte es funktionieren. danke, ich werds mal ausprobieren.
    @ besserwessi:
    meinst du so?
    http://img9.imageshack.us/img9/2203/huehnerklappe2.png

    und was ich noch vergessen habe zu sagen.
    ich habe vor 4 tagen einen 50kohm widerstand parallel zum LDR gesetzt, da der ldr bei dunkelheit im bereich von 1 Mohm war und mein poti (mit aktuell 50kohm) gnadenlos zu klein war und die einstelllung sehr darunter litt.
    seitdem ging es dann auch wieder etwas besser, 3 tage, dann war wieder alles shice.

    gruß

  5. #5
    Erfahrener Benutzer Robotik Visionär
    Registriert seit
    26.11.2005
    Ort
    bei Uelzen (Niedersachsen)
    Beiträge
    7.942
    Schon besser die Schaltung.
    Noch C6 duch einen Widerstand unter 100 Ohm oder eine Induktivität ersetzen, dann ist es gut.

    Ich sehe gerade: der LDR geht am 12 V , das ist auch nicht so gut. Besser wäre es den LDR an die stabilen 5 V zu klemmen. Der Widerstand am LDR sollte nichts mit dem eigentlichen Problem zu tun haben. Wenn der Poti zu klein ist, dann halt ein Widerstand in Reihe zum Poti.

    Sollen unten die 12 V wirklich an den ISP Anschluß ? Das ist ganz und gar nicht gut !

  6. #6
    Neuer Benutzer Öfters hier
    Registriert seit
    22.02.2007
    Beiträge
    26
    nein, natürlich nicht. das mit den 12 V hab ich auf dem plan total vermurkst. effektiv hängt nur der motor und der regler an den 12V, der rest (alles was mit dem C zu tun hat) an den 5V.
    aber kann die falsche beschaltung des ADC den C durcheinander bringen?
    ich werde am wochenende mal den tipp von Rofo umsetzen und nocheinmal probieren.

  7. #7
    Erfahrener Benutzer Robotik Visionär
    Registriert seit
    26.11.2005
    Ort
    bei Uelzen (Niedersachsen)
    Beiträge
    7.942
    Der Anschluß AVCC ist nicht nur für den ADC. Ein falsche Spannung da kann den ganzen µC blockieren und im schlimmsten fall sogar zerstören.


    Was man auf alle Fälle ändern sollte, ist die Interruptsroutine im Programm. Ein nicht gesichertes SREG führt gerade zu eher seltenen und schwer zu findenden Fehlern

  8. #8
    Neuer Benutzer Öfters hier
    Registriert seit
    22.02.2007
    Beiträge
    26
    du meinst also, ich soll das SREG in den Interruptdingern speichern und wieder laden?

  9. #9
    Erfahrener Benutzer Robotik Visionär
    Registriert seit
    26.11.2005
    Ort
    bei Uelzen (Niedersachsen)
    Beiträge
    7.942
    Das sichern des SREG in einer ISR ist absolut standart und fast ein muß, vor allem für Anfänger. Es gibt nur ganz wenige Ausnahmen wo es auch mal ohne geht.
    Hier werden je nur wenige Register benutzt und es reicht das SREG in einem dafür reservierten Register zu speicher.

  10. #10
    Neuer Benutzer Öfters hier
    Registriert seit
    22.02.2007
    Beiträge
    26
    so, kleine zwischenmeldung:
    habe die änderungen nun so vorgenommen, bis auf den Watchdog, der hatte irgendwie nicht funktioniert. auf jeden fall speichere ich aber das SREG in den ISR. heute hats funktioniert, mal sehen obs das morgen auch noch so tut, ich werde berichten.
    danke nochmal für deine/eure hilfe.

Seite 1 von 2 12 LetzteLetzte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •