kompilierfehler "no member declared in class"



  • Servus zusammen,

    ich versuche für einen Arduino ein Sketch zu kompilieren und erhalte die Meldung:

    ..\Anemometer.cpp:74:28: error: no 'double Anemometer::mps2mph()' member function declared in class 'Anemometer'
    double Anemometer::mps2mph(){
    ________________________________ ^

    74 double Anemometer::mps2mph(){
    75   _mps * 2.2369362920544;
    76   return mps2mph;
    77  }
    
    

    Auf der Seite wo ich den Sketch herhabe muss es wohl gelaufen sein, leider kann ich jedoch weder mit dem Fehler etwas anfangen noch bin ich in C++ bewandert. Kann mir da jemand helfen???
    Wenn weitere Infos gebraucht werden bitte schreiben...

    Gruß
    GoldenAmerican


  • Administrator

    Hast du die Memberfunktion mps2mph in Anemometer deklariert? Heisst in der Headerdatei von Anemometer?

    Also irgendwo in der Anemometer.hpp:

    class Anemometer
    {
      // ... snip ...
      double mps2mph(); // <- das scheint zu fehlen
      // ... snip ...
    }
    

    Abgesehen davon wirkt die Implementierung ziemlich sinnlos. Es wird eine Variable für nichts multipliziert, deren Ergebnis verworfen und dann irgendeine andere Variable zurückgegeben.



  • Hallo Dravere,

    danke ersteinmal für deine Mühe.
    In der Anemometer.h ist die class Anemometer definiert und dort der erwähnte Parameter unter public. Auch in der Anemometer.cpp ist der Parameter im Kopf aufgeführt. Deswegen komme ich ja nicht weiter. Alle mir bekannten Möglichkeiten habe ich schon probiert.

    Grüße GoldenAmerican



  • @goldenamerican Aber die von dir gezeigte Funktion hat gar keine Parameter.
    Willst du die Funktion überladen (gleiche Funktion mit unterschiedlichen Parametern)? Dann musst du dennoch jede Funktion mit allen Parametern so wie von Dravere gezeigt in der class deklarieren.



  • Hallo Unterfliege,

    wie soll ich das verstehen? Scheinbar, wenn ich Dich richtig verstanden habe, ist irgendwo eine Deklaration zuviel?

    Grüße GoldenAmerican



  • @goldenamerican Ich tippe eher auf zu wenig.
    Hast du eine Zeile wie von Dravere gezeigt genau so in deinem Code im Header-File stehen?
    Wenn ja können wir ohne mehr Code vermutlich kaum weiterhelfen.



  • Hallo Unterfliege,

    ich gebe Euch mal die Anemometer.h:

    #ifndef Anemometer_h
    #define Anemometer_h
    
    #include "Arduino.h"
    
    class Anemometer
    {
      public:
        Anemometer (int pin, int radius, int interval);
        double mph();
        float WindSpeed();
    	float _mps();
    	double _mps2mph;
        
      private:
        
        int countRotations();
        int circumference();
        
        int _pin;
        int _radius;
        int _interval;
        int _lastRotation;
        int _currentRotation;
        int _previousMillis;
        int _frequency;
        int _rotations;
        int _circ;
        int _rotationsPerInterval;
        float _radiusMeters;
    
        
    };
    
    #endif
    
    

    und die Anemometer.cpp bis zu dem Fehler...

        int countRotations();
        int circumference();
        double mps2mph();
    	float _mps;
    
        int _pin;
        int _radius;
        int _interval;
        int _lastRotation;
        int _currentRotation;
        int _previousMillis;
        int _frequency;
        int _rotations;
        int _circ;
        int _rotationsPerInterval;
        int _rotationsPerSecond;
        int _metersPerSecond;
    	int _mph;
    	float _radiusMeters;
    
    
    Anemometer::Anemometer(int pin, int radius, int interval) {
      
        _pin=pin;
        _radius=radius;
        _interval=interval;
        
        analogReference(DEFAULT);
    }
    
    //the following function uses the formulae from http://www.dfrobot.com/wiki/index.php/SHARP_GP2Y0A41SK0F_IR_ranger_sensor_%284-30cm%29_SKU:SEN0143
    //converts the signal from the analog pin to cm
    double Anemometer::mph() {
    	_rotationsPerInterval = countRotations();			//call countrotations
    	_rotationsPerSecond = (_rotationsPerInterval/_interval)*1000;	//convert roations back to milliseconds and multiply by 1000 to get rotations per second
    	_metersPerSecond = _rotationsPerSecond * circumference();		//times the distance in meters with roations per hour to get meters per hour
    	_mph = mps2mph();
    	return _mph;
    	
    }
    
    double Anemometer::mps2mph(){
       _mps * 2.2369362920544;
       return mps2mph;
    }
    
    

    Vielleicht kann einer von Euch sehen wo es klemmt.

    Grüße GoldenAmerican



  • Du deklarierst die Funktion außerhalb der Klasse in dem Source-File. Dadurch ist es kein Mitglied der Klasse und kann auch nicht aufgerufen werden, wenn du Anemometer.h inkludierst.

    Es gibt aber noch ein paar andere Unschönheiten:

    • Windspeed() ist eine Funktion, weshalb man diese üblicherweise mit einem Kleinbuchstaben beginnt. Machst du bei den anderen Funktionen ja nicht anders
    • Du hast eine Variable im public-space. Diese deklarierst du meistens besser private und nutzt dann getter/setter
    • ist es Absicht, dass die Funktionen countRotations() und circumference() private sind? Damit sind die von außen nicht aufrufbar.
    • Du deklarierst countRotations() und circumference() einmal innerhalb und einmal außerhalb der Klasse. Gleiches für die ganzen Member. Inkludiere mit "#include "Aenometer.h" die Klasse in dein Source-File. Dann verschiebst du noch die ganzen Variablen, die du im Source-File hast in den private-space der Klasse. Wenn die Variablen instanzenübergreifend verwendet werden sollen, mache sie static. (Nicht das ganze Header-File gesehen)

    Vermutlich habe ich noch einiges vergessen, daran habe ich jetzt aber auf den ersten Blick gedacht.
    Um es einfach nur zum Funktionieren zu bringen, musst du in der Klasse "double _mps2mph" durch "double mps2mph()" ersetzen und natürlich die Klasse im Source-File inkludieren. Wenn das der einzige Fehler ist, was ich zu bezweifeln wage.
    Woher hast du denn diesen Code?



  • Und wo ist in der Headerdatei die Funktion mps2mph deklariert? Du hast dort nur eine Membervariable '_mps2mph` deklariert.

    Und die Funktion sollte dann wohl eher so aussehen:

    double Anemometer::mps2mph()
    {
        return  _mps() * 2.2369362920544;
    }
    

    (wie @Dravere auch schon angemerkt hat)

    Aber der ganze Klassenaufbau kommt mir komisch vor - soviele private Membervariablen ohne Benutzung, und dann auch noch die globalen gleichnamigen Variablen in der Sourcedatei.
    Mein Tipp: Schmeiß die ganze Klasse weg und erstelle sie nach Anforderung neu!

    @goldenamerican schrieb:

    noch bin ich in C++ bewandert

    Dies ist jedoch dein Hauptproblem - lern ersteinmal vernünftig C++!



  • @goldenamerican sagte in kompilierfehler "no member declared in class":

    Auf der Seite wo ich den Sketch herhabe muss es wohl gelaufen sein, leider kann ich jedoch weder mit dem Fehler etwas anfangen noch bin ich in C++ bewandert. Kann mir da jemand helfen???

    Ich hab jetzt ein paar Minuten nach Anemometer-Sketchen in C++ gesucht und nichts gefunden. Dafür jede Menge in C. Das bringt uns direkt zu der Frage, warum du es nicht auch in C machst? C ist deutlich einfacher zu lernen. Mal im Ernst, ich stimme hier allen zu, dass du erstmal C++ lernen solltest, aber das wirst du sowieso nicht tun. Du wirst solange an diesem grauenhaften (sorry, ist aber so) Code rumpfriemeln, bis er scheinbar funktioniert.



  • Hallo zusammen,

    wie ich bereits oben geschrieben habe ist der Code nicht von mir, sondern wurde von graham22 auf hackaday.io veröffentlicht.

    @Th69 Die vielen Membervariablen werden schon gebraucht, ich schrieb ja auch, dass ich der Code bis zu dem Fehler poste. Insgesammt ist er 100 Zeilen lang und wenn ich mich recht der Forumregeln erinnere, soll man unnötig lange Codes nicht posten.
    Was Du auch recht SCHÖN bemerkt hast ist, dass ich kein C++ kann - dass ist richtig. Aber hast Du denn Konditor gelernt, nur weil Du MAL einen Kuchen backen willst? Das bischen was ich brauche versuche ich schon selbst zu machen, für die meisten Sachen gibt es ja Vorlagen und dann auch noch das Internet. Doch manchmal reicht das eigene Wissen halt nicht aus - soll ich deswegen eine Programmiersprache lernen? Ich betrachte es als Hobby mit meinen Arduinos zu spielen und da ich jetzt nicht weiterkomme frage ich halt bei Leuten, von denen ich mir Hilfe erhoffe - weil sie es KÖNNEN.
    Als ich nach der Schule mit Assembler angefangen habe ging es solange gut, bis ich zur CPU-Programmierung kam - da bin ich nicht mehr mitgekommen. Ich sitze zu Hause an meinem Rechner und mache alles schön alleine - nix da mit Schule und Pauken.
    Trotz allem danke für Deine Kritik.

    @Unterfliege die Inkludierungen sind schon da, aber durch die vielen Mem-Zeilen habe ich sie beim Posten weggelassen.

    #define _USE_MATH_DEFINES
    #include <math.h>
    #include "Arduino.h"
    #include "Anemometer.h"
     
    

    @Bashar Dankefür deinen Tip, ich vermute jedoch, dass die Arduino-IDE mit C nichts anfangen kann...
    Was Du mit dem C++lernen meinst, da werde ich Dir zustimmen müssen, ich denke dass das für mich zu hoch ist (bin auch nicht mehr der jüngste).

    Trotz allem vielen Dank und beste Grüße
    GoldenAmerican



  • Wenn du es einfach nur zum Funktionieren bringen willst:

    • schreib alle verwendeten Variablen (Groß-/Kleinschreibung und verwendete Underscores beachten) in den private-space deiner Klasse
    • gleiches für Funktionen (Klammern und korrekte Parameter beachten)
    • außer dem Include vor dem Konstruktor im Source-File keine Variablen/Funktionen deklarieren
      Führt vermutlich zu keinem schönen, aber hoffentlich funktionierendem Code.
      Wenn du nachhaltig etwas lernen willst, solltest du dich zumindest etwas mehr mit C++ oder zumindest mit grundlegenden Konzepten wie Objektorientierung auseinandersetzen.


  • @goldenamerican sagte in kompilierfehler "no member declared in class":

    wie ich bereits oben geschrieben habe ist der Code nicht von mir, sondern wurde von graham22 auf hackaday.io veröffentlicht.

    Ich kann den Code da nicht finden. Die ino-Datei enthält keine Klasse. Eine Anemometer-Klasse liegt versteckt in einer ZIP-Datei. 🙄 Aber die ist auch nicht wirklich ähnlich zu dem, was du gepostet hast.

    Gib mal bitte einen Link zu dem Code, an dem du dich orientierst.

    Ich sitze zu Hause an meinem Rechner und mache alles schön alleine - nix da mit Schule und Pauken.

    Vielleicht missverstehst du, was mit C++ lernen gemeint ist. Du sollst keine Ausbildung oder Studium machen, sondern dir ein gutes Lehrbuch besorgen und das systematisch -- zuhause und nach deinem Tempo -- durcharbeiten.



  • hallo zusammen,

    @Bashar Um die Programme in die Arduinos zu bekommen, muss man in der IDE die Sachen importieren, dann sind sie dort verfügbar. Die Librarys und Codes landen dann in dem libraries-Ordner. Der erwähnte Code ist schon von der genannten Adresse, beim ersten Compilier-Versuch hatte ich jedoch so viele Fehler, dass ich die ersten "Heilungs-Versuche" schon hinter mir habe. Letztlich das oben genannte Problem ist übrig geblieben.

    @Bashar @Unterfliege Noch habe ich nicht so viele Fragen, dass sich ein "Studium" eines solchen Buches rentieren würde - deshalb ja auch der Versuch, in einem Forum Hilfe zu bekommen. Wie ich schon zu TH69 gemeint habe macht es wenig bis gar keinen Sinn etwas zu erlernen wenn man MAL etwas vom Weg abweichen möchte. Mein Ziel ist es, für meine Domoticz-Seite Aussensensoren verfügbar zu machen. Damit habe ich dann nicht nur vom Haus sondern auch von aussen die aktuellen Werte. Sachen wie Roboter oder 3D-Drucker selber bauen traue ich mir nicht zu - weil mir da das Wissen und Können fehlt. Ausserdem sind solche Sachen für mich nicht von Nutzen.
    Ich werde versuchen die von Euch genannten Hinweise zu befolgen und hoffe damit dann zum Erfolg zu kommen.

    Bis dahin viele Grüße
    GoldenAmerican.



  • Ich bin mal so frei, die dortige Anemometer-Klasse zu posten, damit man weiß, worüber geschrieben wird.

    #pragma once
    #include <Arduino.h>
    
    
    class Anemometer
    {
    	//#define voltageConversionConstant .004882814 //This constant maps the value provided from the analog read function, which ranges from 0 to 1023, to actual voltage, which ranges from 0V to 5V
    
    	int _sensorPin; //Defines the pin that the anemometer output is connected to
    	float _voltageConversionConstant;  //This constant maps the value provided from the analog read function, which ranges from 0 to 1023, to actual voltage, which ranges from 0V to 5V
    
    //Anemometer Technical Variables
    //The following variables correspond to the anemometer sold by Adafruit, but could be modified to fit other anemometers.
    #define voltageMin .4 // Mininum output voltage from anemometer in V.
    #define windSpeedMin  0 // Wind speed in meters/sec corresponding to minimum voltage
    #define voltageMax 2.0 // Maximum output voltage from anemometer in V.
    #define windSpeedMax 32 // Wind speed in meters/sec corresponding to maximum voltage
    
    public:
    	Anemometer(int sensorPin, float voltageConversionConstant);
    	~Anemometer();
    	float WindSpeed();
    	float SensorVoltage();
    };
    
    #include "Anemometer.h"
    
    
    Anemometer::Anemometer(int sensorPin, float voltageConversionConstant)
    {
    	_sensorPin = sensorPin;
    	_voltageConversionConstant = voltageConversionConstant;
    }
    
    Anemometer::~Anemometer()
    {
    }
    
    float Anemometer::WindSpeed()
    {
    	int sensorValue = analogRead(_sensorPin); //Get a value between 0 and 1023 from the analog pin connected to the anemometer
    
    	float sensorVoltage = sensorValue * _voltageConversionConstant; //Convert sensor value to actual voltage
    
    																   //Convert voltage value to wind speed using range of max and min voltages and wind speed for the anemometer
    	if (sensorVoltage <= voltageMin) {
    		return 0; //Check if voltage is below minimum value. If so, set wind speed to zero.
    	}
    	else {
    		return (sensorVoltage - voltageMin)*windSpeedMax / (voltageMax - voltageMin); //For voltages above minimum value, use the linear relationship to calculate wind speed.
    	}
    }
    
    float Anemometer::SensorVoltage()
    {
    	int sensorValue = analogRead(_sensorPin); //Get a value between 0 and 1023 from the analog pin connected to the anemometer
    	return sensorValue * _voltageConversionConstant; //Convert sensor value to actual voltage
    }
    
    

    Wie schon Bashar gemeint hat, produzierst Du eigenständigen Code, der über die Vorlage hinaus geht.
    Um bei Deinem Kuchen-Beispiel zu bleiben, wenn ich einen Kuchen backen will, weiß ich nicht mehr, als das irgendwie Teig, Wasser, Milch gebraucht werden. Auch wenn ich das nur einmal machen will, muss ich mir etwas besorgen, wo steht wie das gemacht wird.
    Und Kuchen backen ist deutlich leichter als programmieren.



  • Hallo Lemon03,

    ja manchmal hilft halt nur der Wink mit dem Zaunpfahl - dank deines Posts habe ich die Diskrepanz entdeckt. Im Vorfeld hatte ich mit einem anderen Aufbau versucht, jedoch wurde da mit einem UNO gearbeitet, welcher nicht die für mich wichtige WIFI-Unterstützung mitbrachte. Im zweiten Versuch, jetzt mit einem ESP8266 hat die Arduino-IDE jedoch die alten Librarys weiter verwendet, wodurch ich natürlich nicht zum Ziel kommen konnte.

    Vielen Dank an alle die sich mit mir Mühe gegeben haben und auch die Hinweise auf ein C++-Studium werde ich beachten, da ich wohl noch weiter mit den Arduinos spielen werde...

    Bis dahin
    GoldenAmerican


Log in to reply