- 3D-Druck Einstieg und Tipps         
Ergebnis 1 bis 4 von 4

Thema: Programm läuft, aber....

  1. #1
    Benutzer Stammmitglied
    Registriert seit
    19.02.2010
    Beiträge
    67

    Programm läuft, aber....

    Anzeige

    Powerstation Test
    Hallo Forum,

    Ich benutze einen ATMega 8 um das Ausgangssignal eines UTI von der Firma Smartec auszuwerten, um damit die Widerstände von PT100-Sensoren zu messen und die Temperatur zu gewinnen.

    Diese wird dann im ATMega gemittel, sowie der Anstieg berechnet.

    Das alles haut wunderbar hin.

    ABER:

    Ich habe durch Optimierungen, Vereinfachungen und Verbesserungen alte ungenutzte Fragmente im Code, sowie Variablen im Speicher, die einfach überflüssig sind und Speicherplatz belegen, den ich für weitere Mittelwertbildungen gut gebrauchen könnte.

    Wenn ich diese nun aber rauslösche oder auskommentiere startet mein ATMega ständig neu, schafft ab und an mal eine Temperaturmessung /-berechnung um dann wieder neu zu starten.


    es geht hauptsächlich um die Long-Variable Capture auf &H150
    sowie um das Array UTI(..) welches ich letztlich nur noch bis uti(10) benötigen würde.





    Nachfolgend mein Quellcode


    $regfile = "m8def.dat"
    $crystal = 8000000
    $baud = 57600
    $framesize = 100
    $swstack = 100
    $hwstack = 100
    '$sim



    Icp1 Alias Pinb.0 : Config Icp1 = Input : Portb.0 = 1


    '################# UTI ################################################## ##
    On Capture1 Oncapture 'Pd4
    On Ovf1 Onoverflow

    Tccr1a = 0 'Kein Compare-Mode
    Tccr1b.icnc1 = 0 'NoiseCancel
    Tccr1b.ices1 = 1 'steigende Flanke
    Tccr1b.cs12 = 0
    Tccr1b.cs11 = 0 '001 - kein Prescaler
    Tccr1b.cs10 = 1
    Enable Interrupts

    Dim Capture As Long At &H150

    Dim Uti(6 As Long , Uti_sort(6) As Long , Uti_summe(6) As Long
    Dim Plaus1 As Word , Plaus2 As Word , Plaus1_string As String * 4 , Plaus2_string As String * 4
    Plaus1_string = "0000" : Plaus2_string = "0000"
    Dim Durchlauf As Byte : Durchlauf = 0

    Dim Werte As Long
    Dim Wcapture As Word , Wcapturealt As Word , Wzaehler As Word , Woverflow As Word


    Dim Ready As Bit : Ready = 0 'Statusbit Messung
    Dim Index As Byte : Index = 1
    Dim Index1 As Byte : Index1 = 1
    Dim R_ref As Byte : R_ref = 100 'Größe des Referenzwiderstandes
    Dim Delta_t As Byte : Delta_t = 8

    Declare Function Ohmgrad(t_off1 As Long , T_off2 As Long , T_ref As Long , T_x As Long , R_ref As Byte) As Single

    'Werte aus http://www.abmh.de/pt100/#umr
    Const A = 3367.8214408825
    Const B = 11342221.257667569
    Const C = 17235.4360565322

    Dim I As Byte : I = 0
    Dim J As Byte : J = 0
    Dim K As Byte : K = 0



    '####################### Temperaturen #####################################
    Dim T1 As Single , T1_string As String * 5 , T1_word As Word
    Dim T2 As Single , T2_string As String * 5 , T2_word As Word
    Dim T1_ringpuffer(32) As Word , T2_ringpuffer(32) As Word

    Dim Rp_counter As Byte , Rp_pointer As Byte

    Dim 8_werte_mittel_t1 As Long , 16_werte_mittel_t1 As Long , 32_werte_mittel_t1 As Long
    Dim 8_werte_mittel_t2 As Long , 16_werte_mittel_t2 As Long , 32_werte_mittel_t2 As Long

    Dim 8_werte_mittel_t1_string As String * 4 , 16_werte_mittel_t1_string As String * 4 , 32_werte_mittel_t1_string As String * 4
    Dim 8_werte_mittel_t2_string As String * 4 , 16_werte_mittel_t2_string As String * 4 , 32_werte_mittel_t2_string As String * 4

    Dim 32_werte_mittel_t1_rp(32) As Long ', 32_werte_mittel_t2_rp(32) As Long

    Dim Anstieg_t1 As Integer , Anstieg_t2 As Integer
    Dim Anstieg_t1_str As String * 5 , Anstieg_t2_str As String * 5

    Dim Help_byte As Byte
    Dim Init As Bit : Init = 0
    '################################################# #############################


    Print : Print "NEUSTART" : Print
    Do
    Gosub Temperaturen
    Incr Durchlauf
    'Waitms 500
    Loop
    End



    Temperaturen:
    Ready = 0
    Index = 0
    Timsk.ticie1 = 1 'Input Capture Interrupt enable
    Timsk.toie1 = 1 'Overflow Interrupt enable
    Do : Loop Until Ready = 1
    Timsk.ticie1 = 0 'Input Capture Interrupt disable
    Timsk.toie1 = 0 'timer overflow interrupt disable
    K = 4 'anzahl ungenutzter Messwerte
    For J = 1 To 6 'K+J*I Meswerte
    Incr K
    Uti_summe(j) = Uti(k)
    Next J
    Gosub Sortieren
    Gosub Rechnen
    Return


    Onoverflow:
    Incr Woverflow
    Return


    Oncapture:
    Wcapture = Capture1

    Werte = Woverflow * 65536
    Werte = Werte + Wcapture
    Werte = Werte - Wcapturealt

    Wcapturealt = Wcapture

    Uti(index) = Werte
    Woverflow = 0
    Incr Index
    If Index > 10 Then
    Index = 1
    Ready = 1
    End If
    Return



    Sortieren:
    K = 1
    For J = 2 To 6
    If Uti_summe(k) > Uti_summe(j) Then K = J 'kleinsten Wert finden
    Next J
    Select Case K
    Case 1 : If Uti_summe(6) < Uti_summe(2) Then K = 6
    Case 6 : If Uti_summe(5) < Uti_summe(1) Then K = 5
    Case Else : If Uti_summe(k - 1) < Uti_summe(k + 1) Then K = K - 1
    End Select
    For J = 1 To 6
    I = J + K
    I = I - 1
    If I > 6 Then I = I - 6
    Uti_sort(j) = Uti_summe(i) 'sortierte Timer-Werte -> uti_sort
    Next J
    'Gosub Loggen
    Return



    Loggen:
    Print Uti_sort(1) ; Spc(3) ; Uti_sort(2) ; Spc(3) ; Uti_sort(3) ; Spc(3) ; Uti_sort(4) ; Spc(3) ; Uti_sort(5) ; Spc(3) ; Uti_sort(6) '; "," ; T1_string ; "," ; T2_string
    Return


    Rechnen:
    T1 = Ohmgrad(uti_sort(1) , Uti_sort(2) , Uti_sort(3) , Uti_sort(4) , R_ref)
    T2 = Ohmgrad(uti_sort(1) , Uti_sort(2) , Uti_sort(3) , Uti_sort(5) , R_ref)
    T1 = T1 * 10 : T1_word = T1 : T1_string = Str(t1_word) : T1_string = Format(t1_string , "0000")
    T2 = T2 * 10 : T2_word = T2 : T2_string = Str(t2_word) : T2_string = Format(t2_string , "0000")

    If Durchlauf > 20 Then
    Durchlauf = 100 'Wert egal, nur größer 20
    Gosub Plausibilitaet
    End If
    Gosub Mitteln
    'Gosub Anstieg

    Print T1_string ; Spc(2) ; 8_werte_mittel_t1_string ; Spc(2) ; 16_werte_mittel_t1_string ; Spc(2) ; 32_werte_mittel_t1_string ; " | ";
    Print T2_string ; Spc(2) ; 8_werte_mittel_t2_string ; Spc(2) ; 16_werte_mittel_t2_string ; Spc(2) ; 32_werte_mittel_t2_string ; " | ";
    Print Plaus1_string ; Spc(2) ; Plaus2_string ; " | ";
    Print Anstieg_t1 '; Spc(2) ; Anstieg_t2

    'Print T1_string ; 8_werte_mittel_t1_string ; 16_werte_mittel_t1_string ; 32_werte_mittel_t1_string ;
    'Print T2_string ; 8_werte_mittel_t2_string ; 16_werte_mittel_t2_string ; 32_werte_mittel_t2_string ;
    'Print Plaus1_string ; Plaus2_string
    Return



    Function Ohmgrad(t_off1 As Long , T_off2 As Long , T_ref As Long , T_x As Long , R_ref As Single) As Single
    Local Zaehler As Long , Nenner As Long , Grad As Single , R As Long , T_off As Long
    Local R_single As Single
    T_off = T_off1 + T_off2
    Zaehler = T_x - T_off :
    Nenner = T_ref - T_off
    R = Zaehler * R_ref
    R_single = R / Nenner
    Grad = R_single - R_ref
    Grad = Grad * C
    Grad = B - Grad
    Grad = Sqr(grad)
    Grad = A - Grad
    Ohmgrad = Grad
    End Function



    Mitteln:
    If Init = 0 Then 'Startwerte
    For Rp_counter = 1 To 32
    T1_ringpuffer(rp_counter) = T1_word
    T2_ringpuffer(rp_counter) = T2_word
    32_werte_mittel_t1_rp(rp_counter) = 0
    '32_werte_mittel_t2_rp(rp_counter) = 0
    Next Rp_counter
    Init = 1
    End If

    Incr Rp_counter : If Rp_counter > 32 Then Rp_counter = 1 'Ringpuffer
    T1_ringpuffer(rp_counter) = T1_word
    T2_ringpuffer(rp_counter) = T2_word

    32_werte_mittel_t1 = 0
    32_werte_mittel_t2 = 0
    16_werte_mittel_t1 = 0
    16_werte_mittel_t2 = 0
    8_werte_mittel_t1 = 0
    8_werte_mittel_t2 = 0

    Rp_pointer = Rp_counter
    For Help_byte = 1 To 32
    32_werte_mittel_t1 = 32_werte_mittel_t1 + T1_ringpuffer(rp_pointer)
    32_werte_mittel_t2 = 32_werte_mittel_t2 + T2_ringpuffer(rp_pointer)
    If Help_byte <= 16 Then
    16_werte_mittel_t1 = 16_werte_mittel_t1 + T1_ringpuffer(rp_pointer)
    16_werte_mittel_t2 = 16_werte_mittel_t2 + T2_ringpuffer(rp_pointer)
    End If
    If Help_byte <= 8 Then
    8_werte_mittel_t1 = 8_werte_mittel_t1 + T1_ringpuffer(rp_pointer)
    8_werte_mittel_t2 = 8_werte_mittel_t2 + T2_ringpuffer(rp_pointer)
    End If
    Rp_pointer = Rp_pointer - 1
    If Rp_pointer < 1 Then Rp_pointer = 32
    Next Help_byte
    Shift 8_werte_mittel_t1 , Right , 3 : 8_werte_mittel_t1_string = Str(8_werte_mittel_t1) : 8_werte_mittel_t1_string = Format(8_werte_mittel_t1_string , "0000")
    Shift 8_werte_mittel_t2 , Right , 3 : 8_werte_mittel_t2_string = Str(8_werte_mittel_t2) : 8_werte_mittel_t2_string = Format(8_werte_mittel_t2_string , "0000")
    Shift 16_werte_mittel_t1 , Right , 4 : 16_werte_mittel_t1_string = Str(16_werte_mittel_t1) : 16_werte_mittel_t1_string = Format(16_werte_mittel_t1_string , "0000")
    Shift 16_werte_mittel_t2 , Right , 4 : 16_werte_mittel_t2_string = Str(16_werte_mittel_t2) : 16_werte_mittel_t2_string = Format(16_werte_mittel_t2_string , "0000")
    Shift 32_werte_mittel_t1 , Right , 5 : 32_werte_mittel_t1_string = Str(32_werte_mittel_t1) : 32_werte_mittel_t1_string = Format(32_werte_mittel_t1_string , "0000")
    Shift 32_werte_mittel_t2 , Right , 5 : 32_werte_mittel_t2_string = Str(32_werte_mittel_t2) : 32_werte_mittel_t2_string = Format(32_werte_mittel_t2_string , "0000")
    32_werte_mittel_t1_rp(rp_counter) = 32_werte_mittel_t1


    If Rp_counter <= Delta_t Then Help_byte = Rp_counter + 32 Else Help_byte = Rp_counter
    Help_byte = Help_byte - Delta_t

    Anstieg_t1 = 32_werte_mittel_t1_rp(rp_counter) - 32_werte_mittel_t1_rp(help_byte)
    'Anstieg_t1 = 32_werte_mittel_t2_rp(rp_counter) - 32_werte_mittel_t2_rp(help_byte)
    Return



    Plausibilitaet:
    'Plausibilität prüfen
    'mehr als doppelt so große Werte, als auch weniger als halb so kleine Werte
    'werden gegen 8-Werte-Mittel ersetzt
    Plaus1 = 8_werte_mittel_t1 : Shift Plaus1 , Left , 1
    Plaus2 = 8_werte_mittel_t1 : Shift Plaus2 , Right , 1
    If T1_word < Plaus2 Or T1_word > Plaus1 Then
    Plaus1_string = Str(t1_word)
    T1_word = 8_werte_mittel_t1
    T1_string = Str(t1_word)
    T1_string = Format(t1_string , "0000")
    Else
    Plaus1_string = "0000"
    End If

    Plaus1 = 8_werte_mittel_t2 : Shift Plaus1 , Left , 1
    Plaus2 = 8_werte_mittel_t2 : Shift Plaus2 , Right , 1
    If T2_word < Plaus2 Or T2_word > Plaus1 Then
    Plaus2_string = Str(t2_word)
    T2_word = 8_werte_mittel_t2
    T2_string = Str(t2_word)
    T2_string = Format(t2_string , "0000")
    Else
    Plaus2_string = "0000"
    End If
    Return

  2. #2
    Erfahrener Benutzer Robotik Visionär
    Registriert seit
    26.11.2005
    Ort
    bei Uelzen (Niedersachsen)
    Beiträge
    7.942
    Die Definition von Capture ist Problematisch, weil eine absolute Adresse für die Variable angegeben wird. Wenn es nur damit geht, spricht das dafür, dass irgendwo eine Stack überläuft, oder ein Array Index zu groß wird.

    Mit dem zu großen Array und der Absoluten Adresse wird ggf. dafür gesorgt, das der Überlauf nur einen ungenutzten Bereich betrifft. Das kann dann zwar funktionieren, ist aber alles andere als sauberer Programierstiel.

  3. #3
    Benutzer Stammmitglied
    Registriert seit
    19.02.2010
    Beiträge
    67
    Leider ist mein Programm sehr unübersichtlich dargestellt...sorry dafür.
    Weiterhin wollte auch nichts aus dem Kontext reißen und nur Fragmente anbieten.

    Die Variable Capture wurde in einer vorherigen Version genutzt - da mit Overlays auf das hi-word und die unteren bytes.

    in der jetzigen Lösung - gemäß dem Roland Walther - Buch lass ich den Timer durchlaufen, und nutze zur Berechnung die wCapture- und wZaehler-Variablen.

    Der Teil haut prima hin - entferne ich nun aber die unbenutzte Capture-Variable auf der festen Adresse, startet mein Mikrocontroller laufend neu.
    Er kommt dabei unterschiedlich weit, meißt nur bis in die Hauptschleife, vereinzelt wird sie wohl aber komplett durchlaufen, so dass ich sogar eine Ausgabe bekomme, mit abenteuerlichen (negativen, betragsmäßig falschen) Werten.


    Die zweite problematische Variable ist die uti(6 (die mit dem smilie).
    Ursprünglich war es ein 100er Array, in dem 100 aufeinanderfolgende Capture-Werte abgelegt wurden.
    Die Mittelung der Capturewerte war dann nicht mehr notwendig, so dass ich nur noch 10 Werte aufnehme.
    Nun brachte das verkleinern des Arrays wiederum genau den Effekt, dass der Controller stets neu startete.

    Erst mit späterer Einführung eines weiteren Arrays (32_werte_mittel_t1_rp(32)), ließ der sich genau um die 32-Word-Werte verkleinern, die das neue Array einnahm.
    nun will ich noch so einen Puffer für den zweiten Messwert anlegen, gerate damit aber über den SRAM. Ein weiteres verkleinern des unnötig grossen uti(k) fuktioniert aber auch nicht.

  4. #4
    Erfahrener Benutzer Robotik Visionär
    Registriert seit
    26.11.2005
    Ort
    bei Uelzen (Niedersachsen)
    Beiträge
    7.942
    Ich würd man Porbieren die Werte für
    $swstack = 100
    $hwstack = 100

    noch etwas größer zu machen. Die Werte sind schon nicht so klein, aber da werden zum Teil ziehmlich viele Prameter übergegen.

Berechtigungen

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

Solar Speicher und Akkus Tests