1. Aufgabe
Auswertung und Anzeige der Daten-Rahmen des PC-Wettersensor-Empfänger von ELV
(Best.-Nr.: 50-390-61, Preis 35.90€) in Verbindung mit dem Display-Atmel. In jeweils einer Zeile wird der Typ
(I=Innen, A=Außen, R=Regen, W=Wind, H=Helligkeit) mit der Adresse des
jeweiligen Sensors sowie die entsprechenden Sensorwerte angezeigt. Da hier nur
ein 2-zeiliges Display verwendet wird, werden in der ersten Zeile die Innen- und
Außensensoren angezeigt und in der 2. Zeile alle anderen Sensoren. Die Anzeige
erfolgt sofort bei Empfang des Daten-Rahmes. Um die
Speicherplatz-"fressenden" LCD-Befehle zu reduzieren werden die
auszugebenden Zeilen in dem TEXT-String zusammengesetzt und mit Leerzeichen
aufgefüllt (erspart das Löschen der betreffenden Zeile).
2. Programm
'***************************************************************************************** |
'
Name
' Author
' Purpose
' Version
' Compiler
' Hardware
'
' Bytes
' Chiptype
' Bemerkung
'History
|
: wx27.bas
: DG1XPZ
: WX-Receiver
: V0.27www
: BasCom AVR 1.11.7.7
: - ELV-Wettersensorempfänger an RS232
- LC-Display 24 * 2
: 2618
: 90S4433/Mega8 u.a.
: Die Außen- u. Innensensoren werden, bei Auftreten, immer
in der 1. Zeile angezeigt. Alle anderen Sensoren werden
in der 2. Zeile angezeigt.
V0.26: Bug in Subroutine Punkt (Berechnung negativer Temp)
(Dank an Wolfgang DL7WA) |
|
'***************************************************************************************** |
'regfile = "m8def.dat"
'ATmega8
'$regfile = "4433def.dat" 'AT90S4433
$crystal = 4000000
'Fuse-Bit bei M8: 0001=1MHz 0010=2MHz 0011=4MHz 0100=8MHz
Config Lcd = 24 * 2 |
Config Lcdpin = Pin , Db7 = Portb.2 , Db6 = Portb.4 , Db5 = Portb.5 , Db4 = Portc.2 , E = Portc.3 , Rs = Portb.3 |
'folgende Zeile nicht für At90S4433
Config Com1 = Dummy , Databits = 8 , Parity = Odd , Stopbits = 2 , Synchrone = 0 , Clockpol = 0 |
$baud = 19200
'nur bei 0.92/1.23/1.843/4/8MHz sauber möglich
Declare Sub Addbyte(a As Byte , B As Byte) 'Deklaration Sub-Routine
Dim Wx_frame(6) As Byte
'enthält gesamtes WX-Framepaket
Dim I As Byte
'Zählvariable
Dim Wx_count As Byte
'wx_framepakete für WX zählen (Index)
Dim Wx_in As Byte
'Byte von RS232 übernehmen
Dim Wx_ok As Bit
'wx_framepaket komplett und neu =1
Dim Wx_tmp As Word
'Temporäre Wetter-Variable
Dim Tmp As Word
'Temporäre Word-Variable
Dim Text As String * 24
'Sammelvariable für LCD-Ausgabe
Dim Stmp As String * 3
'Temporäre String-Variable
On Urxc Onrxd
'wenn wx_frame an RS232 anliegen, gehe zu ONRXD
Enable Urxc
'Interupt Urxc aktiv
Enable Interrupts
'Interrupts global erlauben
Cursor Off
'Cursor aus
Cls
'Lösche LCD
Lcd "DG1XPZ-WX-Receiver V0.27"
'Ausgabe auf LCD
Wait 1
'warte 1 Sekunde
'----------------------
Do
'Beginn der Schleife(Hauptprogramm)
If Wx_ok = 1 Then
'wenn wx_framepaket komplett und neu
Disable Interrupts
'Interupts sperren
Call Addbyte(wx_frame(2) , Wx_frame(3))
'High-Byte und Low-Byte zusammenfügen
Locate 1 , 1
'LCD auf Beginn Zeile 1
If Wx_frame(1) <= 31 And Wx_count > 0 Then
'z.B. 28=AussensensorV1.2(Kanal 4)
Tmp = Wx_frame(1)
Text = "A"
'"A"=Aussensensor hinzufügen
Gosub Lcd_sensor_nr
'Sensornummer hinzufügen
Gosub Punkt
'Wert + Komma(Punkt) einfügen
Gosub Grad_c
'Maßeinheit hinzufügen
If Wx_frame(1) > 15 Then Text = Text + Str(wx_frame(4)) + "% "
'bei Sensor größer 15, Feuchte hinzufügen
Gosub Addspace
'abschließende Leerzeichen hinzufügen
Gosub Print2lcd
'auf LCD ausgeben
End If
If Wx_frame(1) >= 64 And Wx_frame(1) <= 79 Then
'z.B. 68=Innensensor(Kanal 4)
Tmp = Wx_frame(1) - 64
'Sensornummer berechnen
Text = "I"
'"I" = Innensensor hinzufügen
Gosub Lcd_sensor_nr
'Sensornummer hinzufügen
Gosub Punkt
'Wert + Komma(Punkt) einfügen
Gosub Grad_c
'Maßeinheit hinzufügen
Text = Text + Str(wx_frame(4)) + "% "
'Luftfeuchte hinzufügen
Call Addbyte(wx_frame(5) , Wx_frame(6))
'High-Byte und Low-Byte zusammenfügen
Gosub Lcd_tmp
'abs Luftdruck hinzufügen
Text = Text + "hPa"
'Maßeinheit hinzufügen
Gosub Addspace
'abschließende Leerzeichen hinzufügen
Gosub Print2lcd
'auf LCD ausgeben
End If
Locate 2 , 1
'LCD auf Beginn Zeile 2
If Wx_frame(1) >= 32 And Wx_frame(1) <= 47 Then
'Regensensoren
Tmp = Wx_frame(1) - 32
'Sensornummer berechnen
Text = "R"
'"R" = Regensensor hinzufügen
Gosub Lcd_sensor_nr
'Sensornummer hinzufügen
Wx_tmp = Wx_tmp * 4
'1 Impuls = 0.4L/qm
Gosub Punkt
'Wert + Komma(Punkt) einfügen
Text = Text + " L/qm(mm) "
'Maßeinheit hinzufügen
Gosub Addspace
'abschließende Leerzeichen hinzufügen
Gosub Print2lcd
'auf LCD ausgeben
End If
If Wx_frame(1) >= 48 And Wx_frame(1) <= 63 Then
'z.B. 60=Windsensor V1.2(Kanal 4)
Tmp = Wx_frame(1) - 48
'Sensornummer berechnen
Text = "W"
'"W" = Windsensor hinzufügen
Gosub Lcd_sensor_nr
'Sensornummer hinzufügen
Gosub Punkt
'Wert + Komma(Punkt) einfügen
Text = Text + "km/h "
'Maßeinheit hinzufügen
Call Addbyte(wx_frame(5) , Wx_frame(6))
'High-Byte und Low-Byte zusammenfügen
Gosub Lcd_tmp
'Windrichtung hinzufügen
Text = Text + Chr(223)
'Grad-Symbol hinzufügen
Gosub Addspace
'abschließende Leerzeichen hinzufügen
Gosub Print2lcd
'auf LCD ausgeben
End If
If Wx_frame(1) >= 88 And Wx_frame(1) <= 95 Then
'Helligkeitsensoren
Tmp = Wx_frame(1) - 88
'Sensornummer berechnen
Text = "H"
'"H" = Helligkeitsensor hinzufügen
Gosub Lcd_sensor_nr
'Sensornummer hinzufügen
Gosub Lcd_tmp
'Helligkeit hinzufügen
For I = 1 To Wx_frame(4)
'Helligkeits-Faktor hinzufügen
Text = Text + "0"
Next I
Text = Text + "Lx "
'Maßeinheit hinzufügen
Call Addbyte(wx_frame(5) , Wx_frame(6)) 'High-Byte und Low-Byte zusammenfügen
Tmp = Wx_tmp / 60
'Berechne Sonnen-Stunden (gesamt)
Text = Text + Str(tmp) + "h"
'Sonnenscheindauer in h hinzufügen
Tmp = Wx_tmp Mod 60
'Berechne Sonnen-Minuten (gesamt)
Text = Text + Str(tmp) + "m "
'Sonnenscheindauer in min hinzufügen
Gosub Addspace
'abschließende Leerzeichen hinzufügen
Gosub Print2lcd
'auf LCD ausgeben
End If
Enable Interrupts
'Interrupts erlauben
Wx_ok = 0
Wx_framepaket Ist Nicht Mehr Neu
End If
'Ende von IF wenn wx_framepaket komplett und neu war
Idle
'gehe in den Idle-Modus (aufwachen durch Urxc od. Interrupt)
Loop
'gehe zum Beginn der Schleife
'-------------------
Onrxd:
'Sprungziel für Interrupt Urxc
Disable Interrupts
'Interrupts sperren
Wx_in = Udr
'Wert aus UART-Puffer einlesen
If Wx_in = 2 Then Wx_count = 1 'wenn Startzeichen(Wert=2) dann Index auf 1 setzen
If Wx_in = 3 Then Wx_ok = 1 'wenn Endzeichen(Wert=3) dann wx_framepaket komplett und neu
If Wx_in > 3 Then
'wenn wx_frame dann
Wx_in = Wx_in - 128
'Bit 7 eleminieren (ist immer gesetzt)
Wx_frame(wx_count) = Wx_in
'Wert in Array ablegen
If Wx_count < 6 Then Incr Wx_count
'Index um 1 erhöhen
End If
Enable Interrupts
'Interrupts erlauben
Return
'Zurück
'-------------------
Addspace:
'Sprungziel um Text mit Leerzeichen aufzufüllen
If Len(text) < 24 Then
'ist Text kürzer als 24 Zeichen
Tmp = 24 - Len(text)
'Berechne Anzahl Leerzeichen
Text = Text + Space(tmp) 'Anzahl Leerzeichen hinzufügen
End If
Return
'Zurück
'-------------------
Print2lcd:
'Sprungziel um Text auf LCD auszugeben
Lcd Text
'Text auf LCD ausgeben
Return
'Zurück
'-------------------
Lcd_sensor_nr:
'Sprungziel um Sensornummer 2-stellig aufzuarbeiten
Stmp = Str(tmp)
'in String umwandeln
Stmp = Format(stmp , "00")'2-stellig mit führender 0
Text = Text + Stmp + ":"
'Sensornummer zu Text hinzufügen
Return
'Zurück
'-------------------
Lcd_tmp:
'Sprungziel um Wert in String zu wandeln
Text = Text + Str(wx_tmp) 'füge Wert zu Text hinzu
Return
'Zurück
'-------------------
Grad_c:
'Sprungziel um Gradsymbol zu Text hinzuzufügen
Text = Text + Chr(223) + "C " 'Maßeinheit
hinzufügen
Return
'Zurück
'-------------------
Punkt:
'Sprungziel um Punkt und Minus in den Wert einzuarbeiten
If Wx_tmp >= 16085 Then 'wenn Temperatur negativ
(bis -29.9 Grad C)
Wx_tmp = 16384-Wx_tmp 'Wert abziehen
Text = Text + "-"
'Minus hinzufügen
End If
Tmp = Wx_tmp / 10
'Vorkommastelle abtrennen
Text = Text + Str(tmp) + "." 'Vorkommastelle + Punkt hinzufügen
Tmp = Wx_tmp Mod 10
'Nachkommastelle abtrennen
Text = Text + Str(tmp)
'Nachkommastelle hinzufügen
Return
'Zurück
'-------------------
Sub Addbyte(a As Byte , B As Byte) 'Sub-Routine um High-Byte und Low-Byte zusammenzufügen
Wx_tmp = A
'High-Byte übernehmen
Shift Wx_tmp , Left , 7
'um 7 Bit nach links schieben
Wx_tmp = Wx_tmp + B
'Low-Byte hinzufügen
End Sub
'Ende Sub-Routine
'-------------------
End
'Programm-Ende |
|