brauche Hilfe class/object

Hallo !
Ich würde gerne auf ein Object(“x”) was ich im Haupt programm erstelle auch in einen anderen cpp file bearbeiten .
Leider scheitere ich und Dr.Google ist mir auch keine Grosse Hilfe.

Haupt.h:

#ifndef _HAUPT_h
#define _HAUPT_h

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


#endif

haupt.cpp:

#include "haupt.h"
#include <Arduino.h>
#include "super_toll2.h"




int main(){
	Serial.begin(1000000);
	meineKlasse x;
	char meinName=x.getName();
    Serial.println(x.getName());
	x.neuerName('C');
	Serial.println(x.getName());
	nameAendern(x);
	while(1){
		//Serial.print("test");
	}
}

klassen header

#ifndef _SUPER_TOLL2_h
#define _SUPER_TOLL2_h

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


#endif



class meineKlasse
{
	private:
	char Name;
	public:
	meineKlasse(); 
	char getName();
	void neuerName(char val);
};

klassen .cpp

#include "super_toll2.h"
#include "teste.h"

meineKlasse::meineKlasse()
{
	
	Name='A';

}


char meineKlasse::getName(){
	
	return this->Name;
}

void meineKlasse::neuerName(char val){
	this->Name=val;
}

und noch ein beispiel file wo ich noch zusatzlich drauf zugreifen möchte

Header:

#ifndef _SUPERTOLL1_h
#define _SUPERTOLL1_h

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


#endif


void nameAendern(object & val

cpp:

#include "supertoll1.h"


void nameAendern(val){
	val.neuerName('X');
}

wäre super wenn ihr mir dabei helfen könntet

Statt

void nameAendern(object & val);

muss du

void nameAendern(meineKlasse & val);

deklarieren, die Funktion auch so definieren, und den zugehörigen header includieren.

Mindestens ...

Wenn du die Instanz globalisieren möchtest, ist das recht einfach zu lösen!

In einer *.cpp Datei deiner Wahl erzeugst du eine Definition der Instanz deiner Klasse.

DeineKlasse instanz;

In einer *.h Datei deiner Wahl, erzeugst du eine Deklaration der Instanz deiner Klasse.

extern DeineKlasse instanz;

Diese *.h fügst du überall ein, wo du mit der Instanz arbeiten möchtest.


Die Alternative ist: Referenzen oder Zeiger übergeben.

@TO: Unsere Fragen nebenan nach Code und Erklärung waren Dir wohl zu blöd, dass Du es nun wo anders versuchst?

Gruß Tommy

Entschuldige ich wollte auf ein Problem eine Lösung !
Und ja ich bin hier her um auch andere zu fragen ! ich finde nicht das das Problem sein sollte .

denn code zu erklären fällt mir einfach schwer und deshalb möchte ich es meiden .

aber ich poste ihn gerne

// 
// 
// 

#include "mains.h"
#include "Communication_Setup.h"
#include "Serial_Communication.h"
#include "Port_Setup.h"
#include "Rotation.h"
#include "Spindel.h"
#include "Rotation_self_drive.h"
#include <Arduino.h>

char motor_state='0';

void set_motor_state(char val){
 motor_state=val;
}
char get_motor_state(){
 return motor_state;
}
void motor_aktiv(){
 if(motor_state=='0'){
 PORTB |= (1<<0); ///motor sperre
 }
 else if(motor_state=='1'){
 PORTB &= ~(1<<0); ///motor sperre
 }
}



void setup(){
 communication_setup_Serial();
 Port_Setup_Digital();
 PORTB |= (1<<0); ///motor sperre
 //Serial.println(self_drive1);
 //runs(5);
 //Auto_Rotation_Pos();
}


void loop() {
 motor_aktiv();
 Serial_Communication_READ();
 unsigned long currentMicros=micros();
 Auto_Rotation_Pos();
 
 //test();
 Spindel_calc_pos();
 Spinndel_axis(currentMicros);
 Rotor_axis(currentMicros);
 
}
// 
// 
// 

#include "Rotation.h"
#include "mains.h"
#include "Spindel.h"
#include <Arduino.h>
//#include "Spindel.cpp"

float rotion_pos=0;
char rotion_direction='R';
const int Rotor_translation = 3;/// 20 zu 60
const int Rotor_microstepping  = 32; /// micro steps per step
const float Rotor_steps_360 = Rotor_microstepping * 200*Rotor_translation; /// 200 fullsteps basis
const float Rotor_step_width=(float)360/Rotor_steps_360;
const byte Rotor_StepPort = 2;  //2
const byte Rotor_DirPort  = 5;  //5
char Rotor_direction='r';/// r rechts l links
char Rotor_frei     = '0';//1
unsigned long previousMicros = 0; // Xtimer // unsingned long um überlauf abzufangen
char Rotor_Step_STATE='0';
float Rotor_Umin=0;
int Rotor_multi=0;
float Rotor_Umin_Soll=15;
float Rotor_Umin_Ist=0;
float Rotor_time_width=1000000;


float get_rotion_pos(){
 //Serial.println(rotion_pos);
 return rotion_pos;
}

void set_Rotor_direction(char val){
 Rotor_direction=val;
}

char get_Rotor_direction(){
 return Rotor_direction;
}


float get_Rotor_time_width(){
 return Rotor_time_width;
}

void set_Rotor_Umin_Soll(float val){
 Rotor_Umin_Soll=val;
}

int get_Rotor_translation(){
 return Rotor_translation;
}

void Rotor_Freigabe(char val){
 Rotor_frei=val;
}


void add_Rotor_error_spindel(){
 float old_spindel_pos=get_Spindel_pos_ist();
 //Serial.print("pos ist : ");
 //Serial.println(old_spindel_pos);
 if(Rotor_direction=='r'){
 float new_spindel_pos=old_spindel_pos-0.33333333;
 set_Spindel_pos_ist(new_spindel_pos);
 }
 if(Rotor_direction=='l'){
 float new_spindel_pos=old_spindel_pos+0.33333333;
 set_Spindel_pos_ist(new_spindel_pos);
 }
}

float set_Rotor_Umin(){
 //Serial.println("rin");
 
 if((Rotor_Umin_Ist < Rotor_Umin_Soll+0.001)&&(Rotor_Umin_Ist > Rotor_Umin_Soll-0.001)&&(Rotor_Umin>0.001)){
 // Serial.println("wert erreicht");
 }
 else{
 Rotor_Umin=Rotor_Umin_Soll;
 Rotor_Umin_Ist=Rotor_Umin;
 unsigned long steptime=(60000000/Rotor_steps_360)/Rotor_Umin*2;
 //Serial.println(steptime);
 return steptime;
 
 }
}


void Rotor_axis(unsigned long currentMicros) {
 char engine=get_motor_state();
 Rotor_time_width=set_Rotor_Umin();
 if(Rotor_direction=='r'){/// richtungs prüfung
 PORTD &= ~(1<<5);
 }
 else if(Rotor_direction=='l'){/// richtungs prüfung
 PORTD |= (1<<5);
 }
 // Serial.println(currentMicros);
 //Serial.println(previousMicros);
 // Serial.println(Speed);
 if((currentMicros - previousMicros >= Rotor_time_width)&&(Rotor_Step_STATE=='0')&&(Rotor_frei=='1')&&(Rotor_Umin>0.001)&&(engine=='1')){
 PORTD |= (1<<2);
 previousMicros = currentMicros;
 Rotor_Step_STATE='1';
 //Serial.println(rotion_pos);
 if(Rotor_direction=='r'){
 Rotor_multi=Rotor_multi+1;
 }
 else{
 Rotor_multi=Rotor_multi-1;
 }
 rotion_pos = Rotor_step_width*Rotor_multi;
 
 if (rotion_pos <360){
 if(rotion_pos <0.0100){
 rotion_pos=0;
 Rotor_multi=19200;
 
 
 
 }
 }
 
 else{
 rotion_pos = 0;
 Rotor_multi=0;
 //rotion_pos = Rotor_step_width*Rotor_multi;
 //Serial.println(rotion_pos);
 }
 
 //Serial.println("on");
 //fail_add_rotor();
 add_Rotor_error_spindel();
 //Serial.println("rotor ein");
 }
 else if ((currentMicros - previousMicros >= Rotor_time_width)&&(Rotor_Step_STATE=='1')&&(Rotor_frei=='1')&&(Rotor_Umin>0.001)&&(engine=='1')){
 previousMicros = currentMicros;
 PORTD &= ~(1<<2);
 Rotor_Step_STATE='0';
 //Serial.println("off");
 //fail_add_rotor();
 add_Rotor_error_spindel();
 //Serial.println("rotor aus");
 }
 
}

das ganze ist noch nicht mal Ansatz weise Fertig.

Und ich hab mir einfach gedacht hey classes das kennst ja aus Python

Noch mal ich wollte dich nicht beleidigen etc ,weil ich selbst noch nicht weiß wie ich das ganze machen soll .

könntet ihr mir die Referenzen oder Zeiger übergaben erkären??

Stichworte sind einfach "call by value" und "call by reference"

Wenn du das machst:

void func(ClassName obj)

Wird eine Kopie des Objekts übergeben. Das ist schlecht und wird schlechter je größer das Objekt ist.

Deshalb nimmt man Referenzen wo nur die Adresse übergeben wird. Referenzen sind ähnlich zu Zeigern, aber können nicht Null sein und müssen bei der Deklaration initialisiert werden. Außerdem ist die Syntax gleich zu "normalen" Objekten.

Hallo,

entschuldigt vorab wenn ich vielleicht nicht die korrekten Begriffe verwende.
Man kann das Objekt als Referenz oder Zeiger übergeben. Beide Varianten sehen wie folgt aus.
Das erstellte Objekt “Led_77” übergebe ich an die blinker Funktion.
Einmal die Adresse auf das Objekt und einmal als Zeiger auf das Objekt.
Wobei der Zeiger letztlich auch nur eine Adresse ist. Für den Zugriff auf das Objekt muss man dann aber this verwenden statt den Punkt Operator. In der blinker Funktion rufe ich dann nur eine verfügbare Methode set() für das Objekt auf. Hier siehst du auch das man als Datentyp den Klassenname verwenden muss bzw. ist der Klassenname der Datentyp. Am Anfang war das für mich auch sehr verwirrend und ich muss auch heute noch alle Gedanken zusammennehmen.

#include <Wire.h>
#include <docMCP23017.h>

const byte MCP_I2C_ADR = 0x20;

Output Led_77 (MCP_I2C_ADR, 9);

void setup(void) {
  Wire.begin();
 
  Led_77.init();
}

void loop(void) {

  blinker(Led_77, 500);

  // oder //
  
  //blinker_this(&Led_77, 500);
}

// ****** Funktionen ******

void blinker (Output &led, const unsigned int interval)
{
  static unsigned long last_ms = 0;
  static bool state = LOW;

  unsigned long ms = millis();

  if (ms - last_ms >= interval) {
    last_ms = ms;
    state = !state;
    led.set(state);
  }
}


void blinker_this (Output *led, const unsigned int interval)
{
  static unsigned long last_ms = 0;
  static bool state = LOW;

  unsigned long ms = millis();

  if (ms - last_ms >= interval) {
    last_ms = ms;
    state = !state;
    led->set(state);
  }
}

könnte ihr mir auch noch schnell zeigen wie ich das im header und cpp einbindet

ich steh echt am schlauch !!

ich bekomme nämlich folgende fehler:

df.ino:1: In file included from

test.h: 15:14: error: variable or field 'machwas' declared void
void machwas(sampel &val)

test.h: 15:14: error: 'sampel' was not declared in this scope

test.h: 15:22: error: 'val' was not declared in this scope
void machwas(sampel &val)

Error compiling project sources
haupt.cpp: In function int main()

haupt.cpp: 11:10: error: too few arguments to function 'void machwas(sampel&)
machwas()

Build failed for project 'df'
haupt.cpp:7: In file included from
test.h:15: note declared here
void machwas(sampel &val)

Ich sag danke.

Hab es jetzt geschaft!

// test.h

#ifndef _TEST_h
#define _TEST_h

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


#endif

class sampel;
int machwas(sampel &val);
#include "test.h"

#include "klase.h"

int machwas(sampel &val){
	int z=val.getsampel();
	
	val.sampling(15);
};

Rein interesses halber wie würde es mit Pointern funktionieren

Glückwunsch!

Hier noch - gerade fertig - ein einfaches Beispiel an deinen ersten Versuch angelehnt:
Mit einer test.h Datei als Deklaration:

#ifndef test_h
#define test_h
class test {
private:
  char n; // kann dynamisch geändert werden
public:
  test(char name);
  char getName ();
  void setName(char name);
};
#endif

Der Implementierung in test.cpp

#include "test.h"
test::test(char name) {
  setName(name);
}

void test::setName(char name){
  n = name;
}

char test::getName() {
  return n;
}

Und einem Beispiel zur Verwendung und call-by-reference in einer ino - Datei, um sich das
#include <arduino.h> zu sparen

#include "test.h"

test t('A');

void setup() {
  Serial.begin(9600);
  Serial.print ( "t heisst " ); Serial.println(t.getName()); 
}

void hilfsfunktion ( test& obj) {  // Parameter ist das Test-Objekt (by reference)
  char n = obj.getName();
  if ( n < 'Z' ) n++;
  else n = 'A';
  obj.setName(n);
}

void loop() { 
    hilfsfunktion(t); // t wird von hilfsfunktion geändert
    Serial.print ( "neuer Name " ); Serial.println(t.getName()); 
    delay(500);
  }

Mit Pointer statt Referenz:

#include "test.h"

test t('A');

void setup() {
  Serial.begin(9600);
  Serial.print ( "t heisst " ); Serial.println(t.getName()); 
}

void hilfsfunktion ( test* obj) {
  char n = obj->getName();
  if ( n < 'Z' ) n++;
  else n = 'A';
  obj->setName(n);
}

void loop() { 
    hilfsfunktion(&t); // t wird geändert
    Serial.print ( "neuer Name " ); Serial.println(t.getName()); 
    delay(500);
  }

Einen Herzlichen dank :grin:

noch eine kurze frage wenn ich in diesen programm
z.b Serial.println(“hallo”); Ausgeben will

Gibt es mir nur “hal” aus und stürzt dann ab

ist der string nur mit 2 zeichen läuft das programm weiter !

was könnte es da haben

In welchem Sketch gibst Du hallo aus?

Gruß Tommy

bin ned ganz sicher was du meinst.

passiert aber auch wenn ich denn code aus auskommentiert
bis auf
#include <Arduino.h>
Serial.begin(1000000);
Serial.println(“ha”);

#include "haupt.h"
#include "klase.h"
#include "test.h"
#include <Arduino.h>
int main(){
	
	Serial.begin(1000000);
	Serial.println("ha");          //diese Zeile macht das Problem
	sampel x;
	int z=x.getsampel();
	Serial.println(z);
	machwas(x);
	z=x.getsampel();
	Serial.println(z);
	while(1){
		
	}
}

Hallo,

Frage an die Experten.

Ich hatte in #7 zwei verschiedene Möglichkeiten der Objektübergabe gezeigt. Für mich sind die erstmal funktionell gleichwertig.
Meine Frage lautet ist es wirklich egal welchen Syntax man nimmt oder gibts Unterschiede im Detail die ich heute noch nicht kenne und sich später erst bemerkbar machen?

Die übliche Variante ist eine const Referenz. Zeiger braucht man für sowas nicht und sie sind fehleranfälliger (da sie NULL sein können)

Serial.begin(1000000);

ist wohl das Problem, wenn es ein 16 MHz Controller ist. Probier mal 250000, und wenn es eine echte Frage ist, mach einen neuen Thread mit passendem Titel auf.

Hallo,

mit der Erklärung ist alles klar, leider meckert er mir dann meine Methode an, die ich vom Objekt anwende.
Das Argument verwirft den Qualifizierer oder so ähnlich? Ideen?

...\Objektuegabe_an_Funktion_002.ino: In function 'void blinker(const Output&, unsigned int)':

...\Objektuegabe_an_Funktion_002.ino:44:18: warning: passing 'const Output' as 'this' argument discards qualifiers [-fpermissive]

     led.set(state);

                  ^

In file included from ...\Objektuegabe_an_Funktion_002.ino:13:0:

...\libraries\docMCP23017/docMCP23017.h:31:8: note:   in call to 'void Output::set(bool)'

   void set (bool);

die Methode sieht so aus, ob der Parameter bool oder uint8_t ist macht keinen Unterschied

void Output::set(bool state)
{   
  if (state)  setHigh();
  else  setLow();
}

und der Testsketch so

/*
  IDE 1.8.8
  avr-gcc 7.3.0 mit -std=gnu++17
  Arduino Mega2560
*/

#include <Wire.h>
#include <docMCP23017.h>

const byte MCP_I2C_ADR = 0x20;

Output Led_77 (MCP_I2C_ADR, 9);

void setup(void) {
  Wire.begin();
  Led_77.init();
}

void loop(void) {

  blinker(Led_77, 500);
}

// ****** Funktionen ******
void blinker (const Output &led, const unsigned int interval)
{
  static unsigned long last_ms = 0;
  static bool state = LOW;

  unsigned long ms = millis();

  if (ms - last_ms >= interval) {
    last_ms = ms;
    state = !state;
    led.set(state);
  }
}

mit Funktions-Template erhalte ich die gleiche Warnung. Ohne const keine Warnung.

template <class L>
void blinke (const L &led, unsigned long interval)
{
  static unsigned long last_ms = 0;
  static bool state = LOW;

  unsigned long ms = millis();

  if (ms - last_ms >= interval) {
    last_ms = ms;
    state = !state;
    led.set(state);
  }
}