-         

Ergebnis 1 bis 10 von 10

Thema: Berechnung mit long-Variable fehlerhaft

  1. #1
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    21.09.2004
    Beiträge
    264

    Berechnung mit long-Variable fehlerhaft

    Anzeige

    Hallo,

    ich bilde einen Mittelwert aus 256 Messungen eines 12-bit-AD-Wandlers.
    Hierzu summiere ich die 256 Messwerte auf und teile anschließend die Summe durch 256. Die Summe ist also immer im Bereich 0 bis 1048320 (=256*4095). Eigentlich müsste das in eine long-Variable passen. Die Berechnung ergibt aber unsinnige Werte. Deklariere ich die Summenvariable als single, funktioniert alles einwandfrei.

    Hat jemand eine Idee, warum das so ist?

    mfg

    Stefan

  2. #2
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    09.11.2004
    Ort
    Hard, Vorarlberg
    Beiträge
    155
    Ich habe die Aufsummierung einer Long-Variable und Division durch 256 getestet und keinen Fehler gefunden.
    Da müsste man eventuell Deinen verwendeten Code sehen, um hier weiterhelfen zu können.

    In Deinem Fall, wo Du 256 Einzelwerte für die Durchschnittberechnung benutzt, kann der Mittelwert sogar ohne Division ermittelt werden.
    Eine Division durch 256 ist eine Verschiebung der 4 Einzelbytes um jeweils 1 Position nach rechts. Das heißt der Durchschnittswert sind die Bytes 2, 3 und 4 der Long-Variable und einer 0 als neues Most-Significant Byte.
    Dieser Fall kann mit einem OVERLAY gelöst werden.

    Code:
    Dim lSumme as Long
    Dim bDummy as  Byte
    Dim lDurchschnitt as Long at lSumme + 1 overlay
    Dim lEinzel as Long
    
    lSumme = 0
    for lEinzel = 15000 to 15255
       lSumme = lSumme + lEinzel
    next
    
    print lDurchschnitt
    Das bDummy ist nötig, damit lDurchschnitt als 4. Byte (MSB) immer einen definierten 0-Wert hat.


    Wenn die Anzahl der Einzelmessungen für den Durchschnittwert eine 2-er Potenz ist, also 2, 4, 8, 16, 32, 64 ..... dann kann mit einem SHIFT RIGHT die Division ersetzt werden. Hier ein Beispiel mit 64 Einzelmessungen.

    Code:
    Dim lEinzel as Long
    Dim lSumme as Long
    Dim lDurchschnitt as Long
    
    lSumme = 0
    
    For lEinzel = 15000 to 15063
       lSumme = lSumme + lEinzel
    next
    
    Shift lSumme, RIGHT, 6
    
    lDurchschnitt = lSumme
    
    Print lDurchschnitt
    Da eine Division vergleichsweise eine zeitaufwendige Berechnung ist, lässt sich mit diesen beiden Methoden besonders in zeitkritischen Applikationen Rechenzeit sparen.
    Viele Grüße
    Josef
    -------------------------------------------------------------------------------------
    DOS-File System für BASCOM-AVR auf http://members.aon.at/voegel

  3. #3
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    21.09.2004
    Beiträge
    264
    Danke für Deine Mühen.

    Hier mal der Code-Ausschnitt:

    Code:
    Const Max127wr = 84
    Const Max127rd = 85
    Const Controlbytequer = &B11100000                          'Ch6, 0 bis 5V, normal Operation
    Const Controlbytehoehe = &B11110000                         'Ch7, 0 bis 5V, normal Operation
    Const Controlbytedruck = &B10110000                         'Ch3, 0 bis 5V, normal Operation
    Const Controlbyteakku = &B11000000                          'Ch4, 0 bis 5V, normal Operation
    
    
    Const Controlbytegyrox = &B10010000                         'Ch1, 0 bis 5V, normal Operation    Vielleicht falsch herum !!!!!!!!!!!!!!!!
    Const Controlbytegyroy = &B10100000                         'Ch2, 0 bis 5V, normal Operation
    
    
    
    Dim I As Byte , Accsumme As Single
    Dim Wert As Word , Wert2 As Word
    
    Dim Highbyte As Byte , Lowbyte As Byte
    
    _lcd_e = 128                                                'Upper half of 4-line display is selected
    
    
    
    Declare Function Max127lesen(byval Chsetting As Byte) As Word
    
    
    Accsumme = 0
    For I = 0 To 255
    Wert = Max127lesen(controlbytequer)
    Accsumme = Accsumme + Wert
    Next
    Wert = Accsumme / 256
    Locate 1 , 1
    Lcd "Quer : " ; Wert ; "     "
    
    
    end
    
    Function Max127lesen(byval Chsetting As Byte) As Word
    Local Adwert As Word
    I2cinit
    I2cstart
    I2cwbyte Max127wr
    I2cwbyte Chsetting
    I2cstop
    I2cstart
    I2cwbyte Max127rd
    I2crbyte Highbyte , Nack
    I2crbyte Lowbyte , Nack
    I2cstop
    Adwert = Highbyte * 16
    Lowbyte = Lowbyte / 16
    Adwert = Adwert + Lowbyte
    Max127lesen = Adwert
    End Function
    Der "Ruhewert" lliegt bei ca 1900. Wenn ich die Variable ACCSumme als "long" deklariere, kommen nur noch 3-stellige Ergebnisse heraus.

    Die Zahl 256 habe ich bewusst gewählt, weil ich dachte, der Controller/Bascom rechnet dann mittels Verschieben der bits.

  4. #4
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    16.02.2006
    Beiträge
    1.112
    Ohne es ausprobiert zu haben denke ich, dass das an deinen impliziten Typ-Wandlungen liegt:
    Wert = Accsumme / 256
    Probier mal so:
    Accsumme = Accsumme / 256
    Wert = Accsumme

    Gruß

    Rolf

  5. #5
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    09.11.2004
    Ort
    Hard, Vorarlberg
    Beiträge
    155
    Ich denke, Rolf hat Recht. Zuerst werden die Variablen in den Typ der Zielvariable umgewandelt und bei LONG --> WORD, die LONG links beschnitten und damit bei Werten über 65535 verändert.

    Bei Deiner Variante mit der Voraussetzung, dass der aufsummierte Wert nicht größer als 16777215 (2^24 - 1) wird, kann die OVERLAY - Variante noch etwas vereinfacht werden:

    Code:
    Dim lSumme as Long
    Dim wDurchschnitt as Word at lSumme + 1 overlay
    Dim lEinzel as Long
    
    lSumme = 0
    for lEinzel = 3000 to 3255
       lSumme = lSumme + lEinzel
    next
    
    print wDurchschnitt
    Hier wird der Durchschnittswert gleich als WORD definiert und ist damit innerhalb des SRAM-Bereiches der LONG-Variable, welche die aufsummierten Werte aufnimmt.
    Viele Grüße
    Josef
    -------------------------------------------------------------------------------------
    DOS-File System für BASCOM-AVR auf http://members.aon.at/voegel

  6. #6
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    16.02.2006
    Beiträge
    1.112
    Zitat Zitat von oe9vfj
    Dim wDurchschnitt as Word at lSumme + 1 overlay
    Ziemlich clevere Lösung für das Teilen durch 256!

    Gruß

    Rolf

  7. #7
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    21.09.2004
    Beiträge
    264
    Danke für Eure Überlegungen. Da ich die Hardware im Büro habe, kann ich es erst am Montag testen. Die Art und Weise, wie typverschiedene Variablen übergeben geben war mir nicht bekannt. Ich beschäftige mich erst seit ein paar Wochen mit Bascom und "übersetze" ein C-Control-Project auf ein RN-Mega2560.

    Stefan

  8. #8
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    21.09.2004
    Beiträge
    264
    Ohne es ausprobiert zu haben denke ich, dass das an deinen impliziten Typ-Wandlungen liegt:
    Wert = Accsumme / 256
    Probier mal so:
    Accsumme = Accsumme / 256
    Wert = Accsumme
    Du hast recht, so geht es.


    Code:
    Dim lSumme as Long 
    Dim wDurchschnitt as Word at lSumme + 1 overlay 
    Dim lEinzel as Long 
    
    lSumme = 0 
    for lEinzel = 3000 to 3255 
       lSumme = lSumme + lEinzel 
    next 
    
    print wDurchschnitt
    Diese Variante ist natürlich wunderbar. Wenn ich bei 256 Messungen bleibe, ist diese Variante natürlichg erste Sahne.

    Vielen Dank für Eure Bemühungen.


    Stefan

  9. #9
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    09.11.2004
    Ort
    Hard, Vorarlberg
    Beiträge
    155
    Wenn Du mit wDurchschnitt weiterarbeiten willst, nachdem die lSumme wieder verändert wird (neuer Meßzyklus) musst diese in eine eigene Word-Variable umspeichern. Mit jeder Änderung von lSumme wird natürlich auch wDurchschnitt (überlagert zu lSumme) verändert.
    Viele Grüße
    Josef
    -------------------------------------------------------------------------------------
    DOS-File System für BASCOM-AVR auf http://members.aon.at/voegel

  10. #10
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    21.09.2004
    Beiträge
    264
    Ja, danke. Das ist mir schon klar.

    mfg

    Stefan

Berechtigungen

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