Richtig Deklarationen und Code spliten

Hallo miteinander,

ich möchte meinen Code etwas aufräumen :slight_smile: und dazu habe ich mir überlegt den Code in verschiedene Dateien zu packen.

dabei habe ich schon gelernt das in eine .ino Datei meine Haupt Programm steht.
In .h Dateien sind immer nur Deklarationen und im .cpp Dateien sind dann die Funktionen die ich in der .h richtig Deklariert habe.

Da ich davon noch keinen Plan habe habe ich mir ein Kleines Test Programm erstellt.

Man kann dem Arduino einfach einen JOB nennen und er schreibt dann etwas auf dem Seriellen Monitor.

Das habe ich alles in eine .ino Datei gepackt.
Da Funktioniert mein Code auch ohne Probleme.

Dann habe ich mir überlegt welche Dateien möchte ich für mein Aufräumen haben.
und habe diese erst ein mal angelegt und per include eingebunden.

Dann bin ich hin und wollte eins (Funktionen) nach dem anderen verschieben und da kamen dann die Probleme, die IDE Deklariert die Funktionen nicht mehr selbst :frowning:

Also bin ich hin und habe die erste ziele der Funktion in die .h Datei geschrieben das hat aber nichts gebracht :frowning:

Irgend wie verstehe ich das nicht wie ich das machen muss, gibt es etwas das ich nachlesen kann sagen wir mal Deklarationen von Funktionen für Sau doofe?

Gruß Mücke

das ist mein Code alles in einer Datei:

/* Deklarieren.ino
 *
 * Übungsprogramm um Code auslagern und richtig zu Deklarieren
 *
 */

// Deklarationen
  #include "Funktion.h"                         // Deklarationen der Funkzionen
  #include "Job.h"                              // Deklarationen der Funkzionen

// Funktion etc. 
  #include "Funktion.cpp"                       // Deklarationen der Definitionen  
  #include "Job.cpp"                            // Deklarationen der Definitionen  


  #define Baudrate 9600                         // Geschwindigkeit, Serielle Schnittstelle
  
void setup()
{
  Serial.begin(Baudrate);                       // Seriellen Monitor Installiren
}

void loop()
{
  delay(10);                                    // warten für eine Sekunde 
  Serielle_abfrage();                           // abfrage der Seiellen schnittstelle und Job aufrufen 
}



/* ***********************************************************************************************
 * ***********************************************************************************************
 * Das soll alles in die Datei Funktion.cpp
 * ***********************************************************************************************
 * ***********************************************************************************************
 */


/* ***********************************************************************************************
 *                            FunktionSerielle Schnittstelle auslesen
 * ***********************************************************************************************/
 #define ZEILENTRENNZEICHEN 10
  
  char* receiveBuffer() 
  {
    static char lineBuffer[35];
    static byte counter = 0;
    char c;
      if (Serial.available() == 0) return NULL;
      if (counter == 0) memset(lineBuffer, 0, sizeof(lineBuffer));
    c = Serial.read();
      if (c == ZEILENTRENNZEICHEN)
      {
        counter=0;
        return lineBuffer; 
      }
      else if (c>=40) 
      {
        lineBuffer[counter] = c;
        if (counter < sizeof(lineBuffer) - 2) counter++; 
      }
    return NULL; 
  }

/* ***********************************************************************************************
 *                            Funktion Serielle Schnittstelle Abfragen
 * ***********************************************************************************************/
void Serielle_abfrage()
{
  
   char* text=receiveBuffer();
     if(text != NULL)
     {
             if (strcmp_P(text, PSTR("Test"))==0)          { Job_Test(); }           // Ausgabe TEST
        else if (strncmp_P(text, PSTR("Print"), 5)==0)     { Job_Print(text + 6); }  // Ausgabe alles was Hinter Print: kommt
        else  { Serial.println(F("NOK, Unbekannter Job"));}
     } // if text 
     
} // Serielle_abfrage



/* ***********************************************************************************************
 * ***********************************************************************************************
 * Das soll alles in die Datei Job.cpp
 * ***********************************************************************************************
 * ***********************************************************************************************/


/* ***********************************************************************************************
 *                            Job: Test
 * ***********************************************************************************************/
void Job_Test()
{ 
   Serial.println(F("OK, TEST")); 
}

/* ***********************************************************************************************
 *                            Job: Print
 * ***********************************************************************************************/
void Job_Print(String str)
{ 
   Serial.print(F("Übergeben wurde: ")); 
   Serial.println(str); 
}
// Funktion etc. 
  #include "Funktion.cpp"                       // Deklarationen der Definitionen  
  #include "Job.cpp"                            // Deklarationen der Definitionen

Das lass weg!
Die IDE kompiliert automatisch die cpp Dateien.
Und der Linker bindet sie ein.

combie:

// Funktion etc. 

#include "Funktion.cpp"                      // Deklarationen der Definitionen 
  #include "Job.cpp"                            // Deklarationen der Definitionen



Das lass weg!
Die IDE kompiliert automatisch die cpp Dateien.
Und der Linker bindet sie ein.

Wenn ich das richtig verstanden habe?
eine CPP Datei die in einem Tab schon mit Offen ist muss ich nicht per include einbinden?

Ich komme mit der CPP Datei nicht zurecht.

ich habe das

// Funktion etc.
  #include "Funktion.cpp"                       // Deklarationen der Definitionen 
  #include "Job.cpp"                            // Deklarationen der Definitionen

aus dem Code gelöscht.

Dann habe ich den Teil

/* ***********************************************************************************************
 *                            Job: Test
 * ***********************************************************************************************/
void Job_Test()
{ 
   Serial.println(F("OK, TEST")); 
}

genommen und in die Datei Job.cpp gepackt.
in der Datei Job.h habe ich hinein geschrieben

void Job_Test()
{ }

Dann bekomme ich beim Koppeliren den Fehler:

sketch/Job.cpp: In function 'void Job_Test()':
Job.cpp:6: error: 'Serial' was not declared in this scope
Serial.println(F("OK, TEST"));
^
Job.cpp:6: error: 'F' was not declared in this scope
Serial.println(F("OK, TEST"));
^
exit status 1
'Serial' was not declared in this scope

Wenn ich jedoch meinen Code anstelle in die .cpp Datei ihn in die .h Datei packe dann funktioniert mein Programm wider, doch das ist nicht sinn und Zweck des ganzem.

Warum mag er auf einmal Serial und F nicht mehr?
An was denke ich nicht? was wies ich nicht? wo mache ich den Fehler?

gruß Mücke

wenn es dir nur darum geht, deinen Code in Dateien zu gliedern, kannst du auch in der IDE verschiedene Tabs aufmachen, von denen jeder für sich in einer Datei abgelegt wird.

mein_projekt_01.zip (922 Bytes)

Hier mein Vorschlag (im Anhang)

Edit: Update/korrektur

MueckeAuslagern.zip (2.33 KB)

@guntherb du hast alles in ino Dateien gepackt, muss ich dann die Dinge nicht Deklarieren macht das die IDE dann wider?

Erlich gesagt geht es mir darum eine Besser Übersicht in meinen Code zu bekommen.
ich suche mir immer einen Wolf der eigentliche Code mit dem ich arbeite ich in zwischen ein paar Seiten lang.

Das andere ist das ich bei kleinen Fehlern immer sehe lange nach Lösungen suchen muss, daher würde ich es auch gerne etwas verstehen was ich da mache. Wobei ich das ganze nicht Studien möchte und auch nicht der Ultimative Programmierer werden möchte und muss.

@combie: Wow, das dauert etwas bis ich das alles durch geschaut habe, und alles nachgeschlagen habe was da neu für mich ist.

.cpp Dateien muss man nicht mit #include einbinden. Das ist für Header. Was in der .cpp Datei steht wird dann praktisch automatisch gefunden

Also für das mit der richtigen auslagern ist doch etwas (Deutlich) komplexer wie ich angenommen habe
.
Arrr...

da werde ich wohl doch auf mehrere .ino Dateien zurück greifen wie von @Gunther vorgeschlagen. das ist bei meinen Fähigkeiten der deutlich bessere Ansatz, irgend wann die Ziellinie zu sehen ;-).

da jedoch die ino Dateien einfach mit eingebunden werden ohne das ich was tun muss, komme ich mit dem Include Befehl jetzt nicht mehr so richtig klar in meinem Kopf.

Angenommen ich möchte einfach einen Bestimmten Code da es sehr viel ist wo anders hin schieben um Ihn dann per Include an einer bestimmten Stelle im Code aufzurufen.
Welche Endung muss dann die Datei haben?

Als Beispiel nehme ich einfach mal die PIN Belegung, sagen wir ich habe 50 LED`s die ich an Pins belegen möchte, Ja sehr unwahrscheinlich ist mir jetzt aber erst mal egal.

Dann würde das bei mir so aussehen:

..... 

int ledPin1 = 3;
int ledPin2 = 4;
... usw. so das hier 50 Stück stehen. 

void setup()
{
  pinMode(ledPin1, OUTPUT);
  pinMode(ledPin2, OUTPUT);
... usw. so das hier 50 Stück stehen. 
} 

...

Jetzt kommt mir bitte nicht das ich das in eine For schleife packen könnte :wink:

An genommen ich möchte in eine Separate Datei den teil

... 
int ledPin1 = 3;
...

Packen damit das im Programm etwas Ordentlicher ausschaut.

Sprich so:

..... 

#include "LED_PIN_Nummern.???"

void setup()
{
  pinMode(ledPin1, OUTPUT);
  pinMode(ledPin2, OUTPUT);
... usw. so das hier 50 Stück stehen. 
} 

...

Die Datei "LED_PIN_Nummern.???" würde dann so ausschauen:

  pinMode(ledPin1, OUTPUT);
  pinMode(ledPin2, OUTPUT);
... usw. so das hier 50 Stück stehen.

Welche Endung gebe ich der Include Datei?
muss ich dann alles was darin ist irgend wie Deklarieren?
oder kann ich der IDE sagen das der teil beim Koppeliren einfach dort eingefügt werden soll, und ich das Include nur für das Übersichtlichere Darstellen für mich da stehen habe?

Mir verwirrt das irgend wie das die ino und die CPP Dateien von alleine eingebunden werden.

gruß Mücke

Mir verwirrt das irgend wie das die ino und die CPP Dateien von alleine eingebunden werden.

Das sind 2 völlig unterschiedliche Verfahren.

Alles in *.ino, damit bist du auf einem propitären Ast.
Welcher auch einige Fallstricke bereit hält.
(warte es nur ab!)

Mein Weg ist der C++ Weg.
Der C++ Welt weit akzeptierte Standard Weg.
(zumindest dicht dran)

Stell dir nur mal vor, du würdest dich mal in das einarbeiten, was du da tust, und plötzlich verstehst du die verrücktesten Programme. Kannst dich mit ALLEN Programmieren weltweit austauschen.
Wäre das nicht wunderbar?
Mich würde erfreuen, wenn du da mal hin kommst!

Und nein, du kannst das Internet nicht leer lesen.
Du muss nichts für andere übrig lassen.

Tipp:
Irgendwo, in den Tiefen der Arduino Web Seite ist der Build Prozess beschrieben.
Lese es, oder lass es.

Muecke:
Angenommen ich möchte einfach einen Bestimmten Code da es sehr viel ist wo anders hin schieben um Ihn dann per Include an einer bestimmten Stelle im Code aufzurufen.

Include bindet ein, da ist nix mit "an bestimmter Stelle per Include aufrufen".

Gruß Tommy

combie:
Stell dir nur mal vor, du würdest dich mal in das einarbeiten, was du da tust, und plötzlich verstehst du die verrücktesten Programme. Kannst dich mit ALLEN Programmieren weltweit austauschen.
Wäre das nicht wunderbar?
Mich würde erfreuen, wenn du da mal hin kommst!

Mich auch, jedoch ist das Thema extrem Komplex finde ich, leider fehlt mir auch oft die zeit, da ich sonst nihcts Programmire, und nur die kleinen für euch wahrscheinlich echt super kleinen Projekte habe.

Mein Weg ist der C++ Weg.
Der C++ Welt weit akzeptierte Standard Weg.
(zumindest dicht dran)

Denn habe ich mir angeschaut, ich bin auch sehr begeistert davon, verstehe aber extrem wenig davon, habe heute auch einiges nachgeschlagen und nachgelesen, und bin extrem verwirrt dadurch, ich kann dir noch nicht mal sagen warum eigendlich, es dreht sich alles udn ich verstehe davon fast nichts. sobald ich eine Kleinigkeit ändere kommen Fehlermeldungen die ich wider nachschlagen muss ;-).

Ich würde gerne so viel davon verstehen, und richtig Können, nur wir wissen ja wie das ist wenn man das gelernte nicht anwendet dann verblast es auch wider, ich wende es immer dann an wenn ich hier im Forum schreibe ansonsten habe ich damit 0,0 Zutun.

Tommy56:
Include bindet ein, da ist nix mit "an bestimmter Stelle per Include aufrufen".

Gruß Tommy

Verstehe ich nicht ;-(
ich hatte den Befehl Include bisher so verstanden das ich genau an der Stelle an der der Befehl steht denn Text schreibe der in der Datei steht der durch Include aufgerufen wird.

Sprich das was ich da im Kopf habe geht nicht?

Gruß Mücke

Was du im Kopf hast sehen wir nicht.
:smiling_imp: Ich weiß auch nicht ob ich das überhaupt sehen will. :smiling_imp:

Tipp:
Solange du begründest, warum das nichts werden kann, solange wird das auch nichts.

Denn:
Wer will, findet Wege.
Wer nicht will, findet Gründe.

, ich kann dir noch nicht mal sagen warum eigendlich,

Darüber solltest du dir klar werden.

Denn dann könntest du mich fragen.
So kleine konkrete Fragen....
Denn es hat ja Gründe, warum ich das so, genau so, und nicht anders, getan habe.

combie:
Was du im Kopf hast sehen wir nicht.
:smiling_imp: Ich weiß auch nicht ob ich das überhaupt sehen will. :smiling_imp:

:o ist vielleicht besser so, ist manchmal ziemlich Karotisch in meiner Birne :wink:

combie:
Tipp:
Solange du begründest, warum das nichts werden kann, solange wird das auch nichts.

Denn:
Wer will, findet Wege.
Wer nicht will, findet Gründe.

Das ist mir auch klar.

combie:
Darüber solltest du dir klar werden.

Denn dann könntest du mich fragen.
So kleine konkrete Fragen....
Denn es hat ja Gründe, warum ich das so, genau so, und nicht anders, getan habe.

genau das wäre echt schön wenn ich das wüste, ich wollte auch kein Blöden Fragen stellen, bei denen ich mit einfachen Google drauf komme, denn dann wird mir auch irgend wann nicht mehr geholfen das will ich nicht.

Etwas selbst zu erarbeiten ist auch mal ganz gut :wink:
Vielleicht kommt das wenn ich die ein oder andere Nacht drüber geschlafen habe, das ich das ein oder andere doch verstehe, und dann Konkrete fragen stellen kann.

@combie: Ich möchte es mal wagen: und kleine Fragen Stellen zu deinem Programm Aufbau.
Auch wenn ich Gefahr laufe das ich gleich mit Google bestraft werde.

Ich gehe das Haupt Programm von Oben nach unten durch.

  1. die Datei config.h wird eingebunden. OK
    es gibt jedoch keine Config.cpp somit stehen dort nur Deklarationen drin !

Hier hast du die Installation der Serielenschnitstelle und den Zeilenumbruch (Job Bestätigung) bei der Serielenschnitstelle.

ich habe das auseinander genommen was du da geschrieben hast: sieht dann so aus bei mir.

#pragma once

 static const unsigned long Baudrate = 9600;   // Geschwindigkeit, Serielle Schnittstelle
 static const char ZEILENTRENNZEICHEN = 10;    // Zeilenumbruch in der Serielle Komunikation


/*  static
 *   Variable bleibt bestehen wird nach einem Fungzionsaufruf nicht zerstört. 
 *  const
 *   Keine Variable sondern eine Konstante, kann werend des Programm 
 *   ablaufes nihct geändert werden. 
 *  unsigned long 
 *   keine negativen Zahlen, Bereich von 0 bis 4.294.967.295
 *  char
 *   ist ein art String wenn ein * dahinter steht dann wird nicht nur der
 *   Wert sondern die Zeichenkette im Speicher verändert ! extrem verwirend
 *   für mich.
 */

Meine Frage, warum hast du das #define hier raus genommen?
mit #define habe ich doch die Möglichkeit das der Wert der dahinter steht im gesamten Code eingetragen wird, warum hast du das bei dir so Kompliziert geschrieben?

Wenn ich die Config Datei richtig verstanden habe, kann ich in in die alles rein schreiben das sonst vor dem void setup() steht? auch genau so wie es vor dem Loop sonst steht, ich muss da auf nichts achten?

Ich arbeite mich langsam durch das Programm Stück für Stück, und versuche auch so viel als Möglich nach zu googeln.

Gruß Mücke

Damit man alles noch mal in der Übersicht hat:

MueckeAuslagern.ino

  #include "config.h"
  #include "Funktionen.h"                       // Deklarationen der Funkionen
  #include "Job.h"                              // Deklarationen der Funkionen
   
void setup()
{
  Serial.begin(Baudrate);                       // Seriellen Monitor Installiren
}

void loop()
{
  delay(10);                                    // warten für 10 millisekunde 
  Serielle_abfrage();                           // abfrage der Seiellen schnittstelle und Job aufrufen 
}

Funktionen.cpp

#include <Arduino.h>
#include "config.h"
#include "Job.h"
#include "Funktionen.h"

/* ***********************************************************************************************
 *                            FunktionSerielle Schnittstelle auslesen
 * ***********************************************************************************************/
  char* receiveBuffer() 
  {
    static char lineBuffer[35];
    static byte counter = 0;
    char c;
      if (Serial.available() == 0) return NULL;
      if (counter == 0) memset(lineBuffer, 0, sizeof(lineBuffer));
    c = Serial.read();
      if (c == ZEILENTRENNZEICHEN)
      {
        counter=0;
        return lineBuffer; 
      }
      else if (c>=40) 
      {
        lineBuffer[counter] = c;
        if (counter < sizeof(lineBuffer) - 2) counter++; 
      }
    return NULL; 
  }

/* ***********************************************************************************************
 *                            Funktion Serielle Schnittstelle Abfragen
 * ***********************************************************************************************/
void Serielle_abfrage()
{
  
   char* text=receiveBuffer();
     if(text != NULL)
     {
             if (strcmp_P(text, PSTR("Test"))==0)          { Job_Test(); }           // Ausgabe TEST
        else if (strncmp_P(text, PSTR("Print"), 5)==0)     { Job_Print(text + 6); }  // Ausgabe alles was Hinter Print: kommt
        else  { Serial.println(F("NOK, Unbekannter Job"));}
     } // if text 
     
} // Serielle_abfrage

Funktionen.h

#pragma once

char* receiveBuffer();
void Serielle_abfrage();

Job.cpp

#include <Arduino.h>
#include "Job.h"

/* ***********************************************************************************************
 *                            Job: Test
 * ***********************************************************************************************/
void Job_Test()
{ 
   Serial.println(F("OK, TEST")); 
}

/* ***********************************************************************************************
 *                            Job: Print
 * ***********************************************************************************************/
void Job_Print(char* str)
{ 
   Serial.print(F("Übergeben wurde: ")); 
   Serial.println(str); 
}

Job.h

#pragma once

void Job_Test();
void Job_Print(char* str);

Job.h

#pragma once

 static const unsigned long Baudrate = 9600;   // Geschwindigkeit, Serielle Schnittstelle
 static const char ZEILENTRENNZEICHEN = 10;    // Zeilenumbruch in der Serielle Komunikation
  1. die Datei config.h wird eingebunden. OK
    es gibt jedoch keine Config.cpp somit stehen dort nur Deklarationen drin !

Nein, das ist nicht wahr!

Dort werden 2 Konstanten deklariert und im gleiche Zug auch definiert.

Sie sind static, damit sie nur für jeweils eine Übersetzungseinheit gültig sind.
Sie sind nicht global für alle Übersetzungseinheiten.

Man könnte die Konstanten auch extern deklarieren und dann in einer *.cpp definieren.
Dann würde jede Übersetzungseinheit mit den selben Konstanten arbeiten.
Hat aber den Nachteil, dass diese Konstanten dann Ram brauchen, da sie dann für mehrere verlinkte Übersetzungseinheiten gelten. Denn der Linker kann das nicht optimieren.

Klarer:
Es werden für alle Übersetzungseinheiten die gleichen Konstanten verwendet. Aber es sind nicht die selben.

Größeren Variablen/Konstanten, z.B. Strings oder Arrays wird man in der config.cpp definieren und in der *.h als extern deklarieren. Eine Mehrfach Definition würde sonst Ram verplempern.

Im Grunde besteht das Programm aus 3 Übersetungseinheiten.
Die beiden Cpp und die Ino.
Jede arbeitet hier mit ihrem eigenen Konstantensatz. (welcher hier zufälliger Weise für alle gleich ist)

Meine Frage, warum hast du das #define hier raus genommen?
mit #define habe ich doch die Möglichkeit das der Wert der dahinter steht im gesamten Code eingetragen wird, warum hast du das bei dir so Kompliziert geschrieben?

Ich mag kein define!

Wo ich darauf verzichten kann, da tue ich es.

Hier lege ich Wert auf eine Typeprüfung.
Und im Falle das Falles auf aussagekräftige Fehlermeldungen/Warnungen.

Natürlich kannst du alternativ auch deine Defines nutzen.
Das kann und will ich dir nicht nehmen.

Es ist in weiten Kreisen, auch noch üblich das so zu tun.
Aber mit den neueren C++ Versionen, ist es kein Muss mehr.
Diese bieten meist bessere Wege.

Wenn ich die Config Datei richtig verstanden habe, kann ich in in die alles rein schreiben das sonst vor dem void setup() steht? auch genau so wie es vor dem Loop sonst steht, ich muss da auf nichts achten?

Das hättest du wohl gerne....

Das wird dir der Linker schon erklären, dass das so einfach nicht ist.

  • char
  • ist ein art String wenn ein * dahinter steht dann wird nicht nur der
  • Wert sondern die Zeichenkette im Speicher verändert ! extrem verwirend
  • für mich.

char ist ein grundlegender Datentype.
Die Abkürzung von Charakter, zu deutsch: Buchstabe.
Mir ist nicht logisch, wie so man nach so vielen Jahren davon noch verwirrt sein kann.
Offensichtlich hast du dich noch nie wirklich mit Datentypen beschäftigt.

Das solltest du mal tun. Das sind grundlegenste Grundlagen, ohne die du auf ewig und immer wieder der Verwirrungen erliegen wirst.

Und was du mit dem * hast, ist ja fast noch schlimmer....
Je nach Kontext, macht der Stern eine Multiplikation, oder er drückt aus, dass man sich mit einem Zeiger beschäftigt.
Offensichtlich verwendest du Zeiger, verstehst sie aber nicht.

char, int und auch die Zeigerwirtschaft mit dem * sind fast 50 Jahre alte Fakten.
Jeder, welcher erfolgreich programmieren möchte, MUSS das lernen.
Bedenke:
Du hast jetzt 4 Jahre Verwirrung, stochern im Nebel, und was auch immer, hinter dir.
Ein einziges Buch lesen.
1 Woche Konzentration.
Und das Thema wäre durch.


Eine Vergleich: (auch wenn er hinkt)
Der Straßenverkehr!
Ein Muecke im Straßenverkehr.
Er läuft da durch. Von einem Ende der Stadt, zum anderen Ende.
Immer wieder. Seit Jahren.
Hat aber nie die Verkehrsregeln gelernt.
Ampeln und Zebrastreifen sind ihm völlig egal.
Sie werden ausgeblendet, weil sie sonst nur verwirren.
Und sowieso, ist das alles bunt hier.
Verwirrend bunt.
Manchmal gelbe blinkende Lichter, manchmal rote Lichter.
Auch weiße Lichter. Manche haben sogar vorn und hinten weiße Lichter.
Manchmal bleiben die Autos stehen..
Mal einzelne, mal ganze Gruppen, wie auf ein heimliches Kommando.
Ohne jedes erkennbare System (denn die Ampeln werden ja ausgeblendet, weil zu verwirrend)
Und überhaupt, was sind Autos, wo kommen sie her?
Gibts da irgendwo Nester?
Wieso haben die alle 4 so schwarze Dinger, welche meist bis zum Boden reichen?

Wenn den Mücke nicht ab und zu mal eine ältere hilfsbereite Dame an die Hand nehmen würde, dann hätte er so manche Straßenüberquerung nicht überlebt.


Aus meiner Sicht bist du mehr und öfter und länger mit deiner Verwirrung beschäftigt, auf Irrwegen, als das Lesen eines Buches dauern würde.

Daraus erstelle ich eine Arbeitshypothese:
Du bist gerne verwirrt.
Du liebst deine Verwirrungen.
Und du bist um keinen Preis der Welt bereit auf diese herrlichen Verwirrungen zu verzichten.

Offensichtlich haben diese Verwirrungen dein bisheriges Überleben gesichert. Also kann der Weg so ganz falsch nicht sein. Auf eine Zukunft ohne diese Verwirrungen bist du darum nicht vorbereitet. Sobald eine Klarheit/Buch hinter einer Ecke hervorlugt, ziehst du dich schockiert/panisch in deine Verwirrung zurück.
Die Verwirrung hat eine Schutzfunktion!
Sie schützt dich vor Erkenntnis.
Vor der bösen Realität.
Und natürlich vor (leicht erreichten) Erfolgen.

Huch, das gleitet ja in die tiefe Psychologie ab. :o

um mal der einfacheren Methode wieder das Wort zu reden, die einfach besser für ungelernte Softwaredummies wie mich geeignet ist:

Muecke:
@guntherb du hast alles in ino Dateien gepackt, muss ich dann die Dinge nicht Deklarieren macht das die IDE dann wider?

ja, das macht alles die IDE.

Stell dir einfach vor, die IDE packe alle deine Reiter (also die *.ino Files im Sketchverzeichnis) von links nach rechts hintereinander.

Daher empfiehlt es sich auch, im ersten Reiter alle Deklarationen zu vereinbaren.
Ich habe bei mir meist eine Struktur wie diese:
Zwischenablage01.jpg
erster Reiter: Projektbeschreibung, Globale Variable, Inkludes, enums, Structs, Funktionsdeklarationen etc. Hier steht noch keine Zeile Programmcode

Zweiter Reiter: setup(), loop() und was dazugehört. Wobei die loop recht kurz ist und meist nur ein paar Zeitscheiben und Funktionsaufrufe enthält.

Dritter bis n-ter Reiter: das eigentliche Programm, aufgeteilt in mehr oder weniger sinnvoller Bereiche

Du kannst in den Reitern (Tabs) vollig frei programmieren. Die IDE behandelt das wie ein einziges grosses File, auch Fehlermeldungen des Compilers werden den entsprechenden Reitern zugeordnet.

Die Bezeichnung der Dateien mit x1_name, x2_name, ... sind so gewählt, weil die IDE die Reiter in alphabetischer Reihenfolge anordnet.