-         

+ Antworten
Seite 1 von 3 123 LetzteLetzte
Ergebnis 1 bis 10 von 30

Thema: Unklare Fehlermeldung

  1. #1
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    18.03.2013
    Beiträge
    193

    Unklare Fehlermeldung

    Anzeige

    Hallo,

    bei diesem Programm erhalte ich ganz unten bei "Umdrehungen3 = 0.0;" die Fehlermeldung, dass "Umdrehungen3" nicht deklariert ist, obwohl das kurz oberhalb passiert.
    Wenn ich "Umdrehungen3" aber nicht in der Anweisung, sondern am Anfang des Programms als "static float" deklariere, dann klappt's.

    Wieso ist das so?

    Code:
    //  **************************************UP lzahn3_ber  *******************************
    
    float lzahn3_ber ( float x1, float y1) {
    
      float P0_P1 = sqrt(pow(x1, 2) + pow(y1, 2));                                  //Gerade P0-P1
    
      float CosinusW4 = (117140.0 - pow(P0_P1, 2)) / 107536.0;
      float W4 =  180.0 / 3.1415926536 * acos(CosinusW4);                           //  W4 in Grad
    
      float P1_P5  = sqrt((1.03310787 - cos(3.1415926536 / 180.0 * (W4 + 12.58))) * 91368.0);            // Linie P1-P5
    
      float W10 =  180.0 / 3.1415926536  *  acos((5184.0 + pow(x1, 2) + pow(y1, 2) - pow(P1_P5, 2))  /  (144 * sqrt (pow(x1, 2) + pow(y1, 2))));   // = W4 in Grad
    
      lzahn3 = sqrt((1.00419 - cos((154.23 - W10 - (180.0 / 3.1415926536 * atan(y1 / x1))) * 3.1415926536 / 180.0)) * 11361.6);
    
      if (lzahn3 >= 68.0   && lzahn3  <=  105.0)  {
    
        float delta_lzahn3 = lzahn3 - lzahn3_alt;       // berechnet die Differenz zum alten Wert
    
    
        float Umdrehungen3 = 0.05 * delta_lzahn3;    // 0.05 = 1 / 20.0; das sind die Umdrehungen für 1 mm Weg
    
    
        return Umdrehungen3;     // die Ausgabe erfolgt in Umdrehungen um die errechnete Längenänderung zu erreichen
    
      }      // >>>>   ENDE    if (lzahn3 >= 68.0   && lzahn3  <=  105.0)
    
    
    
      Serial.println ("FEHLER: lzahn3 ausser Bereich!!!");
      
      digitalWrite (52, HIGH);
      Umdrehungen3 = 0.0;      // keine Bewegung, da Fehler vorliegt
      return Umdrehungen3;     
    
    
    }   //*************     ENDE  UP lzahn3_ber
    vG

    fredyxx

  2. #2
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    11.12.2007
    Ort
    weit weg von nahe Bonn
    Alter
    32
    Beiträge
    1.959
    die variable wird innerhalb des if-block deklariert und ist außerhalb nicht bekannt!

    generell gaaaaaanz schlechter stil variablen on the fly zu deklarieren.

    deklariere bitte ALLE in eienr methode verwendeten dateien immer gaaanz oben!
    Es gibt 10 Sorten von Menschen: Die einen können binär zählen, die anderen
    nicht.

  3. #3
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    04.09.2011
    Ort
    Hessen
    Beiträge
    507
    Hallo,

    lokale Variablen sind auf dem {} Block beschränkt, in dem sie deklariert wurden (und alles was darin verschachtelt liegt).

    D.h. in obigem Code ist Umdrehungen3 nur bis zu schliessenden Klammer des if sichtbar.

    Zwei Anmerkungen zu dem ganzen Code:

    Auf 8-Bit Arduinos ist Rechnen mit float sehr langsam.

    Auf 32-Bit Arduinos (Zero, Teensy, Due, usw.) ist der Code ungünstig, da alle Kommazahlenkonstanten (wie 0.05), wenn sie so geschrieben werden, den Typ double (15 Stellen Genauigkeit) haben. Man müsste richtiger 0.05f schreiben, wenn man float meint (7 Stellen Genauigkeit), sonst würde da sehr häufig umgerechnet, was auch wieder langsam wäre. Auf 8-Bit Arduinos spielt das keine Rolle, weil es dort kein double gibt, es wird immer float genommen.

    - - - Aktualisiert - - -

    Zitat Zitat von Ceos Beitrag anzeigen
    deklariere bitte ALLE in eienr methode verwendeten dateien immer gaaanz oben!
    @Ceos
    In C macht (bzw. muss man das), in Sprachen wie C++ (und das ist Arduino), C#, Java usw. ist es eher empfohlen Variablen erst wenn man sie braucht zu deklarien. In C++ wird sogar der AAA-Stil (Almost Always Auto) propagiert (z.B. von Herb Sutter, Chef des ISO C++ Kommitees), d.h. man schreibt den Typ nur hin, wenn es unbedingt sein muss.

  4. #4
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    18.03.2013
    Beiträge
    193
    Herzlichen Dank

    Gruß

    fredyx

  5. #5
    Unregistriert
    Gast
    Anm.:
    auch die Funktion pow() ist sehr rechenzeitintensiv. Wenn du nur quadrieren willst, schreibe lieber ausführlich x*x statt pow(x,2). Du kannst auch selber ein Makro dafür definieren:

    #define sq(x) (x*x) // sq für Square

    - - - Aktualisiert - - -

    Anm.:
    auch die Funktion pow() ist sehr rechenzeitintensiv. Wenn du nur quadrieren willst, schreibe lieber ausführlich x*x statt pow(x,2). Du kannst auch selber ein Makro dafür definieren:

    #define sq(x) (x*x) // sq für Square

    - - - Aktualisiert - - -

    Zitat Zitat von Unregistriert Beitrag anzeigen
    Anm.:
    auch die Funktion pow() ist sehr rechenzeitintensiv. Wenn du nur quadrieren willst, schreibe lieber ausführlich x*x statt pow(x,2). Du kannst auch selber ein Makro dafür definieren:

    #define sq(x) (x*x) // sq für Square
    Auch dafür danke!

    vg

    fredyxx

  6. #6
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    27.08.2013
    Ort
    Region Basel
    Alter
    58
    Beiträge
    2.056
    Hallo fredyx,

    Du kannst das Problem auch umgehen im den du am Ende der Funktion
    return 0.0;
    schreibst.
    bzw. explizit:
    return (float) 0.0;

    Vom Stil her, wäre es sogar übersichtlicher da dieser Ausgang nur im Fehlerfall benutzt wird.

    MfG Peter(TOO)
    Manchmal frage ich mich, wieso meine Generation Geräte ohne Simulation entwickeln konnte?

  7. #7
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    11.12.2007
    Ort
    weit weg von nahe Bonn
    Alter
    32
    Beiträge
    1.959
    @Mxt das ist doch C-Code oder hab ich da was übersehen? Wenn er nach C++/#/Java fragt hätte ich was anderes gesagt ... aber bei Java geh ich !nicht! konform mit dir. Ich schreib dir dazu eine kurze PM weil ich dazu gern eine Meinung von dir hätte

    PS: mir ist aufgefallen dass das "gaaaaanz oben" missverständlich klingt, ihc meinte damit innerhalb der methode ganz oben nicht innerhalb der Datei (Datei-Global)

    ARGSNbla .. du hast private Messages leider aus
    Sorry fürs kurze OT dann:
    Mittlerweilen bin ich (Minecraft sei dank) auf den Trichter gekommen, zumindest in Java Objekte wo es nur geht zu recyclen(also so zu strukturieren dass ich immer eine Referenz drauf halte und statt eines "new" ein "populate" aufrufe), der Garbage Collector und den Anwender der nicht alle Nase lang einen langen Freeze hat wird es dir danken
    Aber der persistente RAM Footprint wird natürlich deutlich größer! Oder man spendiert der JVM ein -XX:NewGenSize=xxxx in einer Größe die man bei der Art der Daten erwartet.
    Es gibt 10 Sorten von Menschen: Die einen können binär zählen, die anderen
    nicht.

  8. #8
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    04.09.2011
    Ort
    Hessen
    Beiträge
    507
    Zitat Zitat von Ceos Beitrag anzeigen
    @Mxt das ist doch C-Code oder hab ich da was übersehen?
    Naja, das ist hier die Arduino Rubrik. Und das ist C++, sonst gäbe es ja keine Objekte wie Serial, Wire usw. Rein technisch betrachtet hat die Arduino IDE (seit 1.6.8 ?) den Schalter -std=gnu++11 gesetzt ...

    Und OT:
    Ja, Java und C# sind da, wegen Garbage Collector, streng genommen wieder eine andere Baustelle als C++. Trotzdem ist es in allen diesen eher üblich nur kurz benötigte Variablen erst am Ort des Geschehens zu deklarieren.

  9. #9
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    18.03.2013
    Beiträge
    193
    Zitat Zitat von Peter(TOO) Beitrag anzeigen
    Hallo fredyx,

    Du kannst das Problem auch umgehen im den du am Ende der Funktion
    return 0.0;
    schreibst.
    bzw. explizit:
    return (float) 0.0;

    Vom Stil her, wäre es sogar übersichtlicher da dieser Ausgang nur im Fehlerfall benutzt wird.

    MfG Peter(TOO)
    Ja, prima Idee. Aber was bewirkt das float in Klammern gegenüber nur return 0.0??

    vG

    fredyxx

  10. #10
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    27.08.2013
    Ort
    Region Basel
    Alter
    58
    Beiträge
    2.056
    Hallo fredyxx,
    Zitat Zitat von fredyxx Beitrag anzeigen
    Ja, prima Idee. Aber was bewirkt das float in Klammern gegenüber nur return 0.0??
    Hier eigentlich nichts

    Es war davor aber die Diskussion, dass je nach verwendeter Hardware, der Compiler float oder double verwendet.
    Mit einem typecast kann man dem Compiler dazu bringen einen bestimmten Datentyp zu verwenden, bzw. kann verhindern, dass interne Konvertierungen vorgenommen werden.

    Ein schlechter Compiler mit double, würde die 0.0 zuerst als double erzeugen und dann in einen float umwandeln. Mit "(float) 0.0" wird er gezwungen 0.0 gleich als float zu erzeugen.

    Es gibt manchmal Fälle, wo man aus Sicht des Compilers etwas "murksen" muss und dann meckert der Compiler rum.
    z.B. sind Ports typischerweise 8-Bit breit:
    Code:
    uint8_t port;
    int i;
    
    i &= 0xFF; // i hat jetzt garantiert nur noch 8 gültige Bits
    
    port = i;  // hier motz der Compiler, weil int mehr als 8 Bits hat und Daten verloren gehen könnten
               // wir haben aber im Programm sicher gestellt, dass nur noch 8 Bit vorhanden sind
    
    port = (uint8_t)i; // hier motzt der Compiler nicht mehr.
    Ein anderes Beispiel:
    Code:
    int i;
    i = i * 3.3;  // das geht nicht
                  // der Compiler wandelt i zuerst in einen double um und multipliziert dann mit 3.3
                  // das Resultat ist dann aber auch double und passt nicht in einen int
    
    i = (int) (i * 3.3); // dies funktioniert und es ist auch dokumentiert, dass bewusst die Nachkommastellen abgeschnitten werden.

    Das mit den Typenkonvertierung ist aber immer eine heisse Kiste und man muss sich genau überlegen was man da tut. Nur weil der Compiler nicht motzt, funktioniert der Code noch lange nicht.
    Auch muss man bedenken, welchen Wertbereich ein Datentyp abbilden kann und welche Konvertierungen der Compiler automatisch macht
    Code:
    volatile uint8_t c;
    
    c = c * 255;
    c = c / 256;  // liefert immer 0!
    
    c = (c * 255) / 256; // hier bekommst du das erwartete Resultat
    Im ersten Fall wird das Zwischenresultat auf 8 Bit gekürzt, erzeugt für alle Werte von c >1 einen Überlauf
    Aber das ist egal, weil ein 8-Bit Wert geteilt durch 256 immer 0 ergibt.

    Im zweiten Fall ist das Zwischenresultat ein Long und es wird kein Überlauf erzeugt.

    "volatile" sagt dem Compiler, dass c sich ausserhalb des Kontext verändern kann. Das habe ich hier verwendet damit der Compiler nicht optimieren kann und das erste Beispiel dann trotzdem funktioniert!

    Wegen solche "Details sind schon Raketen explodiert.
    Hier die Kurzversion: https://de.wikipedia.org/wiki/Ariane_V88#Fehlerursachen
    Und noch der ausführliche Bericht: http://www4.in.tum.de/lehre/seminare...g-27-11-02.pdf


    MfG Peter(TOO)
    Manchmal frage ich mich, wieso meine Generation Geräte ohne Simulation entwickeln konnte?

+ Antworten
Seite 1 von 3 123 LetzteLetzte

Ähnliche Themen

  1. Arduino fehlermeldung
    Von Luca Spindler im Forum Arduino -Plattform
    Antworten: 4
    Letzter Beitrag: 14.05.2012, 16:02
  2. Fehlermeldung bei Bascom
    Von pacman im Forum Allgemeines zum Thema Roboter / Modellbau
    Antworten: 2
    Letzter Beitrag: 26.03.2011, 17:32
  3. Fehlermeldung bei Dev-C++
    Von Zylbath im Forum C - Programmierung (GCC u.a.)
    Antworten: 2
    Letzter Beitrag: 12.10.2009, 16:21
  4. Fehlermeldung
    Von Proworx im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 9
    Letzter Beitrag: 12.04.2006, 09:49
  5. Fehlermeldung!?!?!?
    Von ricoderrichter im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 3
    Letzter Beitrag: 11.08.2005, 18:57

Berechtigungen

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