PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Programm hängt sich auf



martin66119
07.10.2007, 15:07
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



$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

Dnerb
07.10.2007, 15:22
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

martin66119
07.10.2007, 15:32
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

Dnerb
07.10.2007, 15:43
Jo, melde Dich hier wenn Du nicht weiterkommst. Der Winter kommt bald... ;-)

for_ro
07.10.2007, 17:27
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

martin66119
07.10.2007, 22:06
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