Forum: Mikrocontroller und Digitale Elektronik Nebelkammer Steuerung Menü+Zeitmanagement


von Johan L. (rattenterminator)


Lesenswert?

Guten Abend,
Ich habe für mein Jugend Forscht Projekt eine Steuerung entwickelt und 
gebaut. Sie besteht aus 3 Tastern(Hoch, Runter, Enter) mit denen man 
durch ein Menü sich bewegt und dort Soll Werte verändern kann. Die solle 
Werte werden mit den zugehörigen Sensorwerten verglichen und je nachdem 
ob der Wert über bzw. unterschritten wurde, werden Relais geschaltet. 
Zusätzlich wird über einen Timer eine Pumpe geregelt, über einen Counter 
eine Ausleseelektronik erfasst, und eine Spule geschaltet.
Nun zu meinem Problem. Wenn ich das Display nicht vor jedem neuen 
beschreibung neu initalisieren würde, würden irgendwelche Asiatische 
Zeichen auf Display erscheinen(vlt. weil es aus China kommt, ka;-)). Wie 
kann es dazu kommen? Zuerst tippte ich auf einen Interrupt, der die 
Datenübertragung unterbricht. Interrupt disable und enable vorher und 
nach dem beschreiben brachte aber keine Besserung. Unten findet ihr 
meinen Quellcode, ich weiß er ist 360 Zeilen lang, aber ich hoffe dass 
er ganz gut kommentiert ist. Ich bin offen für jede Kritik, was Struktur 
und Time Management angeht, sowie die Art und Weise, wie das Menü 
realisiert wurde.Gebt einfach euren Senf dazu ab.
Auf Wunsch kann ich auch noch den Schaltplan hochladen.

$regfile = "m32def.dat"
$crystal = 8000000
$baud = 19200

'IO Konfiguration
Ddrd.4 = 1
Ddrd.5 = 1
Ddrd.6 = 1
Ddrd.7 = 1                                                  'Pwm
Ddrb.1 = 1
Ddrb.3 = 1

'Alias
Relaisalkoholpumpe Alias Portd.4
Relaiskuehlung Alias Portd.5
Relaisalkoholheizung Alias Portd.6
Relaiskammerheizung Alias Portb.3
Relaishelmholtz Alias Portb.1

'Pullups für die Eingänge
Portd.2 = 1
Portd.3 = 1
Portb.2 = 1

'Taster
Config Int0 = Falling
Config Int1 = Falling
Config Int2 = Falling
'Sprünge für Interrupts
On Int0 Taster_enter
On Int1 Taster_hoch
On Int2 Taster_runter
Enable Int0 
'Tasterinterrupts aktivieren
Enable Int1
Enable Int2

'Variablen
'Menü
Dim Menue As Byte , Change As Bit
'Temperatursollwerte
Dim Sollkuehlung As Integer , Sollalkohol As Integer , Sollkammer As 
Integer , Adcwert As Word
Dim Localtemp As Integer
'Momentanen Temperaturwerte
Dim Tempkuehlung As Integer , Tempalkohol As Integer , Tempkammer As 
Integer , I As Byte
'Helmholtzspule
Dim Helmholtzschalter As Bit
'Pumpe Alkohol
Dim Pumpentimer As Byte , Alkoholanzeit As Byte , Alkoholhelp As Byte , 
Uhrhelp As Byte
'Szintillationszähler
Dim Szintischalter As Bit , Uhr As Word

'Programmdefinitionen
'LC-Display
Config Lcdpin = Pin , Db4 = Portc.2 , Db5 = Portc.3 , Db6 = Portc.4 , 
Db7 = Portc.5 , E = Portc.6 , Rs = Portc.7
Config Lcd = 16 * 2

'Temperatursensor
Config Adc = Single , Prescaler = Auto , Reference = Avcc
Start Adc

'Menü+Uhr+Pumpe
Config Timer1 = Timer , Prescale = 256
Enable Timer1
On Timer1 Uhr
Start Timer1

'Szint. Detektor
Config Timer0 = Counter , Edge = Rising
Enable Timer0
On Timer0 Szintillationscounter
Start Timer0

'Prozeduren und Funktionen
Declare Sub Init
Declare Sub Menue_show
Declare Function Check(byval Channel As Byte) As Byte
Declare Sub Steuerung_kuehlung
Declare Sub Steuerung_alkohol
Declare Sub Steuerung_kammer
Declare Sub Runter
Declare Sub Hoch
Declare Sub Enter
Declare Sub Serial0charmatch
Declare Sub Serial0_logger
Declare Sub Steuerung_pumpe

'#########################Hauptschleife################################# 
#############'
Main:
Call Init 
'Initalisierung aufrufen
Enable Interrupts
'''''''''''''''''''''''Auslesen des Temperatursensors und umrechnen in 
Celsius in einer Endlos Schleife'''''''''
Do
   Adcwert = Getadc(i)                                      'ADC Wert 
besorgen
   Localtemp = Adcwert - 460                                ' 460 = 
Analogwert bei 0 Grad und 1 kOhm Vorwiderst
   Localtemp = Localtemp / 2                                ' pro Grad 2 
AD-Schritte
   Select Case I
   Case 0 : Tempkuehlung = Localtemp
   Case 1 : Tempalkohol = Localtemp
   Case 2 : Tempkammer = Localtemp
   End Select
   Incr I
   If I = 2 Then I = 0
Loop
End

'''''''''''''''''''''''''''''''''''''''''''''Timer'''''''''''''''''''''' 
'''''''''''''''
Szintillationscounter:
   Timer0 = 0
Return

'dies ist die Hauptsteuerung
Uhr:
   Timer1 = 49910
   Incr Uhrhelp
  If Uhrhelp = 2 Then
   Incr Pumpentimer
   Uhrhelp = 0
  End If
   Call Steuerung_kuehlung 
'Steueraufgaben
   Call Steuerung_alkohol
   Call Steuerung_kammer
   Call Steuerung_pumpe
   Initlcd
   Cursor Off Noblink
   Call Menue_show

Return

Sub Steuerung_pumpe
   Alkoholhelp = Alkoholanzeit + 10
  If Pumpentimer = Alkoholanzeit Then                       'An-Periode 
erreicht, Pumpe aus
      Relaisalkoholpumpe = 0
   End If
   If Pumpentimer = Alkoholhelp Then 
'Wartezeit(10 sec) vorbei, Pumpe an
      Relaisalkoholpumpe = 1
      Pumpentimer = 0
   End If
End Sub

'''''''''''''''''''''''''''''''''''''''''Initalisierung''''''''''''''''' 
''''''''''''''''''''''''
Sub Init                                                    'hier werden 
die Startwerte geladen
Local Test As Byte
  Timer1 = 49910                                            'Timer1 
startet mit 49910(Halbe Sekunde)62410, damit im 100stel Sekundentakt 
gezählt wird
  Timer0 = 0 
'Szintillationscounter zählt von 0
  Pumpentimer = 0                                           'Pumpe zählt 
von 0
  Uhrhelp = 0
  Szintischalter = 1 
'Szintillationscounter ist an
  Helmholtzschalter = 0
  Menue = 1                                                 'der erste 
Reiter des Menüs ist ausgewählt
  Change = 0                                                'das 
Anzeigemenü wird dargestellt
  I = 0                                                     'die For 
Variable für Main
  Readeeprom Sollkuehlung , 0                               'die 
Einstellungen werden aus dem Internen EEprom geladen
  Readeeprom Sollalkohol , 2
  Readeeprom Sollkammer , 4
  Readeeprom Alkoholanzeit , 6

  Cls
  Cursor Off Noblink
  Locate 1 , 1
  'check ob die Temperatur im grünen Bereich oder ob ein Fehler vorliegt
   For I = 0 To 2
   Adcwert = Getadc(i)                                      'ADC Wert 
besorgen
   Localtemp = Adcwert - 460                                ' 460 = 
Analogwert bei 0 Grad und 1 kOhm Vorwiderst
   Localtemp = Localtemp / 2                                ' pro Grad 2 
AD-Schritte
   Select Case I
   Case 0 : Tempkuehlung = Localtemp
   Case 1 : Tempalkohol = Localtemp
   Case 2 : Tempkammer = Localtemp
   End Select
   Next
   I = 0
If Check(0) = 1 Then                                        'bloß ein 
kleiner Test, ob die Temperaturwerte im Rahmen liegen
   If Check(1) = 1 Then
      If Check(2) = 1 Then
         Lcd "Check OK"
         Test = 1
      Else
         Test = 0
      End If
   Else
      Test = 0
   End If
Else
Test = 0
End If
If Test = 0 Then Lcd "Check failed"
Wait 1
End Sub


Function Check(byval Channel As Byte) As Byte               'wird bloß 
beim Start aufgerufen
Select Case Channel
   Case 0 : Localtemp = Tempkuehlung
   Case 1 : Localtemp = Tempalkohol
   Case 2 : Localtemp = Tempkammer
End Select
If Tempkuehlung > -80 Then
   If Tempkuehlung < 80 Then
      Check = 1
   Else
      Check = 0
   End If
Else
   Check = 0
End If

End Function


''''''''''''''''''''''''''''Hier wird das Menü verwaltet und 
dargestellt'''''''''''''''
Sub Menue_show
 Locate 1 , 1
 If Change = 0 Then                                         'das 
Anzeigemenü wird dargestellt
  Select Case Menue
   Case 1 : Lcd "1:Temp Kuehlung:"
            Locate 2 , 1
            Lcd Str(tempkuehlung) ; " C(" ; Str(sollkuehlung) ; " C)  "
   Case 2 : Lcd "2:Temp Alkohol: "
            Locate 2 , 1
            Lcd Str(tempalkohol) + " C(" + Str(sollalkohol) + " C)    "
   Case 3 : Lcd "3:Temp Kammer:  "
            Locate 2 , 1
            Lcd Str(tempkammer) + " C(" + Str(sollkammer) + " C)  "
   Case 4 : Lcd "4:Szint. Zaehler"
            Locate 2 , 1
            Lcd Str(timer0) ; "           "
   Case 5 : Lcd "5:Alkoh. Zeit an"
            Locate 2 , 1
            Lcd Str(alkoholanzeit) ; "          "
   Case 6 : Lcd "6:Helmholtz:    "
            Locate 2 , 1
            If Helmholtzschalter = 0 Then Lcd "aus             " Else 
Lcd "an              "
   Case Else : Menue = 1                                    'wieder 
zurück zu Reiter 1
  End Select
 Else
  Select Case Menue
   Case 1 : Lcd "Soll Kuehlung:  "
            Locate 2 , 1
            Lcd "(" + Str(sollkuehlung) ; " C)      "
   Case 2 : Lcd "Soll Alkohol:   "
            Locate 2 , 1
            Lcd "(" + Str(sollalkohol) ; " C)      "
   Case 3 : Lcd "Soll Kammer:    "
            Locate 2 , 1
            Lcd "(" + Str(sollkammer) ; " C)       "
   Case 4 : Lcd "Szinti an?      "
            Locate 2 , 1
            If Szintischalter = 0 Then Lcd "aus             " Else Lcd 
"an              "
   Case 5 : Lcd "Soll Pumpe      "
            Locate 2 , 1
            Lcd Str(alkoholanzeit) ; "          "
   Case 6 : Lcd "Helmholtz an?   "
            Locate 2 , 1
            If Helmholtzschalter = 0 Then Lcd "aus             " Else 
Lcd "an              "
  End Select
 End If
End Sub

''''''''''''''''''''''''''Steuerungen der Heizungen bzw. 
Kühlungen'''''''''''''''''''''
Sub Steuerung_kuehlung
If Tempkuehlung > Sollkuehlung Then                         'wenn wärmer 
als Sollwert
   Relaiskuehlung = 1                                       'dann die 
Kühlung einschalten
Else
   Relaiskuehlung = 0                                       'wenn 
wärmer, dann einschalten
End If
End Sub

Sub Steuerung_alkohol
If Tempalkohol < Sollalkohol Then                           's.u.
   Relaisalkoholheizung = 1
Else
   Relaisalkoholheizung = 0
End If
End Sub

Sub Steuerung_kammer                                        'wenn kälter 
als Sollwert,
If Tempkammer < Sollkammer Then
   Relaiskammerheizung = 1                                  'dann die 
Heizung der Kammer anschalten
Else
   Relaiskammerheizung = 0                                  'wenn 
wärmer,dann ausschalten
End If
End Sub

''''''''''''''''''''''''''''''''''''''''''TASTER'''''''''''''''''''''''' 
'''''''''''''''
'Taster Enter + Entprellen
Taster_enter:
   Debounce Pind.2 , 0 , Enter , Sub
Return

Sub Enter
   Change = Not Change
End Sub

'Taster Hoch + Entprellen
Taster_hoch:
Debounce Pind.3 , 0 , Hoch , Sub
Return

Sub Hoch
If Change = 1 Then
   Select Case Menue
      Case 1 : Incr Sollkuehlung
        Writeeeprom Sollkuehlung , 0
      Case 2 : Incr Sollalkohol
        Writeeeprom Sollalkohol , 2
      Case 3 : Incr Sollkammer
        Writeeeprom Sollkammer , 4
      Case 4 : If Szintischalter = 0 Then
            Szintischalter = 1
            Start Timer0
            Else
            Szintischalter = 0
             Stop Timer0
        End If
      Case 5 : Incr Alkoholanzeit
         Writeeeprom Alkoholanzeit , 6
      Case 6 : If Helmholtzschalter = 0 Then
                  Helmholtzschalter = 1
                Else
                  Helmholtzschalter = 0
                End If
                Toggle Relaishelmholtz
   End Select
Else
      Incr Menue
End If
End Sub

'Taster Runter + Entprellen
Taster_runter:
   Debounce Pinb.2 , 0 , Runter , Sub
Return

Sub Runter
If Change = 1 Then
     Select Case Menue
        Case 1 : Decr Sollkuehlung
          Writeeeprom Sollkuehlung , 0
        Case 2 : Decr Sollalkohol
          Writeeeprom Sollalkohol , 2
        Case 3 : Decr Sollkammer
          Writeeeprom Sollkammer , 4
          Case 4 : If Szintischalter = 0 Then
            Szintischalter = 1
            Start Timer0
            Else
            Szintischalter = 0
             Stop Timer0
        End If
      Case 5 : Decr Alkoholanzeit
         Writeeeprom Alkoholanzeit , 6
      Case 6 : If Helmholtzschalter = 0 Then
                  Helmholtzschalter = 1
                Else
                  Helmholtzschalter = 0
                End If
                Toggle Relaishelmholtz
      End Select
Else
     Decr Menue
End If
End Sub

von MaWin (Gast)


Lesenswert?

Irgendwie fehlt ein Config Lcdbus = 4,
aber dann käme nix raus :-)

Der Rest sieht richtig aus, CLS ist dabei
ich würde aber immer 32 Zeichen pro LCD-Aufruf ausgeben,
um den Rest dahinter gerantiert zu überschreiben.

von Johan L. (rattenterminator)


Lesenswert?

Bascom ist Standardmäßig auf LCDBus=4 eingestellt... zur Sicherheit 
machs ich trotzdem rein. Das mit den 32 Zeichen meinst du dass jetzt für 
jede Reihe, also insgesammt 64, oder eher das ich die ganzen Leerstellen 
auch mit übertrage(das tue ich schon)

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
Noch kein Account? Hier anmelden.