-         

Ergebnis 1 bis 6 von 6

Thema: Programm hängt sich auf

  1. #1
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    22.12.2006
    Beiträge
    109

    Programm hängt sich auf

    Anzeige

    Einen schönen gten Tag!

    Seit einiger Zeit bin ich dabei eine Heizungssteuerung zu Programmieren. Das Programm das ich erstellt habe funktioniert soweit schon aber eigentlich wiederum nicht. Jeden Tag, so wie es aussiet hängt der Code sich auf und ich muss den Stecker ziehen. Wenn ich den Stecker dann wieder einstecke läuft alles wieder bestens. Kann mir jemand helfen woran das hängt! Hier der gesmte Code:

    Schonmal danke für die Hilfe

    Code:
    $regfile = "m8def.dat"
    $crystal = 3686400
    $hwstack = 46
    $swstack = 40
    $framesize = 40
    '***************************Config Schaltausgänge*******************************
    Config Portb = Output
      Brenner Alias Portb.3
      Pumpefb Alias Portb.4
      Pumpehk Alias Portb.5
    '**************************Def. allgemeiner Variabeln***************************
    Dim Tagnacht As Bit
    Dim Nachtbetrieb As Byte
    Dim Tagbetrieb As Byte
    Dim Tempmessstelle(8) As Single
    Dim Brennerstarts As Integer
    Dim Interrupt_brenner As Bit
    Dim Zeit_in_min As Integer
    Dim Kessel_max As Single
    Dim Kessel_min As Single
    Dim Kessel_grenz_max As Single
    Dim Kessel_grenz_min As Single
    Dim Delta_vl_rl_fb As Single
    Dim Wassertemp As Bit
    
    Kessel_max = 58.0
    Kessel_min = 38.0
    Kessel_grenz_max = Kessel_max
    Kessel_grenz_min = Kessel_min
    Delta_vl_rl_fb = 5.0
    Wassertemp = 1
    
    Brennerstarts = 0
    Interrupt_brenner = 0
    
    Nachtbetrieb = 22
    Tagbetrieb = 4
    
    Const Tagtemp_og = 21.8
    Const Tagtemp_ug = 21.6
    Const Nachttemp_og = 21.5
    Const Nachttemp_ug = 21.3
    
    '**************************Funktionen LCD-Display*******************************
    
    Config Lcd = 40 * 4
    Config Lcdpin = Pin , Rs = Portb.0 , Db4 = Portd.5 , Db5 = Portd.4 , Db6 = Portd.3 , Db7 = Portd.2 , E = Portd.6 , E2 = Portd.7
    Config Lcdbus = 4
    Config Lcdmode = Port
    
    Dim ___lcdno As Byte
    
    ___lcdno = 0
     Initlcd
     Cursor Off
     Cls
    ___lcdno = 1
    Initlcd
    Cursor Off
    Cls
    '*******************************************************************************
    
    Config 1wire = Portc.1                                      'DS1820
    
    Match_rom Alias &H55
    Read_scratchpad Alias &HBE
    Start_conversion Alias &H44
    
    Innen Alias 0
    Vorlauf_fb Alias 1
    Rücklauf_fb Alias 2
    Vorlauf_hk Alias 3
    Kessel Alias 4
    
    Dim Read_temp As Integer
    Dim Sensor_ids(48) As Byte
    Dim Id As Byte
    Dim Offset As Byte
    Dim Ds_array(7) As Byte
    Dim Bruchteil As Single
    Dim Temperatur As Single
    Dim I As Integer
    
    '*************************Config Timer1*****************************************
    Config Timer1 = Timer , Prescale = 256                      '256                      '64       '256       'Konfiguriere Timer1
    Enable Timer1                                               'schalte den Timer1 ein
    On Timer1 Isr_von_timer1                                    'verzweige bei Timer1 überlauf zu   Isr_von_Timer1
    Enable Interrupts
    Timer1 = 51135                                              'Timer1 soll schon von 34285 wegzählen
    '***************************Config RTC******************************************
    Config Sda = Portc.4
    Config Scl = Portc.5
    
    Const Ds1307w = &HD0                                        ' Addresses of Ds1307 clock
    Const Ds1307r = &HD1
    
    Config Clock = User                                         ' this will dim the bytes automatic
    Dim Weekday As Byte
    
    'Time$ = "20:26:00"                                          ' to watch the day changing value
    'Date$ = "02.27.07"                 ' erstmaliges stellen der Uhr
    '***************************AD-Config*******************************************
    Config Adc = Single , Prescaler = Auto
    Dim Faktor As Single
    Dim Sp As Integer
    Faktor = 5.28 / 1023
    
    '***************************ID 1Wire configurieren******************************
    For Id = 1 To 40                                            'Einlesen der 5 Sensoren IDs (5*8 Byte)
       I = Id - 1
       Readeeprom Sensor_ids(id) , I
    Next Id
    '**************************Initialisierung**************************************
    
       Brenner = 0
       Pumpefb = 1
       Pumpehk = 1
    
    '**************************Hauptrogramm*****************************************
    Do
       Gosub Ad_wandler
       Waitms 700
       For Id = Innen To Kessel                                 'Kessel
          Offset = Id * 8
          Offset = Offset + 1                                   'Offset geht auf 1, 9, 17, 25 und 33
          1wreset                                               'hier wird der Temperaturwert eingelesen
          1wwrite Match_rom
          1wwrite Sensor_ids(offset) , 8                        '8 Byte ID wird übertragen
          1wwrite Read_scratchpad
          For I = 1 To 7                                        'nur bis 7, weil 8 und 9 uninteressant
             Ds_array(i) = 1wread()
          Next I
          Read_temp = Makeint(ds_array(1) , Ds_array(2))
          1wreset                                               'jetzt wird wieder die Konvertierung gestartet
          1wwrite Match_rom
          1wwrite Sensor_ids(offset) , 8
          1wwrite Start_conversion
          Shift Read_temp , Right
          If 127 < Read_temp Then Read_temp = Read_temp - 32768
          Bruchteil = 16 - Ds_array(7)
          Bruchteil = Bruchteil / 16
          Bruchteil = Bruchteil - 0.25
          Temperatur = Read_temp + Bruchteil
    
          If Temperatur >= -16.0 Then
            Tempmessstelle(id + 1) = Read_temp + Bruchteil      'Temperatur
          End If
           ___lcdno = 0
                                                  '1
          Locate 1 , 2 : Lcd "BO-U RA-T KE-T VLB-T RLB-T"
          Select Case Id
          Case Innen:                                           '1
               Locate 2 , 7 : Lcd Fusing(tempmessstelle(1) , "#.#")
               Locate 2 , 11 : Lcd " "
          Case Kessel:                                          '2
              Locate 2 , 12 : Lcd Fusing(tempmessstelle(2) , "#.#")
              Locate 2 , 16 : Lcd " "
          Case Vorlauf_fb:                                      '3
              Locate 2 , 17 : Lcd Fusing(tempmessstelle(3) , "#.#")
              Locate 2 , 21 : Lcd "  "
          Case Rücklauf_fb:                                     '4
              Locate 2 , 23 : Lcd Fusing(tempmessstelle(4) , "#.#")
              Locate 2 , 27 : Lcd " "
          End Select
            Locate 2 , 6 : Lcd " "
          If Tempmessstelle(8) >= 0 Then
            Locate 2 , 2 : Lcd Fusing(tempmessstelle(8) , "#.##")
          Else
            Locate 2 , 1 : Lcd Fusing(tempmessstelle(8) , "#.#")
          End If
    
            ___lcdno = 1
          Locate 2 , 20
          Lcd Time$
          Locate 2 , 15 : Lcd "     "
          Select Case Id
          Case Vorlauf_hk:                                      '5
             Locate 1 , 1 : Lcd "Vl-hk" : Lcd Fusing(tempmessstelle(5) , "#.#")
             Locate 1 , 9 : Lcd "   "
          End Select
          Locate 1 , 12 : Lcd "AU-T " : Lcd Fusing(tempmessstelle(7) , "#.##")
          Locate 2 , 1 : Lcd "B-Start:     "
          Locate 2 , 10 : Lcd Brennerstarts
         Cursor Off
       Next Id
      Loop
    End
    '*******************************Überwachung Brauchwassertemp********************
    Überwachung_brauchwassertemp:
       If Tempmessstelle(4) <= 42.0 Then
         Wassertemp = 0
         If Tempmessstelle(2) < 48.0 Then
           Brenner = 1
         End If
         If Tempmessstelle(2) > 58.0 Then
           Brenner = 0
         End If
         Pumpehk = 1
         Pumpefb = 0
       End If
       If Tempmessstelle(2) >= 50 Then
          Wassertemp = 1
       End If
    Return
    '*******************************Überwachung Pumpen******************************
    Überwachung_pumpen:
       If Tempmessstelle(2) < 30.0 Then
         Pumpefb = 0
       End If
       If Tempmessstelle(2) >= 32.0 Then
         Pumpefb = 1
       End If
       If Tempmessstelle(2) < 38.0 Then
         Pumpehk = 0
       End If
       If Tempmessstelle(2) >= 36.0 Then
         Pumpehk = 1
       End If
    Return
    '*******************************AD-Wandler**************************************
     Ad_wandler:
        Start Adc
        Sp = Getadc(0)
        Tempmessstelle(8) = Sp * Faktor
        'Tempmessstelle(8) = Tempmessstelle(8) - 0.35
        'Tempmessstelle(8) = 132.14 * Tempmessstelle(8)
        'Tempmessstelle(8) = Tempmessstelle(8) - 153.93          ' Boiler_temp unten
        Sp = Getadc(2)
        Tempmessstelle(7) = Sp * Faktor                         ' Außentemp
        'Sp = Getadc(2)
        'Tempmessstelle(6) = Sp * Faktor
     Return
                                                          '
    '**************************Überwachung Kesseltemp*******************************
    Überwachung_kesseltemp:
     If Tempmessstelle(2) >= Kessel_max Or Tempmessstelle(8) >= 1.52 Then
       Brenner = 0
       If Interrupt_brenner = 0 Then
         Brennerstarts = Brennerstarts + 1
         Interrupt_brenner = 1
       End If
     End If
    
     If Tempmessstelle(2) < Kessel_min And Tempmessstelle(8) <= 1.46 Then
       Brenner = 1
       Interrupt_brenner = 0
     End If
    Return
    
    '*************************Sub Relais schalten***********************************
    Schalterelais:
    Select Case Tagnacht
      Case 0
        Gosub Nachtbetrieb
      Case 1
        Gosub Tagbetrieb
    End Select
    Return
     '**************************Sub für Tagbetrieb**********************************
    Tagbetrieb:
      Kessel_min = 38.0
      Gosub Überwachung_kesseltemp
      If Tempmessstelle(1) <= Tagtemp_ug Then
        Pumpefb = 1
      End If
      If Tempmessstelle(1) >= Tagtemp_og Then
        Brenner = 0
        Pumpefb = 0
      End If
      If _hour = 21 Then
       Kessel_min = Kessel_grenz_min - 2
       Kessel_max = Kessel_grenz_max - 2
      Else
        Kessel_min = Kessel_grenz_min
        Kessel_max = Kessel_grenz_max
      End If
    Return
    '**************************Sub für Nachtbetrieb*********************************
    Nachtbetrieb:
      Kessel_min = 31.0
      If Tempmessstelle(2) >= Kessel_min Then
        Brenner = 0
        Pumpefb = 1
      Else
        Brenner = 0
        Pumpefb = 0
      End If
    Return                                                      '
     '**************************Subroutine für Timer1*******************************
    Isr_von_timer1:                                             'ISR von Timer1
      Timer1 = 51135
        If _hour >= Nachtbetrieb Or _hour < Tagbetrieb Then     'Or _hour = 7 Or _hour = 8 Then
          Tagnacht = 0                                          'Nachteinstellung
        Else
          Tagnacht = 1                                          'Tageinstellung
        End If
    
        Gosub Schalterelais
        Gosub Überwachung_pumpen
        If Wassertemp = 0 Then
          Gosub Überwachung_brauchwassertemp
        End If
    
        Delta_vl_rl_fb = Tempmessstelle(3) - Tempmessstelle(2)
        Zeit_in_min = _hour * 60
        Zeit_in_min = Zeit_in_min + _min
    Return
    '***************************Subs für RTC****************************************
    Getdatetime:
      I2cstart                                                  ' Generate start code
      I2cwbyte Ds1307w                                          ' send address
      I2cwbyte 0                                                ' start address in 1307
    
      I2cstart                                                  ' Generate start code
      I2cwbyte Ds1307r                                          ' send address
      I2crbyte _sec , Ack
      I2crbyte _min , Ack                                       ' MINUTES
      I2crbyte _hour , Ack                                      ' Hours
      I2crbyte Weekday , Ack                                    ' Day of Week
      I2crbyte _day , Ack                                       ' Day of Month
      I2crbyte _month , Ack                                     ' Month of Year
      I2crbyte _year , Nack                                     ' Year
      I2cstop
      _sec = Makedec(_sec) : _min = Makedec(_min) : _hour = Makedec(_hour)
      _day = Makedec(_day) : _month = Makedec(_month) : _year = Makedec(_year)
    Return
    
    Setdate:
      _day = Makebcd(_day) : _month = Makebcd(_month) : _year = Makebcd(_year)
      I2cstart                                                  ' Generate start code
      I2cwbyte Ds1307w                                          ' send address
      I2cwbyte 4                                                ' starting address in 1307
      I2cwbyte _day                                             ' Send Data to SECONDS
      I2cwbyte _month                                           ' MINUTES
      I2cwbyte _year                                            ' Hours
      I2cstop
    Return
    
    Settime:
      _sec = Makebcd(_sec) : _min = Makebcd(_min) : _hour = Makebcd(_hour)
      I2cstart                                                  ' Generate start code
      I2cwbyte Ds1307w                                          ' send address
      I2cwbyte 0                                                ' starting address in 1307
      I2cwbyte _sec                                             ' Send Data to SECONDS
      I2cwbyte _min                                             ' MINUTES
      I2cwbyte _hour                                            ' Hours
      I2cstop
    Return
    
    '*******************************************************************************
    $eeprom
    
    Data &H10 , &HE8 , &HF4 , &H23 , &H01 , &H08 , &H00 , &HEF  '     0
    Data &H10 , &H1B , &HD0 , &H23 , &H01 , &H08 , &H00 , &H23  '     1
    Data &H10 , &H78 , &H37 , &H39 , &H01 , &H08 , &H00 , &H11  '     2
    Data &H10 , &HC0 , &H46 , &H19 , &H01 , &H08 , &H00 , &H67  '     3
    'Data &H10 , &HBD , &HB6 , &H23 , &H01 , &H08 , &H00 , &H40  '     4
    Data &H10 , &H56 , &HA3 , &H23 , &H01 , &H08 , &H00 , &H3F  '     5

  2. #2
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    29.01.2005
    Alter
    45
    Beiträge
    294
    Hallo,

    den ganzen Code durchzuackern hat bestimmt niemand Lust.

    Deshalb ein paar Tipps zum Eingrenzen des Problems, dann macht eine Suche auch Sinn.

    Falls Du mit einem Simulator nichts herausbekommst, würde ich in den Routinen irgendeine Ausgabe auf´s LCD mitlaufen lassen. Damit weist Du nach einem Absturz wenigstens mal groß eine Richtung in der es zu Suchen gilt.

    Oder den Watchdog einschalten. Vielleicht ist ja gar nicht das Programm das Problem, sondern irgendwelche äußeren Einflüße. Da hilft Dir auch das "Debuggen" mit den LCD-Ausgaben nichts.

    Gruß Dnerb
    Das Gegenteil von "gut" ist "gut gemeint"!

  3. #3
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    22.12.2006
    Beiträge
    109
    Gute Idee! Ich werde jeder Sub und dem Hauptprogramm ein Ziffer zuordner, die ich dann auf dem LCD anzeige. Mal schauen wo das Programm stoppt.

    Martin

  4. #4
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    29.01.2005
    Alter
    45
    Beiträge
    294
    Jo, melde Dich hier wenn Du nicht weiterkommst. Der Winter kommt bald...
    Das Gegenteil von "gut" ist "gut gemeint"!

  5. #5
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    16.02.2006
    Beiträge
    1.112
    Hallo Martin,
    wenn du wirklich den Eindruck hast, dass der µC steht, würde ich dir auch empfehlen, auf dem LCD eine Ausgabe zu machen.
    Ich habe mir auch mal deine Routinen angeschaut.
    Zuerst ist mir aufgefallen, dass du praktisch alle Subs in der Timer ISR aufrufst. Auch wenn du dies nicht direkt machst, so laufen auch die in den Subs aufgerufenen Subs immer noch in der Interrupt Umgebung. Das kann teilweise sehr lange dauern.
    Kannst du nicht einfach ein Flag setzen und dies dann in der MainLoop abfragen, also etwa so:

    Do
    if Timer_flag = 1 then
    Timer_flag=0
    If _hour >= Nachtbetrieb Or _hour < Tagbetrieb Then
    Tagnacht = 0 'Nachteinstellung
    Else
    Tagnacht = 1 'Tageinstellung
    End If
    Gosub Schalterelais
    .... alle Befehle
    endif
    .....
    Loop

    Isr_von_timer1:
    Timer1 = 51135
    Timer_flag=1
    Return

    Und nach Möglichkeit die 700ms Wait verhindern. Lass das lieber auch von der Timer ISR anstoßen. Wenn dein Programm größer wird, dann können andere Sachen in der Wartezeit gemacht werden.

    Dies hier scheint mir falsch zu sein:
    If Tempmessstelle(2) < 38.0 Then
    Pumpehk = 0
    End If
    If Tempmessstelle(2) >= 36.0 Then
    Pumpehk = 1
    End If
    Wenn Tempmessstelle(2) z.B. 37.0 ist, dann wird Pumpehk immer hin und her geschaltet.

    Gruß

    Rolf

  6. #6
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    22.12.2006
    Beiträge
    109
    Hallo "for_ro",

    das was du schreibst ist wohl richtig. Ich werde das mal umsetzten und schauen was passiert. Kann jetzt einige Tage nichts tun an meinem Programm, da ich tabezieren muss. Werde mich aber melden was rauskommt nach der änderung.

    VIELEN Dank für Zeit die du und auch alle anderen für micht investiert haben.

    Martin

Berechtigungen

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