Library Verständnisprobleme

Hallo!
Ich programmiere erst seit ein paar Tagen mit dem Arduino (Uno). Ich habe einge Erfahrungen im Programmieren mit VB.net und befürchtre, das ich dadurch auch einiges durcheinander bekomme.
Ich möchte mir eine erweiterte Servo Lib erstellen. Damit ich mehrere Servos damit bedienen kann. Also brauche ich jeweils instanzen auf die Lib. Hier mein Code:
MyServo.cpp

#include "MyServo.h"
#include "../libraries/Servo/src/Servo.h"
#include <string.h>

void MyServo::NewMyServo(int _port, int _ref, int _PosMin, int _PosMax, boolean _GoToRef)
{
	port = _port;
	ref = _ref	;
	PosMin = _PosMin;
	PosMax = _PosMax;
	
	if (_GoToRef){
		GoToRef();
	}
}

void MyServo::GoToRef()
{
	Serial.println("GoToRef Port:");
	Serial.println(port);
	servo.attach(port);
	servo.write(ref);
}

MyServo.h

// MyServo.h

#ifndef _MYSERVO_h
#define _MYSERVO_h

#if defined(ARDUINO) && ARDUINO >= 100
	#include "Arduino.h"
#else
	#include "WProgram.h"
#endif

#include "../libraries/Servo/src/Servo.h"

class MyServo
{
	
 public:
	MyServo();
 
	Servo servo;
	int port;
	int ref;
	int PosMin;
	int PosMax; 
 
	void NewMyServo(int _port, int _ref, int _PosMin, int _PosMax, boolean _GoToRef);
	void GoToRef();
 
};

#endif

ServoTest.ino

#include <MyServo.h>
#include <Servo.h>

MyServo Servo1();

void setup()
{
	Serial.begin(9600);           // set up Serial library at 9600 bps
	delay(300);
	Serial.println("Starte ServoTest");
	
	Servo1.GoToRef();
}

void loop()
{

}

Der Fehler beim Compilieren tritt nun bei der Zeile "Servo1.GoToRef();" in void setup() auf.
"ServoTest.ino:20: error: request for member 'GoToRef' in 'Servo1', which is of non-class type 'MyServo ()()'"

Ich verstehe es nicht, warum das nicht geht. Ich habe in einem Beispiel (Morse) das ganze eigentlich sehr ähnlich.
Mache ich das vielleicht grundsätzlich falsch?

Gruß
Bismosa

Konstruktoren habe wie in anderen Sprachen auch den gleichen Namen wie die Klasse. Wieso heißt der bei dir dann NewMyServo? Du hast da zwar noch einen Konstruktor im Header, machst aber was eigentlich da rein gehört in einer extra Methode.

Und dann musst du die Klasse auch mit dem Konstruktor instantiieren und nicht mit dem Default Konstruktor. Das ist dann aber ein Laufzeit Problem.

Siehe z.B.:
http://www.cpp-tutor.de/cpp/le10/ctor_dtor.html#cdefinition

Die Variablen sollten private sein.

Tip:
In C/C++ fangen Methoden-Namen laut Konvention mit Kleinbuchstaben an. Das ist nicht unbedingt nötig, aber hat sich so eingebürgert. Nur der Konstruktor wird groß geschrieben.

Hallo!

Vielen Dank für die Antwort. Da habe ich wohl noch ein wenig Nachholbedarf. Gerade was die Begriffe und Grundregeln angeht.

NewMyServo habe ich angelegt, da ich Probleme hatte GoToRef beim Start auszuführen. Das wurde einfach nicht gemacht. Daher habe ich den Konstruktor leer und beim setup() setze ich dann alle Werte und kann dabei auch den Referenzpunkt anfahren. Das wird nicht das einzige bleiben, was dort reinkommt. Ich fange aber sehr langsam an.

Auf die Variablen brauche ich später Zugriff. Vermutlich nicht alle...aber das kommt später.

Liegt das jetzt also am Default Konstruktor?

Gruß
Bismosa

Wahrscheinlich. Bei statischer Allokation (ohne new), ruft man den Default Konstruktor ohne Klammern auf:

MyClass myInstance;

Der Grund ist wahrscheinlich weil das hier auch geht:

MyClass myInstance();

Das ist aber die Deklaration einer Funktion ohne Parameter die ein Objekt der Klasse MyClass zurückgibt.

Deshalb meckert er da was von "which is of non-class type 'MyServo ()()" Du hast da einen Funktions-Prototypen deklariert :slight_smile:

Das muss aber auch mit einem normalen Konstruktor gehen. Versuche lieber das korrekt zu machen als da irgendwelche Krücken zu programmieren, die das Problem nur umgehen.

Hallo!

Danke! Ich glaube ich habe jetzt schon einen gangbaren Weg. Ich habe es jetzt so gelöst:
MyServo.cpp

#include "MyServo.h"
#include "../libraries/Servo/src/Servo.h"
#include <string.h>

MyServo::MyServo(int _port, int _ref, int _PosMin, int _PosMax)
{
	port = _port;
	ref = _ref	;
	PosMin = _PosMin;
	PosMax = _PosMax;
}

void MyServo::goToRef()
{
	Serial.println("goToRef Port:");
	Serial.println(port);
	servo.attach(port);
	servo.write(ref);
}

void MyServo::myServoInit(boolean _GoToRef)
{
	if (_GoToRef){
		goToRef();
	}
}

MyServo.h

// MyServo.h

#ifndef _MYSERVO_h
#define _MYSERVO_h

#if defined(ARDUINO) && ARDUINO >= 100
	#include "Arduino.h"
#else
	#include "WProgram.h"
#endif

#include "../libraries/Servo/src/Servo.h"

class MyServo
{
	
 public:
	MyServo(int _port, int _ref, int _PosMin, int _PosMax);

	Servo servo;
	int port;
	int ref;
	int PosMin;
	int PosMax; 
 
	void myServoInit(boolean _goToRef);
	void goToRef();
 private:
};
#endif

ServoTest.ino

#include <MyServo.h>
#include <Servo.h>

MyServo Servo1(9,90, 0, 180);

void setup()
{
	Serial.begin(9600);           // set up Serial library at 9600 bps
	delay(300);
	Serial.println("Starte ServoTest");
	
	Servo1.myServoInit(true);
}

void loop()
{
}

Ich denke es lag tatsächlich am default Konstruktor.

Das myServoInit musste ich aber trotzdem im setup() machen, da sonst der Servo schon beim Aufruf von servo.attach(port) einfach auf Anschlag gefahren ist. Das Programm schien dann auch stehen geblieben zu sein. Eine Serielle Ausgabe habe ich nicht mehr bekommen.

Vielen Dank für die vielen Tipps und Hilfen!

Gruß
Bismosa