Forum: Mikrocontroller und Digitale Elektronik Arduino und struct gefallen sich nicht !


von Ralph S. (jjflash)


Lesenswert?

Wie im Postingstitel geschrieben werden Arduino und struct in einer .ino 
Datei nicht wirklich Freunde werden.

Zugegeben (und dafür schäme ich mich mal ausnahmsweise nicht), bin ich 
ja nun wirklich ein Arduino-Anfänger (und will das so auch bleiben), 
aber andererseits möchte ich auch, wenn ich schon etwas für Arduino 
mache, das dann auch halbwegs richtig machen und genauso eben auch 
verstehen.

Im Moment erzeugt Arduino bei mir (mal wieder) ein Kopfschütteln:
1
typedef struct
2
{
3
  int x1, y1;
4
  int x2, y2;
5
  int upborderattr;
6
  int dwnborderattr;
7
  int txfieldattr;
8
} txbox_t;
9
10
txbox_t tbox;
11
12
// Arduino braucht diesen Funktionsprototyp, das ist doch bescheuert !
13
void ansi_txbox(const txbox_t *box);
14
// und hier die Funktion selbst, direkt darunter
15
void ansi_txbox(const txbox_t *box)
16
{
17
  int x;
18
  
19
  x = box->x1;
20
}

Ehrlich, wie "bescheuert" ist das denn? Und schön aussehen tut's auch 
nicht! Arduino braucht diesen Funktionsprototypen und warum?

Schlicht deshalb, weil Arduino automatisch Funktionsprototypen vor der 
Kompilierung generiert. Bei Funktionen mit Struct-Parametern kennt der 
Compiler den Typ noch nicht und deshalb muss ein Prototyp explizit 
angegeben werden um einen Fehler beim compilieren/linken:

txbox_t does not name a type.

zu vermeiden.

Ich schreibe einen Funktionsprototypen und darunter dann direkt die 
Funktion?
Okay, dann kann man das auch noch anderst lösen, verwenden wir halt 
Zeiger,
aber schön ist das ebensowenig
1
typedef struct
2
{
3
  int x1, y1;
4
  int x2, y2;
5
  int upborderattr;
6
  int dwnborderattr;
7
  int txfieldattr;
8
} txbox_t;
9
10
// Pointer ist hier ein "Arduino-Hack"
11
typedef txbox_t* ptxbox_t;
12
13
txbox_t tbox;
14
15
// Kein Prototyp notwendig und funktioniert direkt in .ino
16
void ansi_txbox(const ptxbox_t box)
17
{
18
  int x;
19
20
  x = box->x1;
21
}

Die sauberste Lösung ist dann wohl am ehesten, den struct in eine eigene 
.h Datei auszulagern, aber: will ein Arduino-User das? Mit mehr als 
einer Datei hantieren.

Eine Frage an die Cracks (und die Nicht-Anfänger wie mich): wie ist das 
korrekte Vorgehen?

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Ralph S. schrieb:
> typedef struct
>
> {
>
>   int x1, y1;
>
>   int x2, y2;
>
>   int upborderattr;
>
>   int dwnborderattr;
>
>   int txfieldattr;
>
> } txbox_t;

Vielleicht geht's ohne den unnötigen typedef-Tanz?
1
struct tbox_t
2
{
3
  int x1, y1;
4
  int x2, y2;
5
  int upborderattr;
6
  int dwnborderattr;
7
  int txfieldattr;
8
};

von Rahul D. (rahul)


Lesenswert?

Wie wäre es, wenn du mal compilierbaren Quellcode zu dem "Problem" 
posten würdest (natürlich gerne als Anhanh)?!

Structs funktionieren auch im Arduino-Wrapper.
Du hast eher ein Problem mit dem Ort der Typen-Definition.

von Falk B. (falk)


Lesenswert?

Ralph S. schrieb:
> Wie im Postingstitel geschrieben werden Arduino und struct in einer .ino
> Datei nicht wirklich Freunde werden.

Ein lösbares Problem.

> mache, das dann auch halbwegs richtig machen und genauso eben auch
> verstehen.

Gute Einstellung.

> Im Moment erzeugt Arduino bei mir (mal wieder) ein Kopfschütteln:typedef
> struct
> {
>   int x1, y1;
>   int x2, y2;
>   int upborderattr;
>   int dwnborderattr;
>   int txfieldattr;
> } txbox_t;
> txbox_t tbox;

Zeig und VOLLSTÄNDIGEN, compilerbaren Quelltext als Anhang.

> // Arduino braucht diesen Funktionsprototyp, das ist doch bescheuert !

Nein, das ist es nicht. Wer C mal verstanden hat, weiß auch warum.

> Ehrlich, wie "bescheuert" ist das denn? Und schön aussehen tut's auch
> nicht! Arduino braucht diesen Funktionsprototypen und warum?

Laber nicht rum! Das habe sich sehr schlau Leute vor verdammt langer 
Zeit ausgedacht. Es hat seinen Sinn! Wenn man die Funktionen in eine 
Datei packt, braucht man nicht unbedingt Prototypen. Wenn man die 
Funktionen aber in mehrere Dateien aufteilt, braucht man sie, denn 
andere Dateien müssen wissen, wie die Funktionen aufgerufen werden. Also 
natürlich der Compiler, wenn er eine Datei compiliert.

> Schlicht deshalb, weil Arduino automatisch Funktionsprototypen vor der
> Kompilierung generiert. Bei Funktionen mit Struct-Parametern kennt der
> Compiler den Typ noch nicht und deshalb muss ein Prototyp explizit
> angegeben werden um einen Fehler beim compilieren/linken:

Und wo liegt das Problem? Der Rest der Welt hat keins damit.

> txbox_t does not name a type.
>
> zu vermeiden.
>
> Ich schreibe einen Funktionsprototypen und darunter dann direkt die
> Funktion?

Nö. Man schreibt Header files und bindet die per #inlcude ein. Dort 
gehören auch die Typdefinitionen rein.

> Die sauberste Lösung ist dann wohl am ehesten, den struct in eine eigene
> .h Datei auszulagern,

BINGO!

> aber: will ein Arduino-User das? Mit mehr als
> einer Datei hantieren.

Er wird es lernen müssen. Ist wohl nicht zuviel verlangt.

von Nick (b620ys)


Lesenswert?

Niklas G. schrieb:
> Vielleicht geht's ohne den unnötigen typedef-Tanz?

Hääää?

Wie gehts denn dann da weiter, ohne typedef? Mit void und casting?
1
void ansi_txbox(const txbox_t *box)
2
{
3
  int x;
4
5
  x = box->x1;
6
}

Ich mach das immer prinzipiell mit typedef, auch wenn ich den typen 
-zunächst vermutlich- nur ein mal brauche.

von Rahul D. (rahul)


Lesenswert?

Nick schrieb:
> Wie gehts denn dann da weiter, ohne typedef?

man schleppt "struct" die ganze Zeit mit.

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Nick schrieb:
> Wie gehts denn dann da weiter, ohne typedef? Mit void und casting?

Nein, einfach nur txbox_t weiter verwenden. Genau wie vorher.

Nick schrieb:
> Ich mach das immer prinzipiell mit typedef, auch wenn ich den typen
> -zunächst vermutlich- nur ein mal brauche.

Wo ist der Nutzen?
1
struct tbox_t
2
{
3
  int x1, y1;
4
  int x2, y2;
5
  int upborderattr;
6
  int dwnborderattr;
7
  int txfieldattr;
8
};

und
1
typedef struct
2
{
3
  int x1, y1;
4
  int x2, y2;
5
  int upborderattr;
6
  int dwnborderattr;
7
  int txfieldattr;
8
} txbox_t;

sind identisch. Das erste ist aber kürzer, und vielleicht kommt Arduino 
damit besser klar.

Rahul D. schrieb:
> man schleppt "struct" die ganze Zeit mit.

Nicht nötig.

von Nick (b620ys)


Lesenswert?

Falk B. schrieb:
> Nö. Man schreibt Header files und bindet die per #inlcude ein.

Aha. Man muss also Sachen die lediglich in einer Datei verwendet werden 
und die Benutzer nichts angehen, veröffentlichen.

> Dort gehören auch die Typdefinitionen rein.

Die gehören da hin, wo sie verwendet werden. Und sonst nirgendwo.

von Falk B. (falk)


Lesenswert?

Nick schrieb:
>> Nö. Man schreibt Header files und bindet die per #inlcude ein.
>
> Aha. Man muss also Sachen die lediglich in einer Datei verwendet werden
> und die Benutzer nichts angehen, veröffentlichen.

Bist du so dumm oder tust du nur so?

>> Dort gehören auch die Typdefinitionen rein.
>
> Die gehören da hin, wo sie verwendet werden. Und sonst nirgendwo.

Du mußt es wissen.

von Arduino F. (Firma: Gast) (arduinof)


Lesenswert?

Nick schrieb:
> Hääää?
>
> Wie gehts denn dann da weiter, ohne typedef?

Arduino ist C++ nicht C, zumindest in *.ino, *.pde und *.cpp Dateien.

C++ kann zwar noch typedef, aber typedef ist in den allermeisten Fällen 
nicht nötig, oder auch sinnig.
Vor struct ist es flüssiger als Waser.
Sie restlichen typedef lassen sich gerne durch using ersetzen.

von Nick (b620ys)


Lesenswert?

Falk B. schrieb:
>> Die gehören da hin, wo sie verwendet werden. Und sonst nirgendwo.
>
> Du mußt es wissen.

Datenkapselung ("encapsulation") ist wohl ein neuer Begriff für dich. 
Ich helf dir kurz:
https://de.wikipedia.org/wiki/Datenkapselung_(Programmierung)

von Falk B. (falk)


Lesenswert?

Nick schrieb:
> Datenkapselung ("encapsulation") ist wohl ein neuer Begriff für dich.
> Ich helf dir kurz:
> https://de.wikipedia.org/wiki/Datenkapselung_(Programmierung)

Du trägst gerade Eulen nach Athen.

https://de.wikipedia.org/wiki/Eulen_nach_Athen_tragen

;-)

von Roland F. (rhf)


Lesenswert?

Hallo,
Arduino F. schrieb:
> Arduino ist C++ nicht C...

Verwirre ihn nicht noch mehr.

rhf

von Christoph M. (mchris)


Lesenswert?

Ralph S. schrieb:
> Wie im Postingstitel geschrieben werden Arduino und struct in einer .ino
> Datei nicht wirklich Freunde werden.

Eine *.ino-Datei ist keine cpp oder c Datei. Die hat ein paar spezielle 
Eigenheiten um den Syntax für die Arduinonutzer zu vereinfachen.

Du kannst aber in jedem Arduinoprojekt eine *.cpp, *.h, *.c Datei 
anlegen per "#include" einbinden (bei *.c "extern C" nicht vergessen). 
Dann verhält sich das Projekt genau wie bei jedem anderen C- oder cpp 
Projekt.

Um alle Arduino-Defines verfügbar zu haben, brauchst du dann noch 
#include "Arduino.h".

von Roland F. (rhf)


Lesenswert?

Hallo,
Nick schrieb:
> Ich helf dir kurz:...

Wenn du wirklich Hilfe suchst, würde ich dir dringend empfehlen hier 
etwas weniger überheblich aufzutreten. Glaub mir, die Allermeisten hier 
brauchen deine Hilfe definitiv nicht (und der Angesprochene schon gar 
nicht).

Und im Übrigen sollte jemand, der so selbstbewusst daher kommt wie du, 
zumindest die Grundlagen der verwendeten Programmiersprache beherrschen.

rhf

von Arduino F. (Firma: Gast) (arduinof)


Lesenswert?

Christoph M. schrieb:
> Eine *.ino-Datei ist keine cpp oder c Datei.

Der Arduino Builder wandelt die *.ino in eine *.cpp um.
Es ist hinreichend dokumentiert, was der Builder tut.
Kann man ruhig mal lesen.

von Nick (b620ys)


Lesenswert?

Roland F. schrieb:
> Wenn du wirklich Hilfe suchst,

Ich such keine Hilfe.

Roland F. schrieb:
> würde ich dir dringend empfehlen hier
> etwas weniger überheblich aufzutreten.

Aha.

Falk B. schrieb:
> Bist du so dumm oder tust du nur so?

Falk B. schrieb:
> Du mußt es wissen.

Falk B. schrieb:
> Du trägst gerade Eulen nach Athen.

Aber gleichzeitig fordern typedefs prinzipiell in header zu schreiben. 
Da scheint mir jede weiteres Diskussion sinnlos.

von Alexander (alecxs)


Lesenswert?

Christoph M. schrieb:
> Du kannst aber in jedem Arduinoprojekt eine *.cpp, *.h, *.c Datei
> anlegen per "#include" einbinden

lies bitte noch mal das OP

von Peter (pittyj)


Lesenswert?

Arduino F. schrieb:

> Arduino ist C++ nicht C, zumindest in *.ino, *.pde und *.cpp Dateien.
>

Und statt struct nimmt man dann eine class. Die bietet einige Vorteile.

Ich habe hier noch einen K&R von 1983 stehen. Trotzdem bevorzuge ich die 
Klassen. Man muss es ja nicht mit templates und Lambdas übertreiben.

von Arduino F. (Firma: Gast) (arduinof)


Lesenswert?

Ralph S. schrieb:
> Die sauberste Lösung ist dann wohl am ehesten, den struct in eine eigene
> .h Datei auszulagern, aber: will ein Arduino-User das? Mit mehr als
> einer Datei hantieren.

Erst den richtigen Weg erkennen, und danach, im gleichen Satz, voll das 
Arduino Bashing.
Also Nein!
Nicht alle Arduino User sind so blöd wie du dir das wünscht!

von Kilo S. (kilo_s)


Lesenswert?

Nick schrieb:
> Aha. Man muss also Sachen die lediglich in einer Datei verwendet werden
> und die Benutzer nichts angehen, veröffentlichen.

Boar, gibt selten Leute denen ich empfehle es einfach sein zu lassen.
Aber wer sogar zu doof ist ne lokale Datei anzulegen und zu verwenden 
gehört definitiv dazu.

Leg die .h mit in deinen Sketchorder:
1
#include "ZuDoofUmPunktHEinzubinden.h"

Und freu dich das die Funktionen in deiner .ino verfügbar sind!

https://docs.arduino.cc/language-reference/en/structure/further-syntax/include/

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Peter schrieb:
> Und statt struct nimmt man dann eine class. Die bietet einige Vorteile.

Welche? struct und class machen genau das Gleiche, nämlich eine Klasse 
definieren. In C++ gibt's keine structs, nur Klassen. Das 
"struct"-Keyword ist fast ein Alias für das "class" Keyword. Bei struct 
sind die Member per default public, und ich glaub es werden IIRC ein 
paar default Konstruktoren angelegt... Aber im Endeffekt kann man mit 
beiden Keywords exakt das gleiche erzielen.

Man kann "struct" zur Dokumentation nutzen um anzudeuten dass es sich um 
eine simple "Datenklasse" handelt, eben so wie man struct in C 
verwendet.

von Arduino F. (Firma: Gast) (arduinof)


Lesenswert?

Nick schrieb:
> Aha. Man muss also Sachen die lediglich in einer Datei verwendet werden
> und die Benutzer nichts angehen, veröffentlichen.

Nein!
Natürlich kannst du struct Definitionen auch in *.cpp Dateien 
verstecken.
Aber sonderlich sinnvoll ist das meist nicht.

von Christoph M. (mchris)


Lesenswert?

Alexander schrieb:
> lies bitte noch mal das OP

Was soll das sein? Drück dich bitte präzise aus.

von Nick (b620ys)


Lesenswert?

Kilo S. schrieb:
> Nick schrieb:
>> Aha. Man muss also Sachen die lediglich in einer Datei verwendet werden
>> und die Benutzer nichts angehen, veröffentlichen.
>
> Boar, gibt selten Leute denen ich empfehle es einfach sein zu lassen.

Was war jetzt nochmal dein Argument dafür unnötig lokale Informationen 
nach aussen hin sichtbar zu machen?
Dummheit? Datenkapselung? Schlechte Interfaces?

Kilo S. schrieb:
> #include "ZuDoofUmPunktHEinzubinden.h"

oder nur mangelnde persönliche Reife?

von Kilo S. (kilo_s)


Angehängte Dateien:

Lesenswert?

Nick schrieb:
> Was war jetzt nochmal dein Argument dafür unnötig lokale Informationen
> nach aussen hin sichtbar zu machen?

Google mal ob du meine lokalen includes irgendwo in Arduino oder online 
findest! (Tipp: du wirst Jahrhunderte suchen und meine Dateien nicht 
finden! Außer der VapeDisplayDriver.h und fontandcolor.h , die liegen 
hier im Forum im Beitrag zur 25k Vape.)

Dateinamen: py32f030k28_vCustom.h, dbgmcu.h, Interface.h

Alle diese Dateien enthalten unter anderem Code workaround speziell für 
die Macken des PYDuino core.

: Bearbeitet durch User
von Nick (b620ys)


Lesenswert?

Arduino F. schrieb:
> Natürlich kannst du struct Definitionen auch in *.cpp Dateien
> verstecken.

OK. Man kann und soll sogar.

> Aber sonderlich sinnvoll ist das meist nicht.

Wenn man sich keine Gedanken zu seinen Interfaces macht, dann kann man 
das so sehen.

Wenn ich nochmal auf Datenkapselung hinweisen darf?
Das Konzept wird ja noch weitergeführt in OOP. Nach aussen hin so wenig 
wie möglich und nur so viel wie nötig preisgeben. Andere Sprachen 
ermöglichen sogar lokale Funktionen/Prozeduren. Das erhöht die 
Lesbarkeit und Wartbarkeit. Manchen mag das egal sein, Hauptsache es 
läuft.

Oder verwendest du nur globale Variablen, statt lokaler (ggf. sogar nur 
innerhalb eines Blocks)?
Ich nehme mal an, dass nicht. Aber dann gilt das gleiche Argument auch 
für die header.

von Harry L. (mysth)


Lesenswert?

Nick schrieb:
> Arduino F. schrieb:
>> Natürlich kannst du struct Definitionen auch in *.cpp Dateien
>> verstecken.
>
> OK. Man kann und soll sogar.
>
>> Aber sonderlich sinnvoll ist das meist nicht.
>
> Wenn man sich keine Gedanken zu seinen Interfaces macht, dann kann man
> das so sehen.
>
> Wenn ich nochmal auf Datenkapselung hinweisen darf?
> Das Konzept wird ja noch weitergeführt in OOP. Nach aussen hin so wenig
> wie möglich und nur so viel wie nötig preisgeben. Andere Sprachen
> ermöglichen sogar lokale Funktionen/Prozeduren. Das erhöht die
> Lesbarkeit und Wartbarkeit. Manchen mag das egal sein, Hauptsache es
> läuft.
>
> Oder verwendest du nur globale Variablen, statt lokaler (ggf. sogar nur
> innerhalb eines Blocks)?
> Ich nehme mal an, dass nicht. Aber dann gilt das gleiche Argument auch
> für die header.

Lern erstmal, den Unterschied zwischen "Definition" und "Deklaration" zu 
verstehen, bevor du dich hier so weit aus dem Fenster lehnst, und so 
einen Bullshit verzapfst!

Das ist einfach nur noch peinlich!

von Arduino F. (Firma: Gast) (arduinof)


Lesenswert?

Nick schrieb:
> Man kann und soll sogar.

Die "Regeln" sind sowohl logisch, als auch sinnvoll!

Wird die Struktur in nur einer *.c oder *.cpp Datei benötigt, dann 
bringt man sie da unter.

Wird die Struktur in in mehreren *.c oder *.cpp Dateien benötigt, dann 
sollte man sie in einer *.h unterbringen.

von Alexander (alecxs)


Lesenswert?

Kilo S. schrieb:
> Google mal ob du meine lokalen includes irgendwo in Arduino oder online
> findest! (Tipp: du wirst Jahrhunderte suchen und meine Dateien nicht
> finden!

ChatGPT hat mir die Dateien gegeben und dazu erzählt es hätte diese erst 
kürzlich erstellt.

von Arduino F. (Firma: Gast) (arduinof)


Lesenswert?

Christoph M. schrieb:
> Du kannst aber in jedem Arduinoprojekt eine *.cpp, *.h, *.c Datei
> anlegen per "#include" einbinden

*.c oder *.cpp Dateien per include einbinden führt ganz schnell zu 
vielen Linker Errors. Bitte nachlesen, was der Bilder tut.

von Kilo S. (kilo_s)


Lesenswert?

Alexander schrieb:
> ChatGPT hat mir die Dateien gegeben und dazu erzählt es hätte diese erst
> kürzlich erstellt.

Zeig mal den Inhalt.

von Nick (b620ys)


Lesenswert?

Arduino F. schrieb:
> Wird die Struktur in nur einer *.c oder *.cpp Datei benötigt, dann
> bringt man sie da unter.

Dann sind wir uns ja einig.
Und damit ist die "Lösung" den typedef in einen header zu schreiben 
(beim Beispiel des TO) eben nur eine unsaubere Lösung.

Harry L. schrieb:
> Lern erstmal, den Unterschied zwischen "Definition" und "Deklaration" zu
> verstehen, bevor du dich hier so weit aus dem Fenster lehnst, und so
> einen Bullshit verzapfst!

Bist du jetzt schon argumentativ im Endschalter?
Nirgendwo hab ich in meiner Antwort Definition oder Deklaration 
verwendet.

Harry L. schrieb:
> Das ist einfach nur noch peinlich!

Also du bist am Anschlag. Danke, aber das hab ich schon gemerkt.

von Arduino F. (Firma: Gast) (arduinof)


Lesenswert?

Nick schrieb:
> Dann sind wir uns ja einig.
> Und damit ist die "Lösung" den typedef in einen header zu schreiben
> (beim Beispiel des TO) eben nur eine unsaubere Lösung.

Nein!
Die Fehler Meldungen im Eingangsposting sagen ganz klar, dass da der 
Bock geschossen wird.
Dummer weise, hat es der TO vermieden ein testbares Beispiel zu liefern.
Außer jammern und Prosa ist da nix.

von Alexander (alecxs)


Angehängte Dateien:

Lesenswert?

Kilo S. schrieb:
> Zeig mal den Inhalt.

von Nick (b620ys)


Lesenswert?

Arduino F. schrieb:
> Nick schrieb:
>> Dann sind wir uns ja einig.
>> Und damit ist die "Lösung" den typedef in einen header zu schreiben
>> (beim Beispiel des TO) eben nur eine unsaubere Lösung.
>
> Nein!

Arduino F. schrieb:
> Wird die Struktur in nur einer *.c oder *.cpp Datei benötigt, dann
> bringt man sie da unter.

Na gut.

Beitrag #8022487 wurde vom Autor gelöscht.
von Kilo S. (kilo_s)


Lesenswert?

;-) hihi, nette Idee.

ChatGPT kann dir die nicht geben, das erstellt höchstens gleichnamige 
Dateien mit viel falschem STM Registerzeug, wenn du dem nicht Quasi 
einprügelst das es Air001 verwendet, baut es nur scheiße zusammen.

von Kilo S. (kilo_s)


Lesenswert?

Ist eher mein geschmack:
1
unsigned char kilo[] = {
2
  0x68, 0x74, 0x74, 0x70, 0x73, 0x3A, 0x2F, 0x2F,
3
  0x74, 0x69, 0x6E, 0x79, 0x75, 0x72, 0x6C, 0x2E,
4
  0x63, 0x6F, 0x6D, 0x2F, 0x34, 0x68, 0x34, 0x6D,
5
  0x76, 0x64, 0x72, 0x65, 0x0D, 0x0A
6
};

von Georg M. (g_m)


Lesenswert?

Es stehen folgende Unterforen zur Auswahl:

Forum: Mikrocontroller und Digitale Elektronik
Für alle Fragen rund um Mikrocontroller und sonstige digitale 
Elektronik.

Forum: Compiler & IDEs
Fragen zu Compilern und Entwicklungsumgebungen für Mikrocontroller, z.B. 
GCC.

Forum: PC-Programmierung
Programmierung auf PCs, Algorithmen, allgemeine Programmierfragen ohne 
direkten Mikrocontroller-Bezug.

von Alexander (alecxs)


Lesenswert?

Kilo S. schrieb:
> Ist eher mein geschmack

Rickrolling passt dann aber nicht mehr, dann musst Du Dir ein eigenes 
Meme ausdenken

https://www.mikrocontroller.net/topic/goto_post/7935049

von Norbert (der_norbert)


Lesenswert?

Kilo S. schrieb:
> Ist eher mein geschmack:unsigned char kilo[] = {
>   0x68, 0x74, 0x74, 0x70, 0x73, 0x3A, 0x2F, 0x2F,
>   0x74, 0x69, 0x6E, 0x79, 0x75, 0x72, 0x6C, 0x2E,
>   0x63, 0x6F, 0x6D, 0x2F, 0x34, 0x68, 0x34, 0x6D,
>   0x76, 0x64, 0x72, 0x65, 0x0D, 0x0A
> };

unsigned? ;-)

von Kilo S. (kilo_s)


Lesenswert?

Norbert schrieb:
> unsigned? ;-)

Hab nur eben die Bytes getauscht, Rest ungelesene übernommen. ;-D

Funktioniert ja trotzdem auch wenn const char richtig wäre.
Wenn ich das auf dem PY32 MCU machen würde, wäre es sogar
1
static const char kilo[] = ...

RAM sparen. ;-)

von Arduino F. (Firma: Gast) (arduinof)


Lesenswert?

Kilo S. schrieb:
> Ist eher mein geschmack:

Naja...
Wenn Arduino/C++ dann doch eher:
1
constexpr unsigned char kilo[] 
2
{
3
  0x68, 0x74, 0x74, 0x70, 0x73, 0x3A, 0x2F, 0x2F,
4
  0x74, 0x69, 0x6E, 0x79, 0x75, 0x72, 0x6C, 0x2E,
5
  0x63, 0x6F, 0x6D, 0x2F, 0x34, 0x68, 0x34, 0x6D,
6
  0x76, 0x64, 0x72, 0x65, 0x0D, 0x0A,
7
};
oder?

: Bearbeitet durch User
von Nick (b620ys)


Lesenswert?

Kilo S. schrieb:
> Funktioniert ja trotzdem auch wenn const char richtig wäre.

Wenn man uint8_t noch nicht kennt...

von Arduino F. (Firma: Gast) (arduinof)


Lesenswert?

Nick schrieb:
> Wenn man uint8_t noch nicht kennt...
Und dann, wenn man Glück hat, muss man feststellen, dass es das nicht 
überall gibt.

von Ralph S. (jjflash)


Lesenswert?

Arduino F. schrieb:
> Erst den richtigen Weg erkennen, und danach, im gleichen Satz, voll das
> Arduino Bashing.
> Also Nein!
> Nicht alle Arduino User sind so blöd wie du dir das wünscht!

Sorry, wenn das so rüber gekommen ist, das soll mit Bashing nichts zu 
tun haben. Ich habe hier etwas angefangen (eben in Arduino) und möchte 
das eben so auch machen, auch wenn das nicht für mich ist.

Und ich möchte das so gut ich das kann machen und ich möchte das so 
angenehm für einen Arduino User machen wie es geht. Hier stellt sich mir 
die Frage schlicht, wie fängt ein Arduino User an. Er fängt erst einmal 
mit nichts an und weiß auch wenig und er weiß auch noch nicht wirklich 
was eine Inlcude-Datei ist und was da hinein gehört und was nicht. Er 
wird nur die eine .ino Datei bearbeiten.

Erst im Laufe der Zeit wird er sich vllt. Gedanken darüber machen, wie 
Libraries aufgebaut sind, was ein Objekt, eine Objektinstanz ein 
Konstruktor etc. ist. Er wird erst später verstehen, dass er in seinem 
Ordner seines Projekts nicht nur die .ino Datei liegen haben kann.

Ich habe schon ausgefeilte Algorithmen und Codes in Arduino gesehen, bei 
denen ich gedacht habe: wow.... aber ich habe auch gestaunt über die Art 
und Weise, wie der Code aufgebaut war.

Von daher: nein, das soll hier kein Bashing sein und schon gar nicht 
halte ich die Arduino-User für blöd. Je mehr ich mich damit momentan 
beschäftige, umso mehr kann ich auch verstehen, dass da manche 
begeistert sind, auch wenn es genügend Einschränkungen gibt.

Wenn man ein Bashing vornehmen möchte (und eigentlich auch kann), dann 
in der Richtung, dass es immer häufiger moderne Chips gibt, die auf ein 
Board geklatscht werden und dann gibt es einen unausgegorenen Core der 
oft (ogt != selten) nicht das tut was er soll.

Arduino F. schrieb:
> Die Fehler Meldungen im Eingangsposting sagen ganz klar, dass da der
> Bock geschossen wird.
> Dummer weise, hat es der TO vermieden ein testbares Beispiel zu liefern.
> Außer jammern und Prosa ist da nix.

:-) nein, der TO war mit seiner Frau einkaufen ... :-)) zudem hat er 
sich entschlossen, dass in seinen Tests erst einmal mit 
Funktionsprototypen zu machen, weil die Dinge die er testet, erst einmal 
in den Structs belässt und dann später sowieso Bestandteil einer Klasse 
werden. Und, ich muß jetzt irgendwie über mich selbst lachen: ich habe 
jetzt das ganze ohne Zeiger gemacht und das funktioniert dann erst 
einmal (von daher ist mein "Problem" gelöst), Die Diskussion hier find 
ich gar nicht mal so schlecht, nur der Ton ist gewohnt 
superklasseroberaffentittengeil-gut ... oder auch nicht !

Ach so, ja, bevor gemeckert wird, ein (leider) funktionsfährig und 
compilierbares Testprogramm:
1
typedef struct
2
3
{
4
  int x1, y1;
5
  int x2, y2;
6
  int upborderattr;
7
  int dwnborderattr;
8
  int txfieldattr;
9
} txbox_t;
10
11
txbox_t tbox;
12
13
void ansi_txbox(txbox_t box)
14
{
15
  int x;
16
  
17
  x= box.x1;
18
  Serial.println("\n\r Nur eine Testausgabe \n\r");
19
}
20
21
void setup() 
22
{
23
  Serial.begin(115200);
24
25
  tbox.x1= 0; tbox.y1= 0;
26
  tbox.x2= 40; tbox.y2= 10;
27
  tbox.txfieldattr= 0x70;
28
  tbox.upborderattr= 0xae;
29
  tbox.dwnborderattr= 0x2e;  
30
  
31
  ansi_txbox(tbox);
32
}
33
34
void loop() 
35
{
36
}

von Hans W. (hanswieland)


Lesenswert?

>> Wenn man uint8_t noch nicht kennt...
Arduino F. schrieb:

> Und dann, wenn man Glück hat, muss man feststellen, dass es das nicht
> überall gibt.

Nenne mal ein nachvollziehbares Beispiel aus diesem Jahrtausend.

von Falk B. (falk)


Lesenswert?

Ralph S. schrieb:

> Und ich möchte das so gut ich das kann machen und ich möchte das so
> angenehm für einen Arduino User machen wie es geht.

Ja, aber.

> Hier stellt sich mir
> die Frage schlicht, wie fängt ein Arduino User an. Er fängt erst einmal
> mit nichts an und weiß auch wenig und er weiß auch noch nicht wirklich
> was eine Inlcude-Datei ist und was da hinein gehört und was nicht. Er
> wird nur die eine .ino Datei bearbeiten.

Und wo liegt das Problem?

> werden. Und, ich muß jetzt irgendwie über mich selbst lachen: ich habe
> jetzt das ganze ohne Zeiger gemacht und das funktioniert dann erst
> einmal (von daher ist mein "Problem" gelöst),

Das ist ein Irrtum. Denn du sollest mal über das Thema "call by value" 
und "call by reference" nachdenken. Dein Testprogramm schreibt in der 
Funktion
ansi_txbox() auf eine KOPIE der globalen Variable/Struct tbox. Das ist 
mit Sicherheit nicht gewünscht. Ein Lesezugriff wäre OK. Structs KANN 
man als Wert (call by value, KOPIE!) oder als Zeiger auf das Objekt 
(call by reference) als Parameter übergeben. Meistens ist die Referenz 
(Zeiger) besser und vor allem das, was man wirklich will.

> Ach so, ja, bevor gemeckert wird, ein (leider) funktionsfährig und
> compilierbares Testprogramm:typedef struct

Wieso leider? Welche komischen, ästhetischen Ansprüche hast du als 
ANFÄNGER?

> {
>   int x1, y1;
>   int x2, y2;
>   int upborderattr;
>   int dwnborderattr;
>   int txfieldattr;
> } txbox_t;

> txbox_t tbox;

globale Variable

> void ansi_txbox(txbox_t box)
> {
>   int x;
>
>   x= box.x1;

Zugriff auf lokale Kopie in der Funktion. Die verschwindet beim 
Verlassen der Funktion!

>   Serial.println("\n\r Nur eine Testausgabe \n\r");
> }
> void setup()
> {
>   Serial.begin(115200);
>   tbox.x1= 0; tbox.y1= 0;
>   tbox.x2= 40; tbox.y2= 10;
>   tbox.txfieldattr= 0x70;
>   tbox.upborderattr= 0xae;
>   tbox.dwnborderattr= 0x2e;
>
>   ansi_txbox(tbox);

Aufruf mit lokaler Kopie von tbox.

von Nick (b620ys)


Lesenswert?

Arduino F. schrieb:
> Und dann, wenn man Glück hat, muss man feststellen, dass es das nicht
> überall gibt.

stdint.h gibts nicht? Aber auf dem Arduino schon.
stdint.h gibts seit C99, also seit 1999. In C++ seit 2005.

Also Pech gehabt.

von Norbert (der_norbert)


Lesenswert?

Nick schrieb:
> Wenn man uint8_t noch nicht kennt...

Knapp daneben ist auch vorbei!

von Arduino F. (Firma: Gast) (arduinof)


Lesenswert?

Ralph S. schrieb:
> void ansi_txbox(txbox_t box)
Hier würde ich den Copy Construktor vermeiden wollen!

von Nick (b620ys)


Lesenswert?

Norbert schrieb:
> Knapp daneben ist auch vorbei!

Wenn du schon weißt, dass Kilo S. uint8_t kennt, dann kannst Du 
sicherlich auch ein gutes Argument bringen, warum man uint8_t nicht 
verwenden sollte.

von Arduino F. (Firma: Gast) (arduinof)


Lesenswert?

Nick schrieb:
> stdint.h gibts seit C99, also seit 1999. In C++ seit 2005.

uint8_t ist ein optionaler Datentype.
Steht nicht auf allen Plattformen zur Verfügung.

von Nick (b620ys)


Lesenswert?

Arduino F. schrieb:
> Steht nicht auf allen Plattformen zur Verfügung.

Arduino scheidet aber schon mal aus, da gibts ihn.

von Arduino F. (Firma: Gast) (arduinof)


Lesenswert?

Nick schrieb:
> Arduino scheidet aber schon mal aus, da gibts ihn.
Da sind so viele µC im Spiel, dass ich da nicht die Hand für ins Feuer 
legen würde.

Was heute noch richtig zu sein scheint, kann morgen schon anders 
aussehen.

: Bearbeitet durch User
von Christoph M. (mchris)


Lesenswert?

Ralph S. schrieb:
> Und ich möchte das so gut ich das kann machen und ich möchte das so
> angenehm für einen Arduino User machen wie es geht. Hier stellt sich mir
> die Frage schlicht, wie fängt ein Arduino User an. Er fängt erst einmal
> mit nichts an

Doch, doch: Er nimmt den Mauszeiger und bewegt ihn auf das 
Drop-Down-Menu, bei dem "examples" steht, denn es gilt: Ein Beispiel 
sagt mehr als 1000 Worte.

Ralph S. schrieb:
> Und, ich muß jetzt irgendwie über mich selbst lachen: ich habe
> jetzt das ganze ohne Zeiger gemacht und das funktioniert dann erst
> einmal (von daher ist mein "Problem" gelöst)

Zeiger sollte man in der Arduinowelt möglichst vermeiden (und das geht 
auch meistens).

von Nick (b620ys)


Lesenswert?

Arduino F. schrieb:
> Da sind so viele µC im Spiel, dass ich da nicht die Hand für ins Feuer
> legen würde.

Dann probier's aus und meld dich dann wieder.

Übrigens:
Wenns keinen unit8_t gibt ist die Verwendung von unsigned char auch 
sinnlos. Wobei ich das Gewurstle von "unsigned char" und "long long" 
etc. schon immer sinnlos fand.
Aber zumindest weiß man es dann nicht. Das hilft ja Einigen schon 
weiter.

von Maxim B. (max182)


Lesenswert?

Christoph M. schrieb:
> Zeiger sollte man in der Arduinowelt möglichst vermeiden

Nachdem ich HAL für STM32 etwas genauer angekuckt habe, sehe ich, daß 
Zeiger auf Structur viele Aufgaben erleichtern könnten und auch manche 
Fehler vermeiden helfen.
Da Arduino GIGA mit STM32H747 bestückt wird, liegt auf der Hand, daß 
HAL-Vorgehensweise auch für Arduino nicht uninteressant wird.

von Ralph S. (jjflash)


Lesenswert?

Falk B. schrieb:
> ansi_txbox() auf eine KOPIE der globalen Variable/Struct tbox. Das ist
> mit Sicherheit nicht gewünscht. Ein Lesezugriff wäre OK. Structs KANN
> man als Wert (call by value, KOPIE!) oder als Zeiger auf das Objekt
> (call by reference) als Parameter übergeben. Meistens ist die Referenz
> (Zeiger) besser und vor allem das, was man wirklich will.

ich weiß, und das ist am Schluß auch nicht gewünscht und wird dann in 
einer Klasse garantiert einen Zeiger haben. Es ging darum, einen 
compilierbaren Code zu haben.

Arduino F. schrieb:
> Ralph S. schrieb:
>> void ansi_txbox(txbox_t box)
> Hier würde ich den Copy Construktor vermeiden wollen!

Wie oben schon für Falk geschrieben wird es das auch werden...

Christoph M. schrieb:
> Zeiger sollte man in der Arduinowelt möglichst vermeiden (und das geht
> auch meistens).

Das ist mir aber nun wirklich neu, dass man keine Zeiger verwenden soll 
!

by the way, damit (hoffentlich) Friede herrscht, mittels Zeiger (an 
chris: ohne Zeiger werde ich sicherlich nichts machen):
1
typedef struct
2
3
{
4
  int x1, y1;
5
  int x2, y2;
6
  int upborderattr;
7
  int dwnborderattr;
8
  int txfieldattr;
9
} txbox_t;
10
11
txbox_t tbox;
12
13
void ansi_txbox(const txbox_t *box)
14
{
15
  int x;
16
  
17
  x= box->x1;
18
  Serial.println("\n\r Nur eine Testausgabe \n\r");
19
  Serial.print(x);
20
  Serial.println(" : end of program");
21
}
22
23
24
void setup() 
25
{
26
  Serial.begin(115200);
27
28
  tbox.x1= 12; tbox.y1= 0;
29
  tbox.x2= 40; tbox.y2= 10;
30
  tbox.txfieldattr= 0x70;
31
  tbox.upborderattr= 0xae;
32
  tbox.dwnborderattr= 0x2e;  
33
  
34
  ansi_txbox(&tbox);
35
}
36
37
38
void loop() 
39
{
40
}

von Arduino F. (Firma: Gast) (arduinof)


Lesenswert?

1
struct TxBox
2
{
3
  int x1, y1; //class/struct Point
4
  int x2, y2; //class/struct Point
5
  int upBorderAttr;
6
  int dwnBorderAttr;
7
  int txFieldAttr;
8
};
9
10
TxBox tbox 
11
{
12
  x1:  0,
13
  y1:  0,
14
  x2: 40,
15
  y2: 10,
16
  upBorderAttr:  0x70,
17
  dwnBorderAttr: 0xae,
18
  txFieldAttr:   0x2e
19
};
20
21
void ansiTxBox(const TxBox &box)
22
{
23
  int x; 
24
  
25
  x= box.x1;
26
  Serial.println("\n\r Nur eine Testausgabe \n\r");
27
}
28
29
void setup() 
30
{
31
  Serial.begin(115200);
32
  ansiTxBox(tbox);
33
}
34
35
void loop() 
36
{
37
}

von Klaus H. (klummel69)


Lesenswert?

Zu stdint.h:

Ich kenne keinen einzigen C Compiler der diese Header Datei nicht hat. 
Selbst uralte Dinger haben das.

Ist ja keine Änderung am Compiler sondern eine einfache Header Datei die 
halt an den Compiler/Architektur angepasst wird.

: Bearbeitet durch User
von Rolf (rolf22)


Lesenswert?

> Das ist mir aber nun wirklich neu, dass man keine Zeiger
> verwenden soll !

Du hast anscheinend noch kein Lehrbuch über C++ gelesen. Sonst wüsstest 
du, dass man in C++ die von C geerbten "rohen" Zeiger nur in bestimmten 
Fällen nutzt. Ansonsten nimmt man die sogenannten Smart Pointer.

Und du wüsstest dann auch, dass man deinen Beispielcode ganz einfach 
ohne Zeiger schreiben kann, ohne ihn länger oder unübersichtlicher zu 
machen. Der Zeiger dort ist völlig überflüssig: Es geht auch mit einer 
Referenz.
Hier zeigt dir das ein Profi:
Beitrag "Re: Arduino und struct gefallen sich nicht !"

von Arduino F. (Firma: Gast) (arduinof)


Lesenswert?

Klaus H. schrieb:
> Ich kenne keinen einzigen C Compiler der diese Header Datei nicht hat.
Es dreht sich doch gar nicht um die Datei selber, sondern eher darum was 
da drin steht!

CHAR_BIT aus limits.h sagt dir wieviel Bit ein char hat.
Wenn ungleich 8, dann gibts auch kein uint8_t.
Früher recht üblich, dass es sowas gab.
Und ist für die Zukunft nicht ausgeschlossen.
Weder C noch C++ legen sich da fest.

von Kilo S. (kilo_s)


Lesenswert?

Nick schrieb:
> Wenn man uint8_t noch nicht kennt...

Ist kein FW blob, keine Rohdaten, keine Register Map.

Warum sollte ich zur Ausgabe per UART konvertieren wollen?

Kein strlen möglich!

Arduino F. schrieb:
> Naja...
> Wenn Arduino/C++ dann doch eher:

Weil const auch mit älteren Cores funktioniert. ;-)

von Arduino F. (Firma: Gast) (arduinof)


Lesenswert?

Ralph S. schrieb:
> Das ist mir aber nun wirklich neu, dass man keine Zeiger verwenden soll

Die C Zeigerwirtschaft ist ein steter Quell von üblen Effekten.
Memory leaks
Bereichsüberschreitungen
Endlose Debugsitzungen
usw.

Wenn man Zeiger vermeiden kann, dann sollt man das auch tun.
C++ bietet da deutlich bessere Möglichkeiten, als C.
Das erleichtert das Leben ungemein.

: Bearbeitet durch User
von Nick (b620ys)


Lesenswert?

Kilo S. schrieb:
> Kein strlen möglich!

Steht ja auch kein x00 in deinem Beispiel mit lauter hex-zahlen.

Kilo S. schrieb:
> Ist kein FW blob, keine Rohdaten, keine Register Map.

Aber integers in deinem Beispiel.
Eventuell könntest du ja auch "https://tinyurl.c*m/4h4mvdre"; schreiben. 
Könnte leserlicher sein. Die \n \r schenk ich dir zu dem kostenlosen Tip 
noch mit dazu.

Kilo S. schrieb:
> Warum sollte ich zur Ausgabe per UART konvertieren wollen?

Da gibts nix zu konvertieren. Nochdazu gibst du deine Daten in Bytes an 
um Platz zu sparen. Um das sicherzustellen, dass tatsächlich Platz 
gespart wird, verwendet man uint8_t. Die Größe von char ist 
implementationsabhängig, uint8_t ist garantiert ein Byte groß.

Genial ist dein Schachzug zuerst einen String in hex zu wandeln und dann 
zu merken, dass strlen nicht funktioniert, stattdessen sizeof verwenden 
zu müssen und dann Zeichen für Zeichen in die UART zu schubsen.

von Hans W. (hanswieland)


Lesenswert?

Arduino F. schrieb:
> uint8_t ist ein optionaler Datentype.
> Steht nicht auf allen Plattformen zur Verfügung.

Ich hake nochmal nach: Nenne bitte ein nachvollziehbares Beispiel aus 
diesem Jahrtausend.

von Alexander (alecxs)


Lesenswert?

Nick schrieb:
> Aber integers in deinem Beispiel.
> Eventuell könntest du ja auch "https://tinyurl​.com/4h4mvdre"; schreiben.
> Könnte leserlicher sein.

Du hast nicht verstanden worum es ging. Das ist auch gar nicht das 
original.

von Arduino F. (Firma: Gast) (arduinof)


Lesenswert?

Nick schrieb:
> stattdessen sizeof verwenden
> zu müssen und dann Zeichen für Zeichen in die UART zu schubsen.

sizeof ist auch oft ein Ort für vertippsler.

Seit C++11 kann man den "range based for loop" verwenden.

Oder per constexpr Template Funktion die Array Größe ermitteln.

: Bearbeitet durch User
von Hans W. (hanswieland)


Lesenswert?

Rolf schrieb:
> Und du wüsstest dann auch, dass man deinen Beispielcode ganz einfach
> ohne Zeiger schreiben kann, ohne ihn länger oder unübersichtlicher zu
> machen. Der Zeiger dort ist völlig überflüssig

Letztendlich sind Referenzen nur eine Variante von Zeigern, und im 
Maschinencode sogar exakt das Gleiche, egal wie sehr fragwürdige 
Lehrbücher das zu leugnen versuchen. Man hat aus einigen Ideen eine 
krampfhafte Lehre gemacht. Zum Glück muss sich niemand daran halten. Und 
nein, Arduino ist keine Gotteslästerei.

Lest mal Bücher von Bjarne Stroustrup nach dem Jahr 2000. Er geht mit 
seiner eigenen Arbeit nachträglich viel entspannter um, als so mancher 
seiner Jünger.

: Bearbeitet durch User
von Arduino F. (Firma: Gast) (arduinof)


Lesenswert?

Hans W. schrieb:
> Letztendlich sind Referenzen nur eine Variante von Zeigern,

Nun ja...
Mit Zeigern kann man deutlich eher dumme Fehler einbauen.

Zudem kann man bei Übergabe per Referenz die Arraygröße im Datentype 
übergeben.
Dieses geht bei der Übergabe per Zeiger verloren.

: Bearbeitet durch User
von Nick (b620ys)


Lesenswert?

Alexander schrieb:
> Das ist auch gar nicht das original.

Er hat es als seinen code gepostet.

Arduino F. schrieb:
> sizeof ist auch oft ein Ort für vertippsler.

Was man nicht alles flasch schreiben kann, wenn man muss.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.