-         

Ergebnis 1 bis 2 von 2

Thema: Wetterstation

  1. #1

    Frage Wetterstation

    Anzeige

    Moin ich bin neu hier und haben mal ein paar Fragen zu meinem aktuellem Projekt. Habe in der Schule folgende Aufgabe bekommen:
    (würde meine Programmierkenntnisse als mittel bis anfänger einschätzen)

    Es soll eine Wetterstation installiert werden. Die Daten sollen durch den Pic16F887 aufgearbeitet werden. Entwickeln sie ein Programm, in welchem die Umweltdaten (Temperatur, Feuchtigkeit, Luftdruck) zur Anzeige gebracht werden.

    Angezeigt werden sollen:
    - Temperatur (0°C ...50°C ) 0,1 V pro °C
    - Luftfeuchtigkeit (0...99%) siehe Kennlinie
    - Luftdruck (950...1050mbar) siehe Kennlinie

    Folgende Sensoren bzw Module werden verwendet:
    -Temperatursensor PT100 (Schaltung muss noch entwickelt werden)
    -Feuchtigkeitsmodul, Sensor HIH 4000
    -Luftdruckmodul, Sensor MPX 4115A

    SCHALTERSTELLUNG FÜR DIE ANZEIGE:
    Schalter 1 Schalter 2 Funktion
    0 0 Automatikbetrieb
    0 1 Temperatur
    1 0 Luftfeuchtigkeit
    1 1 Luftdruck

    Festlegung der Eingänge:
    Eingabe Port
    Schalter 1 Port A, Bit 7
    Schalter 2 Port A, Bit 6
    Temperatursensor Port A, Bit 0 (Kanal 0)
    Feuchtigkeitssensor Port A, Bit 1 (Kanal 1)
    Luftdruck-Sensor Port A, Bit 2 (Kanal 2)

    Festlegung der Ausgänge:
    Ausgabe Port
    7-Segmentanzeige Port D
    Freigabe für 7-Seg. D0 (Einer) Port B, Bit 0
    Freigabe für 7-Seg. D1 (Zehner) Port B, Bit 1
    Freigabe für 7-Seg. D2 (Hundert) Port B, Bit 2
    Freigabe für 7-Seg. D3 (Tausend) Port B, Bit 3

    Hier sind meine Fragen:

    1. Erstmal wollte ich ganz gern wissen ob man dass überhaupt so machen kann? Und ob ich noch was an meinem Programmierstil verbessern kann? (nimm gerne Tips an)

    2. Ich bin mir nicht ganz sicher, ob ich das mit der Variablen Deklaration so machen kann? Habe noch nicht so viel mit cblock gearbeitet.?

    3. Kann ich zur Bankauswahl BANKSEL benutzen oder muss ich RP0 und RP1 setzen?

    4. Ich bin mir nicht sicher wie ich die Schritte einteilen kann, also bei der Temperatur z.B. soll ja von 0 bis 50 angezeigt werden und im Moment gibt er bei mir ja jeden Schritt aus, also 0 bis 255. Wenn man das aufteilt könnte man ja sagen das man den Wert durch 5 dividiert das müsste ungefähr hinkommen. Ich bin mir aber nicht sicher wie ich das umsetzen kann.

    5. Gibt es vllt für den Automatikbetrieb noch eine elegantere Lösung? Ich habe da ja jetzt nur alle drei hintereinander geschrieben mit nem kleinen delay.?


    (die schleife "delay2s" hab ich noch nicht, ist aber kein Problem)

    Vielen Dank schonmal im Vorraus. Lg IceBobo


    hier mein bisheriger Code:
    Code:
    ;***************************************
    ; Syntax zur PIC-Programmierung
    List P=16F887
    ; Einbindung der Includedatei
    #include <P16F887.INC>
    ; Konfigurationseinstellungen
    __CONFIG _CONFIG1, _INTRC_OSC_NOCLKOUT & _WDT_OFF & _PWRTE_OFF & _MCLRE_ON & _CP_OFF & _CPD_OFF & _BOR_OFF & _IESO_OFF & _FCMEN_OFF & _LVP_OFF & _DEBUG_OFF
    __CONFIG _CONFIG2, _BOR21V & _WRT_OFF
    ;**************************************
    
    
    ;Deklarieren der Variablen 
    
    	cblock 0x27
    					loop_A						;Variable für delay
    					loop_B						;Variable für delay
    					loop_C						;Variable für delay
    					Ergebnis					;Ergebnis der AD-Wandlung
    					old_level					;Merker für Pegel		
    					bin_val						;Hilfsvariable fuer BCD-Converter
    					dispval						;Variable fuer 7-Segment-Converter
    					bcd1						;Einerstellen
    					bcd10						;Zehnerstellen
    					bcd100						;Hunderterstellen
    					bcd1000						;Tausenderstellen
    	endc
    	
    ;**************************************
    ; PROGRAMMSTART
    	org		0x00					;Startadresse
    	goto 	init					;Springe zu "init"
    
    
    
    
    ;********************************************
    ; Grundinitialisierung
    
    init								
    	;bsf 	STATUS, RP0				;Setze Bit RP0	
    	;bsf	STATUS, RP1				;Setze Bit RP1
    	BANKSEL	ANSEL					;Bankauswahl
    	movlw	B'11111111'				;PORTA wird als Analog definiert
    	movwf	ANSEL
    
    	BANKSEL	ANSELH					;Bankauswahl
    	clrf	ANSELH					;PORTB wird als Digital definiert
    
    	BANKSEL	TRISA					;Bankauswahl
    	movlw	B'11111111'				;PORTA wird als Eingang definiert
    	movwf	TRISA	
    	clrf	TRISB					;PORTB wird als Ausgang definiert
    	clrf	TRISD					;PORTD wird als Ausgang definiert
    	clrf	ADCON1					;loesche Register ADCON1
    
    	BANKSEL	ADCON0					;Bankauswahl
    	movlw	B'01000001'				;Einstellungen für Register ADCON0
    	movwf	ADCON0					;Einstellungen in Register ADCON0 laden
    			
    	clrf	PORTA					;PORTA loeschen
    	clrf	PORTB					;PORTB loeschen
    	clrf	PORTD					;PORTD loeschen
    
    	goto	main					;springe zu "main"
    
    
    ;*************************************************************************************
    
    
    
    ;Hauptprogramm
    
    main
    
    	btfss	PORTA, 7				;Abfrage Schalter 1, springe wenn gesetzt
    	goto	Schalter1_nein			;springe zu "Schalter1_nein"	
    	goto	Schalter1_ja			;springe zu "Schalter1_ja"
    
    Schalter1_nein
    
    	btfss	PORTA, 6				;Abfrage Schalter 2, springe wenn gesetzt
    	goto	Automatik				;springe zu "Automatik"
    	goto	Temperatur				;springe zu "Temperatur"
    
    Schalter1_ja
    
    	btfss	PORTA, 6				;Abfrage Schalter 2, springe wenn gesetzt
    	goto	Luftfeuchtigkeit		;springe zu "Luftfeuchtigkeit"
    	goto	Luftdruck				;springe zu "Luftdruck"
    
    Temperatur
    
    	BANKSEL	ADCON1					;Bankauswahl
    	movlw	B'00000000'				;Ergebnis = linksbündig
    	movwf	ADCON1
    
    	BANKSEL	ADCON0					;Bankauswahl
    	movlw 	B'01000001'				;FOSC/8---Kanal 0---AD-Wandlung aktiviert
    	movwf	ADCON0
    	bsf		ADCON0, 1				;starte AD-Wandlung
    	btfsc	ADCON0, 1				;fertig?
    	goto	$-1						;sonst warte
    
    ;Speichern
    	movf	ADRESH, w				;kopiere Inhalt aus ADRESH in Arbeitsregister
    	movwf	Ergebnis				;schreibe Inhalt aus Arbeitsregister in "Ergebnis"
    	
    	goto 	main					;springe zu "main"
    
    Luftfeuchtigkeit
    
    	BANKSEL	ADCON1					;Bankauswahl
    	movlw	B'00000000'				;Ergebnis = linksbündig
    	movwf	ADCON1
    
    	BANKSEL	ADCON0					;Bankauswahl
    	movlw 	B'01000101'				;FOSC/8---Kanal 1---AD-Wandlung aktiviert
    	movwf	ADCON0
    	bsf		ADCON0, 1				;starte AD-Wandlung
    	btfsc	ADCON0, 1				;fertig?
    	goto	$-1						;sonst warte
    
    ;Speichern
    	movf	ADRESH, w				;kopiere Inhalt aus ADRESH in Arbeitsregister
    	movwf	Ergebnis				;schreibe Inhalt aus Arbeitsregister in "Ergebnis"
    	
    	goto 	main					;springe zu "main"
    
    Luftdruck
    
    	BANKSEL	ADCON1					;Bankauswahl
    	movlw	B'00000000'				;Ergebnis = linksbündig
    	movwf	ADCON1
    
    	BANKSEL	ADCON0					;Bankauswahl
    	movlw 	B'01001001'				;FOSC/8---Kanal 2---AD-Wandlung aktiviert
    	movwf	ADCON0
    	bsf		ADCON0, 1				;starte AD-Wandlung
    	btfsc	ADCON0, 1				;fertig?
    	goto	$-1						;sonst warte
    
    ;Speichern
    	movf	ADRESH, w				;kopiere Inhalt aus ADRESH in Arbeitsregister
    	movwf	Ergebnis				;schreibe Inhalt aus Arbeitsregister in "Ergebnis"
    	
    	goto 	main					;springe zu "main"
    
    Automatik
    
    ;***Temperatur***
    	BANKSEL	ADCON1					;Bankauswahl
    	movlw	B'00000000'				;Ergebnis = linksbündig
    	movwf	ADCON1
    
    	BANKSEL	ADCON0					;Bankauswahl
    	movlw 	B'01000001'				;FOSC/8---Kanal 0---AD-Wandlung aktiviert
    	movwf	ADCON0
    	bsf		ADCON0, 1				;starte AD-Wandlung
    	btfsc	ADCON0, 1				;fertig?
    	goto	$-1						;sonst warte
    
    	;Speichern
    	movf	ADRESH, w				;kopiere Inhalt aus ADRESH in Arbeitsregister
    	movwf	Ergebnis				;schreibe Inhalt aus Arbeitsregister in "Ergebnis"
    
    	call	delay2s
    
    ;***Luftfeuchtigkeit***
    	BANKSEL	ADCON1					;Bankauswahl
    	movlw	B'00000000'				;Ergebnis = linksbündig
    	movwf	ADCON1
    
    	BANKSEL	ADCON0					;Bankauswahl
    	movlw 	B'01000101'				;FOSC/8---Kanal 1---AD-Wandlung aktiviert
    	movwf	ADCON0
    	bsf		ADCON0, 1				;starte AD-Wandlung
    	btfsc	ADCON0, 1				;fertig?
    	goto	$-1						;sonst warte
    
    	;Speichern
    	movf	ADRESH, w				;kopiere Inhalt aus ADRESH in Arbeitsregister
    	movwf	Ergebnis				;schreibe Inhalt aus Arbeitsregister in "Ergebnis"
    
    	call	delay2s
    	
    ;***Luftdruck***
    	BANKSEL	ADCON1					;Bankauswahl
    	movlw	B'00000000'				;Ergebnis = linksbündig
    	movwf	ADCON1
    
    	BANKSEL	ADCON0					;Bankauswahl
    	movlw 	B'01001001'				;FOSC/8---Kanal 2---AD-Wandlung aktiviert
    	movwf	ADCON0
    	bsf		ADCON0, 1				;starte AD-Wandlung
    	btfsc	ADCON0, 1				;fertig?
    	goto	$-1						;sonst warte
    
    ;Speichern
    	movf	ADRESH, w				;kopiere Inhalt aus ADRESH in Arbeitsregister
    	movwf	Ergebnis				;schreibe Inhalt aus Arbeitsregister in "Ergebnis"
    
    	call	delay2s
    
    	goto 	main
    
    
    	
    
    
    delay500us
    	movlw 	D'5' 					;schreibe "5" in "loop_A" 
    	movwf 	loop_A 
    z6 
    	movlw 	D'50' 					;schreibe "50" in "loop_B" 
    	movwf 	loop_B 
    z5 
    	movlw 	D'50' 					;schreibe "50" in "loop_C" 	
    	movwf 	loop_C 
    z4 	
    	decfsz 	loop_C 					;ziehe "1" von "loop_C" ab 
    	goto 	z4
    	decfsz 	loop_B 					;ziehe "1" von "loop_B" ab 
    	goto 	z5
    	decfsz 	loop_A 					;ziehe "1" von "loop_A" ab 
    	goto 	z6
    
    return
    
    
    ;Unterprogramm Displayausgabe mit BCD dreistellig (sr_display, sr_conv7seg)
    
    ; ------------------------------------------------------------------------
    ; Display Ausgabe auf 7-Segmentdisplay mit BCD dreistellig
    ; ------------------------------------------------------------------------
    sr_display
    		clrf	bcd1000				; bcd10000 loeschen
    		clrf   	bcd100				; bcd100 loeschen
    		clrf	bcd10				; bcd10 loeschen
    		clrf 	bcd1				; bcd1 loeschen
    		movf	Ergebnis,w			; Ergebnis in w laden
    		movwf 	bin_val				; w nach bin_val
    
    									; Division durch 1000
    		movlw	d'1000' 			; lade w mit 1000
    loop1000
    		subwf	bin_val,1			; subtrahiere 1000 von bin_val, Resultat nach bin_val
    		btfss	STATUS,C			; Resultat < 1000 ?
    		goto   	end1000				; ja -> dann 100er Stelle 
    		incf	bcd1000				; bcd1000 + 1
    		goto	loop1000			; naechster Durchgang
    end1000
    		addwf	bin_val,1			; addiere 1000 zu bin_val, Korrektur der letzten Pruefung
    									; Division durch 100
    		movlw	d'100' 				; lade w mit 100
    loop100
    		subwf	bin_val,1			; subtrahiere 100 von bin_val, Resultat nach bin_val
    		btfss	STATUS,C			; Resultat < 100 ?
    		goto   	end100				; ja -> dann 10er Stelle 
    		incf	bcd100				; bcd100 + 1
    		goto	loop100				; naechster Durchgang
    end100
    		addwf	bin_val,1			; addiere 100 zu bin_val, Korrektur der letzten Pruefung
    									; Division durch 10
    		movlw 	d'10' 				; lade w mit 10
    loop10
    		subwf	bin_val,1			; subtrahiere 10 von bin_val, Resultat nach bin_val
    		btfss   STATUS,C			; Resultat < 10 ?
    		goto   	end10				; ja -> dann 1er Stelle 
    		incf	bcd10				; war groesser oder gleich 10, dann bcd10 + 1
    		goto	loop10				; naechster Durchgang
    end10
    		addwf	bin_val,0			; addiere 10 zu bin_val, Korrektur der letzten Pruefung
    		movwf 	bcd1				; Rest ist gleich Einerstelle
    
    		movf	bcd1,0				; Uebergebe Einerstelle an Converter
    		movwf	dispval
    		call	sr_conv7seg			; Convertiere nach 7-Segment
    		bsf		PORTB,0				; Schreibe nach Einerstelle
    		call	delay500us
    		bcf		PORTB,0
    		call	delay500us
    
    		movf	bcd10,w				; Uebergebe Zehnerstelle an Converter
    		movwf	dispval
    		call	sr_conv7seg			; Convertiere nach 7-Segment
    		bsf		PORTB,1				; Schreibe nach Zehnerstelle
    		call	delay500us
    		bcf		PORTB,1
    		call	delay500us
    
    		movf	bcd100,w			; Uebergebe Hunderterstelle an Converter
    		movwf	dispval
    		call	sr_conv7seg			; Convertiere nach 7-Segment
    		bsf		PORTB,2				; Schreibe nach Hunderterstelle
    		call	delay500us
    		bcf		PORTB,2
    		call	delay500us
    
    		movf	bcd1000,w			; Uebergebe Tausenderterstelle an Converter
    		movwf	dispval
    		call	sr_conv7seg			; Convertiere nach 7-Segment
    		bsf		PORTB,3				; Schreibe nach Tausenderterstelle
    		call	delay500us
    		bcf		PORTB,3
    
    return
    
    
    
    
    
    
    ; ------------------------------------------------------------------------
    ; 7-Segment Display Converter
    ; ------------------------------------------------------------------------
    
    sr_conv7seg
    		movlw		b'00111111'	; Displaycode für 0 
    		movwf		PORTD		; nach PORTD
    		movf		dispval,0
    		sublw		D'0'		; subtrahiere den Pruefwert = 0
    		btfsc		STATUS,Z	; wenn dispval = 0, dann Z=1?
    		goto		write_sign	; ja, dann springe zur Ausgabe
    								; nein, dann pruefe nächsten Wert
    
    		movlw		b'00000110'	; Displaycode für 1 
    		movwf		PORTD		; nach PORTD	
    		movf		dispval,0
    		sublw		D'1'		; subtrahiere den Pruefwert = 1		; 
    		btfsc		STATUS,Z	; wenn dispval = 1, dann Z=1?
    		goto		write_sign	; ja, dann springe zur Ausgabe
    								; nein, pruefe nächsten Wert
    
    		movlw		b'01011011'	; Displaycode für 2
    		movwf		PORTD		
    		movf		dispval,0
    		sublw		D'2'		; 
    		btfsc		STATUS,Z
    		goto		write_sign
    
    		movlw		b'01001111'	; Displaycode für 3
    		movwf		PORTD	
    		movf		dispval,0
    		sublw		D'3'		; 
    		btfsc		STATUS,Z
    		goto		write_sign
    
    		movlw		b'01100110'	; Displaycode für 4
    		movwf		PORTD		
    		movf		dispval,0
    		sublw		D'4'		; 
    		btfsc		STATUS,Z
    		goto		write_sign
    
    		movlw		b'01101101'	; Displaycode für 5
    		movwf		PORTD		
    		movf		dispval,0
    		sublw		D'5'		; 
    		btfsc		STATUS,Z
    		goto		write_sign
    
    		movlw		b'01111101'	; Displaycode für 6
    		movwf		PORTD		
    		movf		dispval,0
    		sublw		D'6'		; 
    		btfsc		STATUS,Z
    		goto		write_sign
    
    		movlw		b'00000111'	; Displaycode für 7
    		movwf		PORTD		
    		movf		dispval,0
    		sublw		D'7'		; 
    		btfsc		STATUS,Z
    		goto		write_sign
    
    
    		movlw		b'01111111'	; Displaycode für 8
    		movwf		PORTD	
    		movf		dispval,0
    		sublw		D'8'		; 
    		btfsc		STATUS,Z
    		goto		write_sign
    
    		movlw		b'01101111'	; Displaycode für 9
    		movwf		PORTD		
    		movf		dispval,0
    		sublw		D'9'		; 
    		btfsc		STATUS,Z
    		goto		write_sign
    		
    write_sign
    
    		return

  2. #2
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    03.09.2009
    Ort
    Berlin (Mariendorf)
    Beiträge
    938
    Hallo icebobo.

    Erstmal herzlich willkommen im Forum und viel Erfolg mit deinem Projekt.

    Zitat Zitat von icebobo Beitrag anzeigen
    1. Erstmal wollte ich ganz gern wissen ob man dass überhaupt so machen kann? Und ob ich noch was an meinem Programmierstil verbessern kann? (nimm gerne Tips an)
    Sieht ziemlich linear aus, wenig optisch gegliedert; aber das ist Geschmackssache. Was gar nicht geht: d'1000' von einem Byte abzuziehen. Dein Controller arbeitet mit 8bit-Werten! Ich will mir gar nicht ausmalen, was der Preprozessor/Assembler aus einem d'1000' macht ... Du wirst dir eine 16bit-Subtraktionsroutine schreiben oder suchen müssen. Es gibt Application Notes von Microchip auch für mathematische Aufgabenstellungen, jeweils auf der Hauptseite für diesen Prozessor. Und zieh dir auch Beschreibungen über die "PIC-Fallen" der PIC16er Typen rein, das kann viel Zeit und Frust sparen. Ein gewisser 'sprut' hat das irgendwo auf seiner Website recht anschaulich gemacht.

    Zitat Zitat von icebobo Beitrag anzeigen
    2. Ich bin mir nicht ganz sicher, ob ich das mit der Variablen Deklaration so machen kann? Habe noch nicht so viel mit cblock gearbeitet.?
    Ich noch gar nicht, aber das sieht nach einer hilfreichen Direktive aus. Das werde ich für mich selbst nun auch ergründen.

    Zitat Zitat von icebobo Beitrag anzeigen
    3. Kann ich zur Bankauswahl BANKSEL benutzen oder muss ich RP0 und RP1 setzen?
    BANKSEL erzeugt m.W. immer zwei BSF / BCF-Befehle für RP0 und RP1 und macht den Code besser portierbar und sicherer als das explizite einstellen von RP0, RP1.

    Zitat Zitat von icebobo Beitrag anzeigen
    4. Ich bin mir nicht sicher wie ich die Schritte einteilen kann, also bei der Temperatur z.B. soll ja von 0 bis 50 angezeigt werden und im Moment gibt er bei mir ja jeden Schritt aus, also 0 bis 255. Wenn man das aufteilt könnte man ja sagen das man den Wert durch 5 dividiert das müsste ungefähr hinkommen. Ich bin mir aber nicht sicher wie ich das umsetzen kann.
    Wenn du bereits 0,1V je Grad Celsius angeliefert bekommst, hast du schon gewonnen. Trimme ggf. die Referenzspannung des ADC auf 2,55V, damit du direkt in Volt interpretierbare ADC-Zahlenwerte bekommst. Du hast kein Rechenzeitproblem, also zähle, wie oft du vom ADC-Ergebnis 5 abziehen kannst (16bit-Subtraktion!) ohne negativ zu werden. Der Rundenzähler ist dann dein Divisionsergebnis. Evtl. noch eine Rundungsbetrachtung des Restwertes.

    Zitat Zitat von icebobo Beitrag anzeigen
    5. Gibt es vllt für den Automatikbetrieb noch eine elegantere Lösung? Ich habe da ja jetzt nur alle drei hintereinander geschrieben mit nem kleinen delay.?
    "Elegant" kann viel heißen: (a) gut nachvollziehbar, auch noch nach vier Wochen(!) oder (b) gut erweiterbar oder (c) gut umbaubar weil modular oder manchmal einfach nur (d) bewundernswert kompakt.
    "Keep it simple" ist zunächst eine gute Herangehensweise. Zu fragen wäre noch, ob ein Moduswechsel auf Einzeldarstellung erst erfolgen braucht, wenn der Automatikzyklus durchgelaufen ist oder ob jederzeit eine sofortige Umschaltung gefordert wird. Wenn jede einzelne Mess- und Anzeigeaufgabe als Prozedur (call) gegliedert ist, kann man nach jedem Schritt auf Tastendrücke abfragen und die Automatik beenden.

Ähnliche Themen

  1. Wetterstation
    Von Maxxtro im Forum Vorstellung+Bilder+Ideen zu geplanten eigenen Projekten/Bots
    Antworten: 7
    Letzter Beitrag: 23.02.2009, 21:09
  2. Wetterstation
    Von theborg im Forum Vorstellung+Bilder+Ideen zu geplanten eigenen Projekten/Bots
    Antworten: 6
    Letzter Beitrag: 18.09.2007, 11:34
  3. wetterstation
    Von Nr. 5 im Forum Vorstellung+Bilder+Ideen zu geplanten eigenen Projekten/Bots
    Antworten: 3
    Letzter Beitrag: 23.07.2006, 14:29
  4. Wetterstation - Windgeschwindigkeitsmesser
    Von RafiK im Forum Sensoren / Sensorik
    Antworten: 2
    Letzter Beitrag: 02.10.2004, 20:07
  5. wetterstation
    Von GorchFock im Forum C - Programmierung (GCC u.a.)
    Antworten: 1
    Letzter Beitrag: 05.08.2004, 13:46

Berechtigungen

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