- LiFePO4 Speicher Test         
Ergebnis 1 bis 10 von 10

Thema: ungewollt geänderte Variable in einer function - spuk?

  1. #1
    Benutzer Stammmitglied
    Registriert seit
    01.01.2008
    Alter
    43
    Beiträge
    48

    ungewollt geänderte Variable in einer function - spuk?

    Anzeige

    Praxistest und DIY Projekte
    Hallo und Frohes Neues!

    Ich kämpfe hier mittlerweile seit 2 Tagen mit einer Kleinigkeit herum, die in anderen Sprachen vielleicht in 2 Minuten erledigt ist aber irgendwie brauche ich mal eine kleine Aufklärung.

    Ich versuche eine Kleine Routine zu schreiben, der ich einen Prozentwert übergebe. Ich möchte dann hinterher den Prozentwert als Balken auf einem Display ausgegeben haben. Ein ähnliches Programm habe ich hier bereits entdeckt, aber der Stolz...

    Hier die Deklaration:
    Code:
    Declare Function Ausgabe(byval Prozent As Byte) As String
    Hier meine Funktion:
    Code:
    Function Ausgabe(byval Prozent As Byte)
    Local Temp As Integer
    Local Temp2 As Word
    Local Temp3 As String * 20
    
    Temp = Prozent / 10
    For Temp2 = 1 To Temp Step 1
    Temp3 = Temp3 + "#"
    Next
    
    Ausgabe = temp3
    End Function

    Mein Problem: Ich kann mit der Programmierung meiner Routine nicht fortfahren weil die übergebenen Werte ständig falsch ankommen.

    Beispiel:
    Ich rufe die Funktion auf: ausgabe(125)
    Der Wert 125 kommt so momentan an. Fein.

    Ändere ich die Funktion mit einer Kleinigkeit ab funktioniert nix mehr:
    Code:
    Function Ausgabe(byval Prozent As Byte)
    Local Pe As Word
    Local Temp As Integer
    Allein die Deklaration von Pe als Word führt dazu, dass sich der Wert von "Prozent" auf den vollkommen unklaren Wert von 59 ändert.


    Das kann und darf doch wohl auf keinen Fall sein, oder habe ich etwas übersehen? Ich hätte nie gedacht, dass ich mich mal an so einer Kleinigkeit so festbeissen würde.


    Beste Grüße,
    Mathias[/php]

  2. #2
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    13.05.2005
    Alter
    32
    Beiträge
    601
    Hi,

    ich würde das mit ner Sub machen:

    Code:
    $regfile = "m8def.dat"                                      ' specify the used micro
    $crystal = 1000000
    $baud = 4800
    
    Declare Sub Get_prozent
    Dim Ausgabe As String * 20
    Dim Eingabe As Byte
    
    Do
    
    Input "Eingabe: " , Eingabe
    Call Get_prozent
    Print "Ausgabe: " ; Ausgabe
    
    Loop
    
    End
    
    Sub Get_prozent
    Ausgabe = ""
    Local Temp As Integer
    Local Temp2 As Byte
    
    Temp = Eingabe / 10
    
    For Temp2 = 1 To Temp Step 1
    Ausgabe = Ausgabe + "#"
    Next
    
    Temp2 = 0
    
    End Sub
    Das funktioniert bei mir in Simulator.
    Grüße Furtion

  3. #3
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    29.07.2007
    Beiträge
    386
    ....ich würde das mit ner Sub machen: .....

    warum nicht eine funktion. wenn die werte richtig übergeben werden funktioniert sie auch.

  4. #4
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    22.05.2005
    Ort
    12°29´ O, 48°38´ N
    Beiträge
    2.731
    Hallo,

    @mathias172
    evtl. musst Du Dir mal diese Seite durchlesen:
    https://www.roboternetz.de/wissen/in.../Bascom_Inside
    und die Werte im Programm für $swstack und $framesize erhöhen !

  5. #5
    Benutzer Stammmitglied
    Registriert seit
    01.01.2008
    Alter
    43
    Beiträge
    48
    Hallo Furtion, hallo roboterheld,

    mir gehts eigentlich gar nicht um die Lösung meiner Programmieraufgabe, sonder eher darum, dass ich herausbekomme, warum ausgerechnet diese Konstellation nicht funktioniert. So ein Kleinkram kann für eine Menge Verwirrung sorgen wenn man mal ein umfangreicheres Projekt hat.

    Könnt ihr dasselbe Problem beobachten wenn ihr die Funktion mal bei euch laufen lasst?

    Im Anhang nochmal das komplette Programm (mittlerweile recht zerrupft).
    Allein durch die Zeile "Local Pe As Word" ändert sich der Ausgabewert der Funktion obwohl nirgens mit "Pe" gearbeitet wird.


    Code:
    $crystal = 8000000
    
    Config Lcd = 20 * 4                                         'Anzeigemodus 40 x 4 Zeichen
    Config Lcdpin = Pin , E = Portb.6 , Rs = Portb.7 , Db4 = Portb.3 , Db5 = Portb.2 , Db6 = Portb.1 , Db7 = Portb.0 , E2 = Portb.5
    
    Dim X As Integer , Mini As Byte , Maxi As Byte , Ausgabe As Byte , Teststring As String * 10
    Dim A As Long , B As Long
    Dim ___lcdno As Byte
    
    Config Servos = 1 , Servo1 = Portc.0 , Reload = 10 , Timer = Timer0
    Config Portb = Output
    Config Portd = Input
    Enable Interrupts
    
    Declare Function Ausgabe(byval Prozent As Byte) As String
    
    ___lcdno = 0
    Initlcd
    Cls
    
    
    Portd = 1
    Mini = 30
    Maxi = 160
    X = Maxi - Mini
    X = X / 2
    X = X + Mini
    
    
    Do
       If Pind.0 = 0 Then X = X + 1
       If Pind.1 = 0 Then X = X - 1
       If Pind.2 = 0 Then X = X + 10
       If Pind.3 = 0 Then X = X - 10
       Waitms 50
    
       Dim P As Integer , P2 As Integer , Y As Integer
       Y = X
       P = Maxi - Mini
       P = P / 100
       P2 = Mini + Y
       P = P2 / P
    
    
       Locate 1 , 1
       Teststring = Ausgabe(90)
    
       Servo(1) = X
    Loop
    End
    
    
    Function Ausgabe(byval Prozent As Byte)
    Local Pe As Word
    Local Temp As Integer
    Lcd Prozent
    Local Temp2 As Word
    Local Temp3 As String * 20
    
    Temp = Prozent / 10
    For Temp2 = 1 To Temp Step 1
    Temp3 = Temp3 + "##"
    Next
    
    Ausgabe = Str(prozent) + " " + Temp3
    Temp3 = ""
    Temp2 = 0
    Ausgabe = Str(prozent)
    
    End Function

  6. #6
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    09.05.2007
    Beiträge
    202
    Hallo Matthias,

    Linux_80 hat vermutlich die Problemlösung bereits aufgezeigt. Was hast du denn als Stackwerte eingetragen? Hast du schon versucht, die zu erhöhen?
    Gruß, Stefan

  7. #7
    Benutzer Stammmitglied
    Registriert seit
    01.01.2008
    Alter
    43
    Beiträge
    48
    Hello again

    Es liegt/lag tatsächlich am swstack. Vielen Dank für die Hilfe.

    Ich werde mal meine Zeilen entwirren und dann nochmal posten. Vielleicht kann ja mal jemand die Funktion brauchen.

  8. #8
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.842
    "local" geht direkt auf die Framesize, vorsicht !

    https://www.roboternetz.de/wissen/in.../Bascom_Inside
    mfg robert
    Wer glaubt zu wissen, muß wissen, er glaubt.

  9. #9
    Benutzer Stammmitglied
    Registriert seit
    01.01.2008
    Alter
    43
    Beiträge
    48
    Gibt es einen empfehlenswerteren Weg als lokale Variablen?
    Mir fiel auch auf, dass die Locals Ihre Werte nach Ablauf der Funktion behalten und beim nächsten Aufruf immer noch zur Verfügung stehen, d.h. in meinem Fall jedes Mal wieder auf 0 gesetzt werden müssen.

    Wie auch immer. Anbei nochmal mein gesamtes Programm mit der Funktion.
    Kurzfassung: Das Ganze hat einen Servo an den Ports C und ein Wintek (Pollin) Display an Port B. An Port D hole ich mir Schalterzustände mit denen ich die Servoposition einstellen kann. In der ersten Display-Zeile wird der Prozentuale Wert angegeben, in der zweiten Zeile der Balken. Funktionsaufruf ist mit Prozentwert und Maximal möglicher Balkenlänge.

    Code:
    $crystal = 8000000
    $framesize = 32                                             ' die Größe des Frames
    $swstack = 320                                              ' die Größe des Software-stacks
    $hwstack = 32                                               ' die Größe des Hardware-Stacks
    
    Config Lcd = 20 * 4                                         'Anzeigemodus 40 x 4 Zeichen
    Config Lcdpin = Pin , E = Portb.6 , Rs = Portb.7 , Db4 = Portb.3 , Db5 = Portb.2 , Db6 = Portb.1 , Db7 = Portb.0 , E2 = Portb.5
    Dim ___lcdno As Byte
    
    Config Servos = 1 , Servo1 = Portc.0 , Reload = 10 , Timer = Timer0
    Config Portb = Output
    Config Portd = Input
    
    Dim X As Byte , Mini As Byte , Maxi As Byte , Ausgabe As Byte , Temp As Byte
    Dim P As Single , P2 As Integer
    
    Enable Interrupts
    
    Declare Function Balken(byval Prozent As Single , Byval Laenge As Byte) As String
    
    ___lcdno = 1
    Initlcd
    Cls
    
    ___lcdno = 0
    Initlcd
    Cls
    Cursor Off
    
    Portd = 1
    Mini = 40
    Maxi = 155
    X = Maxi - Mini
    X = X / 2
    X = X + Mini
    
    
    
    Do
    
       P = Maxi - Mini
       P = P / 100
       P2 = X - mini
       P = P2 / P
       P = Round(p)
    
    
    
       If Pind.0 = 0 Then
          Temp = X + 2
          If Temp <= Maxi Then X = X + 2
       End If
    
       If Pind.1 = 0 Then
             Temp = X - 2
          If Temp => Mini Then X = X - 2
       End If
    
    
       If Pind.2 = 0 Then
             Temp = X + 10
          If Temp <= Maxi Then X = Maxi
       End If
    
    
       If Pind.3 = 0 Then
          Temp = X - 10
          If Temp => Mini Then X = Mini
       End If
    
       Locate 1 , 1
       Lcd P
       Locate 2 , 1
       Lcd Balken(p , 20)
       Servo(1) = X
    
       Loop
    End
    
    
    Function Balken(byval Prozent As Single , Byval Laenge As Byte)
       Local Temp1 As Single
       Local Temp2 As Single
       Local Temp3 As String * 40
    
       Laenge = Laenge - 2
    
       Temp1 = Prozent * Laenge
       Temp1 = Temp1 / 100
    
       If Prozent <= 1 Then Temp3 = "" Else Temp3 = "#"
    
       For Temp2 = 1 To Temp1 Step 1
       Temp3 = Temp3 + "#"
       Next
       Balken = Temp3 + " "
    End Function

  10. #10
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    26.05.2007
    Beiträge
    594
    Also die Locals werden glaubich im Simulator nur einfach nicht gelöscht.
    Sobald die Sub zuende ist, werden die Speicherplätze wieder "recyclet" und beim neu initialisieren gelöscht.

Berechtigungen

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

LiTime Speicher und Akkus