- 12V Akku mit 280 Ah bauen         
Ergebnis 1 bis 10 von 10

Thema: Probleme mit Single-Variablen

  1. #1
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    08.11.2005
    Ort
    QTH: JO43BC
    Alter
    56
    Beiträge
    112

    Probleme mit Single-Variablen

    Anzeige

    Powerstation Test
    Hallo,

    Ich habe da ein kleines Problem mit einigen Single-Variablen. Wenn ich folgende Variablen auf einem ATMega16 mit diesen Werten deklariere:

    A1 = 50.16666667
    A2 = 7.2
    A3 = 53.16666667
    A4 = 7.226016667

    und diese Werte wieder auf dem LCD ausgebe, wird folgendes angezeigt:

    A1 = 50.16666667936
    A2 = 7.199999806
    A3 = 53.16666667936
    A4 = 7.226016518

    Sinn und Zweck des Ganzen ist eine Distanz- und Winkelberechnung in Kilometern zwischen zwei angegebenen Koordinaten. Mit der ACOS-Funktion habe ich auch noch so meine Probleme. Auch hier erhalte ich voellig unterschiedliche Ergebnisse. Diese unterscheiden sich vom ATMega16 und einem PC oder Taschenrechner gravierend.

    B10 = 0.999999958
    B11 = Acos(B10)

    Hier erhalte ich auf dem angeschlossenen LCD als Ergebnis: 0.000345228
    Berechne ich das im Excel mit der Funktion: ARCCOS(B10), dann erhalte ich als Ergebnis: 0.0002908617

    Irgendwas stimmt da doch nicht? Was mache ich denn da falsch?
    Ich benutze das aktuelle Bascom 1.11.8.2 (auch die letzten Updates habe ich mir gezogen)

    Mit freundlichen Gruessen
    Digitali

  2. #2
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    08.11.2005
    Ort
    QTH: JO43BC
    Alter
    56
    Beiträge
    112
    Problem geloest!
    Habe alle Variablen als Double deklariert. Nach einer Vergleichsrechnung zwischen einer Excelfunktion und dem ATMega habe ich zwischen zwei Koordinaten 4m Differenz auf einem knappen Kilometer. Naja, damit kann ich leben.

    Ich wollte damit eine GPS-Mouse auslesen. Zu der aktuellen Position laesst sich dann eine zweite Koordinate eintippen und ein GOTO starten. Auf dem GLCD wird dann eine Kompassrose gezeichnet und ein Pfeil zeigt mir die Richtung an in der man fahren muss. Und die noch verbleibene Wegstrecke in Kilometern. Eine Art Navigation nur nach Pfeil. Das ganze soll vielleicht mal als Festeinbau ins Auto. Fuer mich als aktiver Geocacher und Atmelbastler genau das Richtige.

  3. #3
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    09.11.2004
    Ort
    Hard, Vorarlberg
    Beiträge
    155
    Bei Verwendung von Gleitkommazahlen (SINGLE und DOUBLE) ist zu beachten, dass viele Dezimalzahlen nicht genau repräsentiert werden können. SINGLE hat eine Auflösung von 24 Bit und DOUBLE eine solche von 53Bit. Dies entspricht bei SINGLE etwa 8 Dezimalziffern und bei DOUBLE etwa 16 Dezimalziffern. (ich verwende hier Dezimalziffern anstatt Dezimalstellen, da auch die Ziffern vor dem Komma miteingerechnet werden müssen)
    Zu Deinem Beispiel mit 50.16666667 ist das 50.166666. Der nächste entsprechende Binärwert im SINGLE Format ist 50.16666793823242 und entspricht ziemlich genau der Ausgabe von BASCOM-AVR.

    Die Problematik trifft auch auf Dein ACOS Beispiel zu. Der exakte Wert für 0.999999958 im SINGLE-Format ist 0.9999999403953552. Berechnet man für diesen Wert den ACOS Wert bekommt man 0.000345266985 was dem Ausgabewert von BASCOM-AVR wiederum recht genau entspricht.

    Die begrenzte Genauigkeit von SINGLE muss daher bei den Berechnungen berücksichtigt werden.

    DOUBLE hat natürlich eine wesentlich bessere Genauigkeit. Auch EXCEL verwendet das DOUBLE-Format. In BASCOM-AVR wurden die trigonometrischen Funktionen so programmiert, dass sie in der Genauigkeit in etwa denen von EXCEL entsprechen sollten.
    Daher hätte mich Deine Beispielsrechnung interessiert, welche bei Dir die Differenz von 4m ergibt.
    Viele Grüße
    Josef
    -------------------------------------------------------------------------------------
    DOS-File System für BASCOM-AVR auf http://members.aon.at/voegel

  4. #4
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    08.11.2005
    Ort
    QTH: JO43BC
    Alter
    56
    Beiträge
    112
    Hallo,

    die Abweichung von den besagten 4m hat sich geklaert. Da hatte ich nen simplen Zahlendreher in der Rechnung (irgendwann sieht man vor lauter Zahlen nichts mehr... :) ). Nun passen die Ergebnisse vom Atmel exakt mit denen von Excel ueberein. Ich habe mittlerweile auch einen ATMega128 genommen. Beim 16er war der Flash schon stellenweise zu 30% voll. Und das Programm ist ja noch laengst nicht fertig. Als naechstes die Winkelberechnung, dann grafische Aufbereitung der Daten, Auslesen einer GPS-Mouse und Abfrage einen Drehimpulsgebers (zur Eingabe von einer Koordinate). Ein Drehimpulsgeber spart Platz und sieht huebscher aus, als so ein klobiges Tastenfeld. :)

    In dem nachfolgenden Beispiel wird zunaechst nur die Distanz zweier fest vorgegebenen Koordinaten berechnet. Sicherlich laesst sich hier und da noch einiges optimieren. Das ist mal so auf die Schnelle entstanden. Hauptsache es funktioniert erstmal.


    Dim A1 As Double , A2 As Double
    Dim A3 As Double , A4 As Double
    Dim B1 As Double , B2 As Double
    Dim B3 As Double , B4 As Double
    Dim B5 As Double , B6 As Double
    Dim B7 As Double , B8 As Double
    Dim B9 As Double , B10 As Double
    Dim Distanz As Double , B11 As Double
    Dim C1 As Double , C2 As Double
    Dim C3 As Double , C4 As Double
    Dim C5 As Double , Pi As Double
    Dim Z As String * 20 , Y As Single
    Dim X As String * 10
    Pi = 3.141592654

    Initlcd
    Cursor Off
    Cls

    'Koordinate 1
    A1 = 50,16666667
    A2 = 7,2

    'Koordinate 2
    A3 = 50,16666667
    A4 = 7,226016667

    'Grundformel zur Distanzberechung zwischen zwei Koordinaten:
    '6371,229*ARCCOS(SIN(A1*PI/180)*SIN(A3*PI/180)+COS(A1*PI/180)*COS(A3*PI/180)’*COS((A2-A7)*PI/180))

    'Zerlegung der Formel
    'SIN(A1*PI/180)

    B1 = A1 * Pi
    B1 = B1 / 180
    C1 = Sin(b1)

    'SIN(A3*PI/180)

    B2 = A3 * Pi
    B2 = B2 / 180
    C2 = Sin(b2)

    'COS(A1*PI/180)

    B3 = A1 * Pi
    B3 = B3 / 180
    C3 = Cos(b3)

    'COS(A3*PI/180)

    B4 = A3 * Pi
    B4 = B4 / 180
    C4 = Cos(b4)

    'COS((A2-A4)*PI/180)

    B5 = A2 - A4
    B5 = B5 * Pi
    B5 = B5 / 180
    C5 = Cos(b5)

    'B9= (C1 * C2) + (C3 * C4 * C5)

    B6 = C1 * C2
    B7 = C3 * C4
    B8 = B7 * C5
    B9 = B6 + B8

    '6371,229*ARCCOS(B9)

    B10 = Acos(b9)
    Distanz = 6371.229 * B10

    Z = Str(distanz)
    Y = Val(z)
    X = Fusing(y , "#.####")

    Locate 1 , 1
    Lcd "Distanz: " ; X ; " Km"

  5. #5
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    09.11.2004
    Ort
    Hard, Vorarlberg
    Beiträge
    155
    Eines Sache ist mir beim schnellen Durchschauen aufgefallen:

    Für die Umrechung von Grad in Radiant gibt es die Funktion Deg2Rad()

    'SIN(A1*PI/180)

    Code:
    B1 = A1 * Pi 
    B1 = B1 / 180 
    C1 = Sin(b1)
    kann daher auch so gerechnet werden.

    Code:
    B1 = Deg2Rad(A1)
    C1 = Sin(B1)
    Das braucht weniger Code und geht schneller.

    Mit Rad2Deg() gibt es auch den umgekehrten Weg.
    Viele Grüße
    Josef
    -------------------------------------------------------------------------------------
    DOS-File System für BASCOM-AVR auf http://members.aon.at/voegel

  6. #6
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    09.11.2004
    Ort
    Hard, Vorarlberg
    Beiträge
    155
    Eine Sache ist mir beim schnellen Durchschauen aufgefallen:

    Für die Umrechung von Grad in Radiant gibt es die Funktion Deg2Rad()

    'SIN(A1*PI/180)

    Code:
    B1 = A1 * Pi 
    B1 = B1 / 180 
    C1 = Sin(b1)
    kann daher auch so gerechnet werden.

    Code:
    B1 = Deg2Rad(A1)
    C1 = Sin(B1)
    Das braucht weniger Code und geht schneller.

    Mit Rad2Deg() gibt es auch den umgekehrten Weg.
    Viele Grüße
    Josef
    -------------------------------------------------------------------------------------
    DOS-File System für BASCOM-AVR auf http://members.aon.at/voegel

  7. #7
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    08.11.2005
    Ort
    QTH: JO43BC
    Alter
    56
    Beiträge
    112
    Oh, war mir noch gar nicht aufgefallen. Und funktioniert! Danke fuer den Tipp!

    Mit freundlichen Gruessen
    Digitali

  8. #8
    Benutzer Stammmitglied
    Registriert seit
    29.09.2005
    Beiträge
    63
    Hallo,
    vielleicht ist auch meine hinzugefügte ( und sicher noch verbesserungsfähige ) Winkelberechnung noch von Interesse.

    Klaus

    '--------------------------------------------------------------------
    'Distanz und Winkel zwischen zwei geogr. Punkten

    Code:
    $lib "double.lbx"
    $regfile = "m64def.dat"
    $hwstack = 32
    $swstack = 32
    $framesize = 96
    
    Dim A1 As Double , A2 As Double
    Dim A3 As Double , A4 As Double ,
    Dim B1 As Double , B2 As Double
    Dim B3 As Double , B4 As Double
    Dim B5 As Double , B6 As Double
    Dim B7 As Double , B8 As Double
    Dim B9 As Double , B10 As Double
    Dim Dist As Double , B11 As Double
    Dim C1 As Double , C2 As Double
    Dim C3 As Double , C4 As Double
    Dim C5 As Double , Pi As Double
    Dim Radian As Double , Ga As Double
    Dim Be As Double , Le As Double
    Dim Bf As Double , Lf As Double ,
    Dim Zw As Double , Zw1 As Double
    Dim Zw2 As Double , Zw3 As Double
    Dim Bear As Double , Bear1 As Double
    Dim Bear2 As Double , Bear3 As Double
    Dim Z As String * 20 , Y As Single
    Dim X As String * 10
    Dim W As String * 20 , V As Single
    Dim U As String * 10
    
    Pi = 3.141592654
    Radian = 0.017453292                                        'Pi/180
    
    Initlcd
    Cursor Off
    Cls
    
    'Koordinate 1
    A1 = 49.96                                                  'Breite Eigen (BE)
    A2 = 8.2                                                    'Laenge Eigen (LE)
    
    'Koordinate 2
    A3 = 48.96                                                  'Breite Fremd ( BF )
    A4 = 8.2                                                    'Laenge Fremd ( LF)
    
    'Grundformel zur Distanzberechung:
    '6371.229 * Arccos(sin(a1 * Pi / 180) * Sin(a3 * Pi / 180) +
    'Cos(a1 * Pi / 180) * Cos(a3 * Pi / 180)’ * Cos((a2 -a7) * Pi / 180))
    
    'Zerlegung der Formel
    'Sin(a1 * Pi / 180)
    
    B1 = Deg2rad(a1)
    C1 = Sin(b1)
    
    'Sin(a3 * Pi / 180)
    
    B2 = Deg2rad(a3)
    C2 = Sin(b2)
    
    'Cos(a1 * Pi / 180)
    
    B3 = Deg2rad(a1)
    C3 = Cos(b3)
    
    'Cos(a3 * Pi / 180)
    
    B4 = Deg2rad(a3)
    C4 = Cos(b4)
    
    'Cos((a2 -a4) * Pi / 180)
    
    B5 = A2 - A4
    B5 = Deg2rad(b5)
    C5 = Cos(b5)
    
    'B9 =(c1 * C2) +(c3 * C4 * C5)
    
    B6 = C1 * C2
    B7 = C3 * C4
    B8 = B7 * C5
    B9 = B6 + B8
    
    '6371 , 229 * Arccos(b9)
    
    B10 = Acos(b9)
    Dist = B10 * 6371.229
    
    'Winkelberechnung ( Bearing ):
    '-----------------------------
    
    Be = A1 * Radian
    Le = A2 * Radian
    Bf = A3 * Radian
    Lf = A4 * Radian
    
    Ga = Le - Lf
    
    'Grundformeln zur Winkelberechung:
    'Zw = Cos(be) * Cos(ga) * Cos(bf) + Sin(be) * Sin(bf)
    'Zw = Atn(zw / Sqr(1 -zw * Zw))
    'Zw = Pi / 2 - Zw
    
    'Bear =((sin(bf) - Sin(be) * Cos(zw)) /(cos(be) * Sin(zw)))
    'Bear = Atn(bear / Sqr(1 -bear * Bear))
    'Bear =(pi / 2 -bear) / Radian
    'Zerlegung der Formeln:
    
    Zw1 = Cos(be)
    Zw2 = Cos(ga)
    Zw3 = Cos(bf)
    Zw2 = Zw1 * Zw2
    Zw3 = Zw2 * Zw3
    Zw1 = Sin(be)
    Zw2 = Sin(bf)
    Zw2 = Zw1 * Zw2
    Zw = Zw2 + Zw3
    
    Zw1 = Zw * Zw
    Zw1 = 1 - Zw1
    Zw1 = Sqr(zw1)
    Zw = Zw / Zw1
    Zw = Atn(zw)
    
    Zw1 = Pi / 2
    Zw = Zw1 - Zw
    
    Bear1 = Sin(bf)
    Bear2 = Sin(be)
    Bear3 = Cos(zw)
    Bear3 = Bear3 * Bear2
    Bear1 = Bear1 - Bear3
    Bear2 = Cos(be)
    Bear3 = Sin(zw)
    Bear2 = Bear2 * Bear3
    Bear = Bear1 / Bear2
    
    Bear1 = Bear * Bear
    Bear1 = 1 - Bear1
    Bear1 = Sqr(bear1)
    Bear = Bear / Bear1
    Bear = Atn(bear)
    
    Bear1 = Pi / 2
    Bear = Bear1 - Bear
    Bear = Bear / Radian
    
    Ga = Sin(ga)
    If Ga >= 0 Then Bear = 360 - Bear
    
    Z = Str(dist)
    Y = Val(z)
    X = Fusing(y , "#.#")
    
    W = Str(bear)
    V = Val(w)
    U = Fusing(v , "#.#")
    
    Locate 1 , 1
    Lcd "DST: " ; X ; " Km"
    Locate 2 , 1
    Lcd "BRG: " ; U ; " Grad"
    
    End

  9. #9
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    08.11.2005
    Ort
    QTH: JO43BC
    Alter
    56
    Beiträge
    112
    Hallo gpsklaus,

    ist nicht wirklich interessant fuer mich, da offensichtlich das Ursprungslisting von mir stammt:

    http://www.speckmann.de/atmel/koordinatenberechnung.htm

    Aber macht nichts, ich hab da kein Problem mit. :)
    Uebrigens habe ich auf einem GLCD schonmal rudimentaer versucht den Winkel grafisch darzustellen:

    http://www.speckmann.de/atmel/gps_test.htm

    Der Winkel wird zunaechst noch von einer for-next Schleife erzeugt. Spaeterhin wird die erste Koordinate aus einer Mouse ausgelesen und die Eingabe der zweiten Koordinate erfolgt mittels Drehimpulsgeber. Alles andere wird laufend vom Atmel berechnet und ausgegeben.

    Mit freundlichen Gruessen
    Digitali

  10. #10
    Benutzer Stammmitglied
    Registriert seit
    29.09.2005
    Beiträge
    63
    Hallo Digitali

    > ist nicht wirklich interessant fuer mich, da offensichtlich das Ursprungslisting von mir stammt:

    http://www.speckmann.de/atmel/koordinatenberechnung.htm

    > Aber macht nichts, ich hab da kein Problem mit.

    Sorry, aber diese Seite war mir nicht bekannt. Ich hatte eine für VisualBasic geschriebene Winkelroutine und sie dann für Bascom-AVR modifiziert. Letztendlich müssen sich die Ergebnisse aber immer irgendwie ähneln.

    > Uebrigens habe ich auf einem GLCD schonmal rudimentaer versucht den Winkel grafisch darzustellen:

    http://www.speckmann.de/atmel/gps_test.htm

    > Der Winkel wird zunaechst noch von einer for-next Schleife erzeugt. Spaeterhin wird die erste Koordinate aus einer Mouse ausgelesen und die Eingabe der zweiten Koordinate erfolgt mittels Drehimpulsgeber. Alles andere wird laufend vom Atmel berechnet und ausgegeben.

    Das sieht interessant aus

    Klaus

Berechtigungen

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

LiFePO4 Speicher Test