Arduino und struct gefallen sich nicht !

#8022365
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?

#8022374
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.

Persönliche Seite #8022380
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.

#8022383
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.

(Firma: Gast) #8022385
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.

#8022398
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".

#8022399
Lesenswert?

Hallo, Nick schrieb im Beitrag #8022387:

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

#8022404
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.

#8022423
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/

Persönliche Seite #8022427
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.

#8022434
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?

#8022442
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.

Angehängte Dateien:
: Bearbeitet durch User
#8022444
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.

#8022452
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!

#8022467
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.

(Firma: Gast) #8022475
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.

Beitrag #8022487 wurde vom Autor gelöscht.
#8022493
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.

(Firma: Gast) #8022512
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
#8022532
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
}
#8022535
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.

#8022556
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).

#8022558
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.

#8022563
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.

#8022564
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
}
(Firma: Gast) #8022565
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
}
#8022575
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 !"

(Firma: Gast) #8022576
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.

(Firma: Gast) #8022583
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
#8022601
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.

#8022612
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
#8022652
Lesenswert?

Nick schrieb:

Könnte leserlicher sein.

Das war kurz da hin gerotzt um bei dem Witz zu bleiben.

Hab Gerade gedanklich noch dem RDP1 vom PY32F002A im Hinterkopf und finde es erfrischend nebenher immer mal wieder an der Feelin Vape weiter zu machen. Dump war ja einfach, nach dem ich endlich den blöden Reset am China JLink gefunden habe.

Alexander schrieb:

Du hast nicht verstanden worum es ging.

Ich kenn ihn auch nur halb, hab trotzdem genug Humor um mal mit zu blödeln.

(Firma: Gast) #8022677
Lesenswert?

Ralph S. schrieb:

nach dieser Methode kann ich aber die Members der Struct im Programm nicht mehr ändern

Natürlich geht das!

C++ generiert für dich eine Handvoll Konstruktoren und Operatoren. Automatisch, für jede Struktur und Klasse, wenn du das nicht unterbindest, kannst du diese nutzen.

Angehängte Dateien:
: Bearbeitet durch User
(Firma: Gast) #8022771
Lesenswert?

Ralph S. schrieb:

hier geht es glaube ich grundsätzlich um Mißverständnisse... so irgendwie ...

Verstehe ich nicht! Ich dachte es geht um Strukturen im Arduino Umfeld.

Aber wenn du meinst.

Nachtrag: Wenn du Missverständnisse siehst, dann möchte ich dich bitten diese aufzulösen, wenn möglich. Oder wenigstens klar benennen.

: Bearbeitet durch User
#8022776
Lesenswert?

Kilo S. schrieb:

Das war kurz da hin gerotzt um bei dem Witz zu bleiben.

Kilo S. schrieb:

spi_write_byte(CMD, 0xB0); spi_write_byte(DATA, 0xC0); // Interface mode spi_write_byte(CMD, 0xB2); // FRMCTR2 - Frame rate normal mode spi_write_byte(DATA, 0x24); spi_write_byte(CMD, 0xB3); // FRMCTR3 - Frame rate partial mode spi_write_byte(DATA, 0x03); spi_write_byte(CMD, 0xB7); // ETMOD - Entry mode spi_write_byte(DATA, 0x01); spi_write_byte(CMD, 0xB6); // DISSET5 - Display function control spi_write_byte(DATA, 0x19); spi_write_byte(CMD, 0xAC); spi_write_byte(DATA, 0xDB);

undsoweiter ...

Ist das dann auch Rotz oder ist es ein Witz? Ich hab den Eindruck, dass du beim schreiben nur wenig nachdenkst.

#8022782
Lesenswert?

Nick schrieb:

undsoweiter

Dich zu ignorieren wird jedenfalls helfen das ich weniger Mordgelüste hab! Mann die Menscheit ist so derbe am Arsch wenn nur noch so Leute wie du rumlaufen!

Reiß das nicht aus dem Zusammenhang, deine Möchtegern Konstruktion die du hier starten willst kannste dir als Zäpfchen verabreichen!

WAS STEHT OBEN ÜBER DEM CODE?!

Dissasembly lesen und vernünftig rekonstruieren ist nicht meine größte Stärke, vor allem weil ich nur sporadisch weiter mache wie ich gerade Zeit habe. Der erste Versuch (Grundlagen) war noch mit Forenhilfe, schon ne Weile her, dafür hab ich mich allerdings ganz gut erinnern können was ich versuchen kann und muss.

Und wenn überhaupt, kaper hier nicht mit dem Code der Nevoks Feeling Vape den Thread!

Und wenn du dort schreibst, Konstruktive Sachen, mach einen auf Oberlehrer und du kannst gleich weg bleiben!

#8022785
Lesenswert?

Harald K. schrieb:

Ralph S. schrieb:

nach dieser Methode kann ich aber die Members der Struct im Programm nicht mehr ändern

Was soll das heißen? Weißt Du nicht, wie's geht, oder gibt der Compiler Fehlermeldungen aus?

Arduino F. schrieb:

Verstehe ich nicht! Ich dachte es geht um Strukturen im Arduino Umfeld. Aber wenn du meinst. Nachtrag: Wenn du Missverständnisse siehst, dann möchte ich dich bitten diese aufzulösen, wenn möglich. Oder wenigstens klar benennen.

doch, ich weiß wie es geht (Schreibfehler bitte entschuldigen, sitze im Auto auf dem Handy). Der letzte Programmpost von Arduino F. ist genau das, wie ich das zuvor auch gemacht hatte und es aufgrund von dämlichen Syntaxfehler von mir Compilerfehler gab. Dann gings hier ab wie Schmidts Katze und es waren zu viele Posts auf einmal, während ich noch am programmieren war... nicht an der Struktur, sondern an den Funktionen selbst. Hm, heute abend vllt. so ein Zwischenpost von dem, an dem ich gerade bin... Schmunzeln muß, das ganze nur deshalb, weil in einem anderen Tread es um Steuerzeichen cr und lf ging... und welches Terminal... hrmpf.. Aber: Arduino F. und Kirnbichler waren sind schon / zielführend (oft) und im Fall hier jetzt war Arduino F. der Experte

#8022953
Lesenswert?

na ja. :-) C mach ich seit 1985... C++ irgendwann mitte 90er... Das Schlimme ist das permanente wechseln der Sprache, weil dazwischen auch immer wieder mal Delphi rutscht... und im moment auch noch Javascript. Viele Köche verderben den Brei. Für Arduino bin ich ein Anfänger, wie bei vielen Frameworks eine Flut von Dateien... Aaaaber so n kleines bischen versteh ich die Philosophie dahinter. Hmmm, ich bin mal gespannt, was ihr zu meinem Zwischenprojekt, wenn man das so sagen kann, sagen werdet. Und alles nur, um mit Arduino Ausgaben auf einem Terminal zu machen.

(Firma: Gast) #8023010
Lesenswert?

Ralph S. schrieb:

C mach ich seit 1985

Kommt bei mir auch so in etwa hin Bin mit "SCO Xenix 286" in die C/Unix Welt gestolpert. Später dann "DG/UX"

Ralph S. schrieb:

Für Arduino bin ich ein Anfänger

Zu Arduino bin ich eher durch Zufall gekommen. Ein Freund brauchte eine kleine Ablaufsteuerung. Wusste dass ich viel mit SPS gemacht habe, genauer "PS4 201 MM1". Hatte noch eine liegen und habe ihm den Preis genannt. Er ist auf den Rücken gefallen. Dann in den Keller gerannt, mit den Worten "Ich habe da noch was!" Ein misslungenes Geburtstagsgeschenk für/von seinem Ableger. Der ist damit nicht warm geworden.

Ein Arduino UNO Starter Kit. Mit Taster Kabel Relais und Hundert weiterem Rödel.

Nach ca 1 Stunde liefen die ersten Beispiele. Nach ca 2 weiteren Stunden, war seine Ablaufsteuerung, noch rudimentär, aber funktionsfähig. Und ich, entgegen meiner anfänglichen Vorbehalte: Begeistert!

#8023296
Lesenswert?

Rahul D. schrieb:

Dann solltest du dir zur weiteren Verwirrung noch python antun. ;)

mag ich schon aufgrund der Einrückungen per Whitespaces nicht... und von daher glaube ich, dass ich mit Computersprachen gut bedient bin. Allerdings: wenn es irgendwann notwendig sein sollte, dann werde ich mich wohl auch noch mit Python beschäftigen.... aber vorerst einmal nicht!

#8023306
Lesenswert?

Ralph S. schrieb:

mag ich schon aufgrund der Einrückungen per Whitespaces nicht...

In jeder halbwegs akzeptablen Programmiersprache rückt man ein, um sein strukturiertes Ansinnen zu verdeutlichen. Python forciert dieses an sich sinnvolle Verhalten.

Aber ich gebe es gerne zu, auch ich habe die ersten zwei** Minuten der darauf folgenden vielen Tausenden von Stunden gemeckert und mir Gründe aus den Fingern gezogen warum ausgerechnet dies nun schlecht sein soll. ;-)

** Könnten auch zwanzig Minuten gewesen sein.

#8023310
Lesenswert?

Norbert schrieb:

In jeder halbwegs akzeptablen Programmiersprache rückt man ein, um sein strukturiertes Ansinnen zu verdeutlichen.

Das gilt als guter Stil, den manche gar nicht mögen.

Norbert schrieb:

Python forciert dieses an sich sinnvolle Verhalten.

Klingt nicht sehr überzeugt.

Aber ich gebe es gerne zu, auch ich habe die ersten zwei** Minuten der darauf folgenden vielen Tausenden von Stunden gemeckert und mir Gründe aus den Fingern gezogen warum ausgerechnet dies nun schlecht sein soll. ;-)

Wenn man aus der C/C++/C#-Ecke oder von einer anderen Programmiersprache mit Semikolon am Ende kommt, ist es etwas gewöhnungsbedürftig.

Moderator #8023353
Lesenswert?

Norbert schrieb:

Rahul D. schrieb:

Wenn man aus der C/C++/C#-Ecke oder von einer anderen Programmiersprache mit Semikolon am Ende kommt, ist es etwas gewöhnungsbedürftig.

Kam' ich. Plus Assembler. Plus, plus,… Mindestens zwanzig Jahre lang.

Isses nicht wirklich. Man lässt es einfach weg.

Oder man lässt es dran. Python ist diesbezüglich gegenüber Umsteigern sehr tolerant ;-)

#8023354
Lesenswert?

Norbert schrieb:

Kam' ich. Plus Assembler. Plus, plus,… Mindestens zwanzig Jahre lang.

Ja, und dann definiert man eine Funktion in einer Klasse und wundert sich, dass deren Aufruf einen Fehler wirft: Bei jeder klammerorientierten Programmiersprache wäre die Einrücktiefe egal. Hier war die Funktion Teil einer anderen Funktion. Also alles einen Tab zurücksetzen, damit sie eine Methode innerhalb der Klasse und nicht einer anderen Methode ist. Wer's mag... (oder frei nach Else Kling: "Wenn's schee macht!?")

#8023371
Lesenswert?

Norbert schrieb:

Die einen machen's selbst, die anderen verlassen sich auf ihre IDE.

Oder der Compiler wirft einen Error, dass die öffnende Klammer nicht geschlossen wurde.

Da kann man dann auch gleich Assembler mit Schaltern programmieren und das EPROM regelmäßig ins Löschgerät packen. Been there, done it, diddn't like it.

Auch, wenn ich mit python so langsam zurecht komme, bis ich die mag, wird es noch dauern. Wenn Niederländer eine Programmiersprache entwickeln... ich habe die Vermutung, dass das in einem Coffee-Shop passierte.

: Bearbeitet durch User
#8023385
Lesenswert?

Falk B. schrieb:

Structs KANN man als Wert (call by value, KOPIE!) oder als Zeiger auf das Objekt (call by reference) als Parameter übergeben.

Das Wort "Zeiger" kann sehr leicht zu Missverständnissen führen, weil es eine Übersetzung von "pointer" ist. Referenzen und Pointer sind aber zwei Paar Schuhe:

1
#include <iostream>
2

3
struct myStruct { int a; int b; };
4

5
void foo1(myStruct  eins) { std::cout << "value     " << eins.a  << '\n'; }
6

7
void foo2(myStruct& zwei) { std::cout << "reference " << zwei.a  << '\n'; }
8

9
void foo3(myStruct* drei) { std::cout << "pointer   " << drei->a << '\n'; }
10

11

12
int main()
13
{  myStruct s = { 33, 44 };
14

15
   myStruct* ptr_s = &s;    
16

17
   foo1(s);
18
   foo2(s);
19
   foo3(ptr_s);
20
   foo3(&s);
21
   //foo3(s&); // Fehler
22
   //foo3(*s); // Fehler
23
   //foo3(s*); // Fehler
24
   
25
    return 0; 
26
}
27

28
// Ergebnis:
29
//value     33
30
//reference 33
31
//pointer   33
32
//pointer   33
: Bearbeitet durch User
#8023416
Lesenswert?

Rahul D. schrieb:

Man kann sich alles schönreden. Man sollte halt bei der Formatierung konsequent sein.

Das gilt umgekehrt aber genauso. Klar, ist nach einer copy'n'paste Aktion noch nie jemandem passiert… Semikolon am Ende einer ›for‹ Schleife und danach schön eingerückt? Klar, ist noch nie jemandem passiert…

Man kann sich in jeder Sprache ins Bein schießen und es nicht sehen. Oder erst wenn es blutet. Nennt sich expectation bias.

#8023428
Lesenswert?

Norbert schrieb:

Man kann sich in jeder Sprache ins Bein schießen und es nicht sehen. Oder erst wenn es blutet. Nennt sich expectation bias.

Was bei klammerorientierten Sprach noch ganz angenehm ist: Man kann Klammer dazu benutzen, Blöcke zu defininieren, auch wenn das gar nicht notwendig ist. Aber die "Diskussion" hat zu viel philosophisches. Ich mag sie nicht, und wie Arduion Fanboy, werde ich mit ihr nicht wirklich warm. Jeder wie er mag.

Persönliche Seite #8023445
Lesenswert?

Oliver S. schrieb:

Arduino F. schrieb:

Referenzen können nicht Null werden. Damit fängts schon an.

Ja, aber das ist auch der einzige Unterschied.

Gibt schon noch mehr. Beispielsweise kann man ein Array von Pointern haben aber kein Array von Referenzen.

Einem Zeiger kann man einen neuen Wert zuweisen, einer Referenz nicht etc.

: Bearbeitet durch User
#8023448
Lesenswert?

Oliver S. schrieb:

Arduino F. schrieb:

Was soll der Unsinn? Referenzen können nicht Null werden. Damit fängts schon an.

Ja, aber das ist auch der einzige Unterschied. Der Rest ist syntactical sugar.

Oliver

Hallo Oliver und auch Hans W.,

nein. Mit syntaktischen Zucker, was man deutsch schreiben darf, sollte man das nicht so lässig abtun. Bsp. kann man den Adresswert in der Zeigervariable defaultmäßig ändern. Das referenzierte Objekt o.ä. einer Referenzvariable dagegen nicht. Da es mit C++ primär um Datenkapselung und Sicherheit geht, sollte eine Referenz Vorrang haben. Das Gehampel mit dem expliziten Dereferenzierungsoperator fällt auch weg. Der gesamte Umgang ist mit Referenzen einfacher und damit weniger bis kaum Fehleranfällig. Allein schon deswegen ...

: Bearbeitet durch User
#8023455
Lesenswert?

Oliver S. schrieb:

Referenzen können nicht Null werden. Damit fängts schon an.

Ja, aber das ist auch der einzige Unterschied.

Pointer sind Variablen mit Typ und Speicherplatz, den man im Maschinencode sieht. Referenzen haben keinen Speicherplatz und treten im Maschinencode gar nicht auf.

Der Rest ist syntactical sugar.

Logik? Rest? Sobald es mindestens einen Unterschied gibt, den man im Maschinencode sehen kann, ist das Ganze kein syntactical sugar.

Klar, der Optimierer kann in manchen(!) Fällen den Unterschied wegoptimieren. Das ist hier aber nicht das Thema.

#8023462
Lesenswert?

Johann L. schrieb:

Gibt schon noch mehr. Beispielsweise kann man ein Array von Pointern haben aber kein Array von Referenzen.

Das ist eine direkte Folge dessen, dass es das Null-Element nicht gibt (bzw. eine Referenz nicht default-constructible ist).

Johann L. schrieb:

Einem Zeiger kann man einen neuen Wert zuweisen, einer Referenz nicht etc.

Aber sicher geht das.

Arduino F. schrieb:

Bei Übergabe per Pointer geht die Arraygröße verloren. Muss man händische als 2ten Parameter nachreichen. Eine üble Fehlerquelle. Bei Referenzen steckt die Arraygröße im Datentype.

1
#include <iostream>
2
#include <type_traits>
3

4
void foo(auto ar)
5
{
6
    std::cout << std::is_same<decltype(ar), int(*)[3]>::value << std::endl;
7
    std::cout << sizeof(*ar) << std::endl;
8
}
9

10

11
int main()
12
{
13
    int arr[3];
14
    foo(&arr);
15
}

;)

Rolf schrieb:

Pointer sind Variablen mit Typ und Speicherplatz, den man im Maschinencode sieht. Referenzen haben keinen Speicherplatz und treten im Maschinencode gar nicht auf.

1
#include <iostream>
2

3
int main()
4
{
5
    int x = 3;
6
    int& r = x;
7

8
    std::cout << sizeof(r) << std::endl;
9
}

Oliver

#8023469
Lesenswert?

Rolf schrieb:

Logik? Rest? Sobald es mindestens einen Unterschied gibt, den man im Maschinencode sehen kann, ist das Ganze kein syntactical sugar.

https://godbolt.org/z/YefnEerdd

Dann such mal den Unterschied...

Veit D. schrieb:

Mit syntaktischen Zucker, was man deutsch schreiben darf, sollte man das nicht so lässig abtun. Bsp. kann man den Adresswert in der Zeigervariable defaultmäßig ändern. Das referenzierte Objekt o.ä. einer Referenzvariable dagegen nicht.

Das ändern des Wertes einer Zeigervariablen und das ändern des referenzierten Objekts sind aber zwei völlig verschiedene Dinge. Den "Wert" einer Referenz kann man durch zuweisen eines anderen referenzierten Objekts auch ändern.

Da es mit C++ primär um Datenkapselung

und Sicherheit geht, sollte eine Referenz Vorrang haben. Das Gehampel mit dem expliziten Dereferenzierungsoperator fällt auch weg. Der gesamte Umgang ist mit Referenzen einfacher und damit weniger bis kaum Fehleranfällig. Allein schon deswegen ...

Da bin ich voll bei dir. Raw pointer kann und sollte man vermeiden. Das entkräftet dann auch das Argumemnt, daß ein pointer die Größeninformation eines Array nicht enthält. Auch Array sind letzendlich raw pointer. Dafür nimmt man besser std::vector.

Oliver

#8023489
Lesenswert?

Oliver S. schrieb:

1
> #include <iostream>
2
> 
3
> int main()
4
> {
5
>     int x = 3;
6
>     int& r = x;
7
> 
8
>     std::cout << sizeof(r) << std::endl;
9
> }
10
>

Ausgegeben wird 4, sieht aus wie die Größe eines Pointers? Machen wir vorsichtshalber mal eine andere Probe:

1
#include <iostream>
2
int main()
3
{
4
    char x = 'A';
5
    char& r = x;
6
    
7
    std::cout  << sizeof(r);
8
}

Da erscheint 1 als Ergebnis, also steht r nicht für einen Speicherplatz, in dem ein Pointer PLatz hätte.

#8023498
Lesenswert?

Nee, da wird die Größe der referenzierten Variable ausgegeben, das ändert aber nichts daran, daß Referenzen „under the hood“ nichts anders als Pointer sind.

Oliver S. schrieb:

Johann L. schrieb:

Einem Zeiger kann man einen neuen Wert zuweisen, einer Referenz nicht etc.

Aber sicher geht das.

Um das noch etwas zu präzisieren: „natürlich“ war natürlich etwas überspitzt. Seit C++20 ist das möglich, von hinten durch die Brust ins Auge, mit placement new. Ist aber irgendwie ein unschöner Hack, auch wenns kein UB ist.

Näheres hier: https://stackoverflow.com/questions/7181372/why-can-i-assign-a-new-value-to-a-reference-and-how-can-i-make-a-reference-refe

Ob mans im realen Leben braucht? Wohl eher nicht.

Oliver

#8023546
Lesenswert?

Oliver S. schrieb:

Nee, da wird die Größe der referenzierten Variable ausgegeben

Eben, und deshalb hat dein Beispiel nicht das bewiesen, was du beweisen wolltest.

das ändert aber nichts daran, daß Referenzen „under the hood“ nichts anders als Pointer sind.

"Unter der Haube" kann vieles bedeuten. Die Frage ist, wer wann was tut.

Bei Zeigervariablen wird die Verbindung zum referenzierten Objekt im Normalfall erst zur Laufzeit hergestellt, also dynamisch zum Zeitpunkt des Zugriffs. Zur Übersetzungszeit ist der Inhalt einer Zeigervariable im Allgemeinen unbekannt. Bei Referenzen stellt der Compiler die Verbindung schon zur Übersetzungszeit her. Anders gesagt, die Adresse des Zielobjekts ist dem Compiler bekannt, sie muss nicht erst zur Laufzeit durch Auslesen einer Zeigervariablen beschafft werden.

Zwar kann man das Ziel einer Referenz umdefinieren, aber das passiert dann genau dort, wo es im Quelltext steht. Deswegen braucht man dafür keinen speziellen Speicherplatz für einen Zeiger, wie man ihn für eine Zeigervariable braucht.

#8023570
Lesenswert?

Oliver S. schrieb:

Das ändern des Wertes einer Zeigervariablen und das ändern des referenzierten Objekts sind aber zwei völlig verschiedene Dinge. Den "Wert" einer Referenz kann man durch zuweisen eines anderen referenzierten Objekts auch ändern.

Hallo Oliver,

ich denke wir reden etwas aneinander vorbei.

1
#include <iostream>
2
using namespace std;
3

4
int var1 {16};
5
int var2 {32};
6

7
int main()
8
{
9
  // --- mit Referenz --- //
10
  cout << "--- mit Referenz ---" << endl;
11
  int &refVar {var1};
12
  cout << "var1   " << var1 << endl;
13
  cout << "refVar " << refVar << endl;
14
  refVar = var2;
15
  cout << "refVar " << refVar << endl;
16
  //refVar = &var2;   // Error
17

18
  // Ausgangszustand herstellen //
19
  var1 = 16;
20
  var2 = 32;
21

22
  // --- mit Zeiger --- //
23
  cout << "--- mit Zeiger ---" << endl;
24
  cout << "addr von var1 " << &var1 << endl; 
25
  cout << "addr von var2 " << &var2 << endl; 
26

27
  int *pRef {&var1};
28
  cout << "addr in pRef  " << pRef << "   Wert " << *pRef  <<  endl;
29
  pRef = &var2;
30
  cout << "addr in pRef  " << pRef << "   Wert " << *pRef  <<  endl;
31

32
  return 0;
33
}

Auch wenn der Unterschied in der Betrachtung banal erscheinen mag, er ist da. Eine Referenzvariable kann ich mit etwas (gleichem Datentyps) initialisieren und dann ist die Referenzvariable wegen ihrem Aliasnamen gleich der initialisierten Variablen oder Objekt o.ä. Zeile 11. Die Instanz, die Adresse, in Zeile 16 zu ändern geht.

Man kann der Referenzvariablen nur durch kopieren/übergeben von Werten andere Werte zuweisen. Aber die Referenzvariable bleibt in dem Bsp. var1 und wird nicht var2. Man arbeitet weiterhin mittels Referenzvariablen refVar immer noch im Namen von var1.

Bei Zeigern weise ich in Zeile 29 pRef die Adresse von var2 zu und ab dem Zeitpunkt arbeitet man sinnbildlich mittels pRef mit var2 und nicht mehr mit var1. Man ändert nicht nur irgendwelche Werte in var1, sondern man arbeiten mit einem anderen Objekt var2.

Das ist der Unterschied in der Betrachtung oder gar Bedeutung, aber der ist wichtig zu verstehen. Ansonsten ackert man mit der falschen Variablen weiter und will das gar nicht.

Edit: Natürlich kann man den gleichen Schutz mit Zeiger durch const

1
int* const pRef {&var1};

an der richtigen Stelle auch erreichen, nur ist das nicht "Default". :-) Und eben das Gehampel mit Dereferenzieren usw. bleibt bestehen. Bis ich das damals verstanden hatte, da verging viel Zeit. Arduino F. wird sich vielleicht erinnern. :-)

: Bearbeitet durch User
#8023580
Lesenswert?

Rolf schrieb:

"Unter der Haube" kann vieles bedeuten. Die Frage ist, wer wann was tut.

Schau dir doch einfach das oben verlinkte godbolt-Beispiel an. Da siehst du den erzeugten Assembler-Code.

Der C++-Standard schreibt „ It is unspecified whether or not a reference requires storage“

Spätestens, wenn die Reference ein Funktionsparameter ist, oder dynamischer Polymorphismus genutzt wird, gehts nicht ohne.

Oliver

#8024124
Lesenswert?

Norbert schrieb:

Ralph S. schrieb:

mag ich schon aufgrund der Einrückungen per Whitespaces nicht...

In jeder halbwegs akzeptablen Programmiersprache rückt man ein, um sein strukturiertes Ansinnen zu verdeutlichen. Python forciert dieses an sich sinnvolle Verhalten.

Exkurs: nicht nur das, die Kombination von Klammern {} und Einrückung ist vor allem redundant und insofern überflüssig. Trotzdem erlaubt Python auch eine Formatierung mit Semikola wie beispielsweise

1
import sys; sys.exit()

Aber ich gebe es gerne zu, auch ich habe die ersten zwei** Minuten der darauf folgenden vielen Tausenden von Stunden gemeckert und mir Gründe aus den Fingern gezogen warum ausgerechnet dies nun schlecht sein soll. ;-)

** Könnten auch zwanzig Minuten gewesen sein.

Man gewöhnt sich jedenfalls sehr schnell dran, insbesondere wenn der genutzte Editor das ordentlich unterstützt.

#8024242
Lesenswert?

Ein T. schrieb:

Oder beides. Such Dir einfach was aus.

Dich stört, dass jemand was gegen dein heiß geliebtes Python hat - dessen Meinung ist für dich demnach irrelevant, was du dadurch ausdrücken könntest, dass du solche Beiträge / Kommentare einfach ignorierst.

Ein T. schrieb:

Oder künstlich aufregen.

Was du ja offensichtlich gerne tust.

Wie schon mehrfach angegeben: "Diskussionen" mit dir sind überflüssig. Hast du schon mal irgendwas sachbezogenes beigetragen? Ein Problem hier gelöst?

: Bearbeitet durch User
#8024250
Lesenswert?

Alexander schrieb:

Hatte ich auch schon uint8_t does not name a type

1
stdint.h is a header file in the C standard library introduced in the C99 standard library section 7.18 to allow programmers to write more portable code by providing a set of typedefs that specify exact-width integer types, together with the defined minimum and maximum allowable values for each type, using macros
1
#include <stdint.h>

https://en.wikibooks.org/wiki/C_Programming/stdint.h

#8024254
Lesenswert?

Da Arduino aber nun C++ ist, ist der passende Header <cstdint>.

Und das Problem dahinter ist, daß der halt manchmal eh schon irgendwo in irgendwelchen Library-headern includiert ist, manchem halt nicht, und daß sich das mit verschiedenen toolchain schonmal ändert.

Mit dem Problem des TO hat das alles aber nun überhaupt nichts zu tun.

Oliver

#8024321
Lesenswert?

Rahul D. schrieb:

Ein T. schrieb:

Oder beides. Such Dir einfach was aus.

Dich stört, dass jemand was gegen dein heiß geliebtes Python hat -

Nö. Mich stört, daß der Betreffende jedes Mal das Maul aufreißen muß, wenn das böse P-Wort erwähnt wird. Mich stört, daß der Betreffende sich dabei jedes Mal auf einen der unwichtigsten Aspekte der Sache kapriziert. Und mich stört, daß sich jemand ernsthaft für einen guten Entwickler mit einer ernstzunehmenden Meinung hält, der sich an solchen Lächerlichkeiten hochziehen kann, und das ständig, jedes Mal, und immer und immer und immer wieder.

Wie schon mehrfach angegeben: "Diskussionen" mit dir sind überflüssig.

Ja, für Dich ist das sicher richtig. Ich habe ja immer Recht. Andere können sehr konstruktiv mit mir diskutieren, aber bei einem, der sich ständig und immer wieder an der Sache mit dem Whitespace hochzieht... mit Kleingeistern zu diskutieren, ist intellektuell anspruchslos und daher Zeitverschwendung.

Hast du schon mal irgendwas sachbezogenes beigetragen? Ein Problem hier gelöst?

Im Gegensatz zu Dir mache ich das sogar recht oft. Und jetzt zurück zum Thema, Du hast schon genug Threads mit Deiner Pythonophobie zuge^Wgeflutet.

#8024323
Lesenswert?

Arduino F. schrieb:

du mir verkaufen wolltest, dass mein OOP Code kein C++ ist.

Schwachsinn. Wie dumm ist das bitte? Wir reden von einer C++ Lib. Ich sage ich versteh das Abstraktionsniveau nicht mehr. Als Antwort kommt ich könnte doch C++ lernen.

Warum sind hier im Forum eigentlich immer die Leute die Experten die nicht sinnerfassend Zusammenhänge lesen können?

Ich schrieb doch ganz klar, Arduino Temp Dateien sind eine mögliche Ursache für nichtreproduzierbare Fehler. Nicht mehr und nicht weniger, nicht ob das hier zutrifft.

Offensichtlich können Tim T. (tim_taylor) und einige andere den Fehler nicht reproduzieren.

Ralph S. schrieb:

typedef struct

{

int x1, y1;

int x2, y2;

int upborderattr;

int dwnborderattr;

int txfieldattr;

} txbox_t;

txbox_t tbox;

Ralph S. schrieb:

txbox_t does not name a type.

Ralph S. schrieb:

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

typedef struct

{

int x1, y1;

int x2, y2;

int upborderattr;

int dwnborderattr;

int txfieldattr;

} txbox_t;

txbox_t tbox;

Ist der Fehler nun reproduzierbar oder nicht?

(Firma: Gast) #8024327
Lesenswert?

Alexander schrieb:

Ist der Fehler nun reproduzierbar oder nicht?

Der TO hat keinen testfähigen Code gepostet. Damit ist jeder Versuch den Fehler zu reproduzieren von Anfang an unmöglich.

Zudem lag der Code in einer *.ino Datei und unterliegt damit deiner heiß geliebten Überwachung. Deine temp Geschichte ist damit eine Nebelkerze. Ein dummer Versuch den Thread zu hijacken. Eine Blamage.

: Bearbeitet durch User
#8024333
Lesenswert?

Ein T. schrieb:

Nö. Mich stört, daß der Betreffende jedes Mal das Maul aufreißen muß, wenn das böse P-Wort erwähnt wird.

Das ich erwähnt habe.

Und mich stört, daß sich jemand ernsthaft für einen guten Entwickler mit einer ernstzunehmenden Meinung hält, der sich an solchen Lächerlichkeiten hochziehen kann, und das ständig, jedes Mal, und immer und immer und immer wieder.

Habe ich irgendwann mal behauptet, dass ich mich "ernsthaft für einen guten Entwickler" halte? Tue ich nicht. Meine Einstellung ist, dass es jemandanders gibt, der es besser kann als ich (z.b. die Kollegen im Büro nebenan).

Du springt doch sofort darauf an, wenn ich mal wieder über python herziehe bzw. es als mittelprächtiges Beispiel einer Programmiersprache verwende. Es gibt bessere. Das solltest du als "programmiertechnisches Super-GAU" ja bestens wissen (der Begriff stammt von einem Uni-Prof)-

Ein T. schrieb:

Im Gegensatz zu Dir mache ich das sogar recht oft. Und jetzt zurück zum Thema, Du hast schon genug Threads mit Deiner Pythonophobie zuge^Wgeflutet.

  1. Das Problem / Thema des Threads ist schon lange geklärt.
  2. Wenn ich meine "Pythonophobie" auslebe, stört das eher wenige - die lesen das kurz und scrollen dann weiter.
  3. der einzige, der sich dadurch getriggert fühlt und seine Übergriffigkeit loswerden muss, bist du.

Wenn dich meine Kommentare stören: Melde sie einfach!

#8024349
Lesenswert?

Norbert schrieb:

Du könntest das auch einfach sein lassen und mal still schweigen, dann störte es gar niemanden.

Ich habe Ralph nur vorgeschlagen, sich auch mit python zu beschäftigen. Dass das nicht so ganz ernst gemeint war, hat er zumindest verstanden (siehe Smilie)

Du bist doch auf Ralphs Aussage eingegangen: Norbert schrieb im Beitrag #8023306:

Aber ich gebe es gerne zu, auch ich habe die ersten zwei** Minuten der darauf folgenden vielen Tausenden von Stunden gemeckert und mir Gründe aus den Fingern gezogen, warum ausgerechnet dies nun schlecht sein soll.

Wo habe ich (in diesem Thread) geschrieben, dass ich die Sprache grundsätzlich schlecht finde? Ich finde sie gewöhnungsbedürftig, weil sie Sachen für notwendig erachtet, die bei anderen Sprachen nicht so relevant sind.

Ja, man kann sich an vieles gewöhnen: Rahul D. schrieb im Beitrag #8023371:

Auch, wenn ich mit python so langsam zurecht komme, bis ich die mag, wird es noch dauern.

#8024356
Lesenswert?

Rahul D. schrieb:

Habe ich irgendwann mal behauptet, dass ich mich "ernsthaft für einen guten Entwickler" halte? Tue ich nicht.

Und trotzdem bekommst Du Deine Missionierungsobsession nicht in den Griff.

Du springt doch sofort darauf an, wenn ich mal wieder über python herziehe bzw. es als mittelprächtiges Beispiel einer Programmiersprache verwende.

Du darfst Python gerne und jederzeit fundiert kritisieren. Was nervt, sind diese ständigen Wiederholungen des immer gleichen Mülls.

Es gibt bessere.

Nur für bestimmmte Anwendungsfälle, allgemein jedoch nicht.

#8024366
Lesenswert?

Warum wollt ihr Äpfel mit Birnen vergleichen; Python ist eine Scriptsprache und keine klassische Programmiersprache. Der Vorteil liegt ja gerade darin dass nichts für eine Zielplattform kompiliert werden muss. Bevor man anfängt Shellskripte und Batchdateien parallel zu pflegen dann lieber ein Python.py

#8024370
Lesenswert?

In der Tat unter Windows eine Fehlerquelle. Microsoft hat sich erdreistet eine dummy Python.exe in den Path mit aufzunehmen. Diese soll dann den Appstore öffnen. Funktioniert aber nicht wenn man den Appstore deinstalliert hat. Scripte laufen dann mit Returncode 0 ins Leere.

#8024884
Lesenswert?

Rahul D. schrieb:

Alexander schrieb:

Zielplattform kompiliert werden muss.

Den Interpreter namens "python" braucht man aber. Der ist zwar häufig vorinstalliert, aber das muss nicht immer der Fall sein. Und dann ist der Kunde aufgeschmissen, wenn er die Software selber installieren soll / will / muss.

Deine Aussage ist doch ein glatter Strohmann. Nichts ist einfacher wie eine Pythoninstallation. Das ist einfacher wie Office zu installieren.

#8025053
Lesenswert?

Veit D. schrieb:

Deine Aussage ist doch ein glatter Strohmann. Nichts ist einfacher wie eine Pythoninstallation. Das ist einfacher wie Office zu installieren.

oder den Unterschied bei der Anwendung von "als" und "wie" zu kennen? Was ist wohl einfacher: Erst einen Interpreter zu installieren, oder gleich eine .exe (bezogen auf MS Windows) zu starten?

#8025078
Lesenswert?

Rahul D. schrieb:

Den Interpreter namens "python" braucht man aber. Der ist zwar häufig vorinstalliert, aber das muss nicht immer der Fall sein. Und dann ist der Kunde aufgeschmissen

Für den Fall kannst du ihm über PyInstaller dann eine Exe machen 😁 Dann ist die alleine lauffähig.

Aber was hat das alles noch mit dem Thema dieses Threads zu tun?

: Bearbeitet durch User
#8025087
Lesenswert?

N. M. schrieb:

Für den Fall kannst du ihm über PyInstaller dann eine Exe machen 😁 Dann ist die alleine lauffähig.

Ich weiß. Dann kann ich aber auch gleich eine lauffähige Datei in einer anderen Programmiersprache erzeugen.

Aber was hat das alles noch mit dem Thema dieses Threads zu tun?

Nichts. Das eigentliche Thema ist schon lange abgeschlossen. Beitrag "Re: Arduino und struct gefallen sich nicht !"

#8025542
Lesenswert?

Alexander schrieb:

also noch mal auf deutsch für Christoph und Rahul (früher hat man sowas gegoogelt)

  • OP - Opening Post

  • EP - Eröffnungspost

  • TE - Threadersteller

  • TO - Thread Opener / Thread Owner

  • TS - Thread Starter

  • OP - Original Poster

Das war nicht die Frage, sondern, was du mit

Alexander schrieb:

Das Problem steht im OP, und wie es umschifft wurde auch.

meintestest. Das war auch gar keine Lösung, sondern Präsentation von gefährlichen Nichtwissen, die schon dicht an Arduino-Bashinng war.

#8025547
Lesenswert?

Also erstens bin ich ich nicht der TE, zweitens das Problem und die 'Lösung' (Workaround; deutsch 'umschifft') stehen sehr wohl im OP. Es steht sogar haarklein die Begründung im Text.

Ich wette ich kann es sogar reproduzieren. Damit habe ich Nichtwisser euch zwei Experten schon mal was voraus.

#8025550
Lesenswert?

Das muss ich gar nicht, da ich schon vor (meinen) KI-Zeiten ein ähnliches Problem hatte und mir die Begründung des TE bzgl. Eigenheiten der Arduino IDE sehr wohl vertraut ist.

Aber gute Idee, ich wette selbst eine KI kann das nachvollziehen, befrag sie doch direkt mal!

Ralph S. schrieb:

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

Dann lass Dir gleich noch im Arduino Quelltext zeigen wie die Reihenfolge genau ist. Dann ist hier ein für alle mal Ruhe.

: Bearbeitet durch User
#8026824
Lesenswert?

Alexander schrieb:

Aber gute Idee, ich wette selbst eine KI kann das nachvollziehen, befrag sie doch direkt mal!

Ralph S. schrieb:

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

Dann lass Dir gleich noch im Arduino Quelltext zeigen wie die Reihenfolge genau ist. Dann ist hier ein für alle mal Ruhe.

Nur mal so: es ist hier schon elendig lange "Ruhe" und das Thema hatte sich auch schon erledigt, gehabt, aber garantiert nicht wegen Dir, sondern schon eher von Arduino F. wegen.

Es ist unglaublich, wie sich hier immer und immer und immer wieder manche auf Kosten anderer profilieren wollen (oder glauben dieses tun zu müssen).

Warum auch immer habe ich mich in der letzten Zeit etwas mehr mit Arduino beschäftigt, als mir das lieb war und das alles nur, weil ich beschreiben will, wie mein Hardwareboard (mit CH32V003 und seriellem Bootloader) mit Arduino zusammenarbeiten kann (aber nicht muß)... und wie man mit bestimmten Gegebenheiten umgehen muß.

Wie gesagt, der Titel dieses Threads hier ist schon lange obsolet und, obwohl ich nicht so wirklich viel mit Arduino gemacht habe, glaube ich dennoch, dass ich darüber schon deutlich mehr weiß, als der Standardanwender.

Also, alle, die sich angesprochen fühlen: klopft euch mal selbst auf die Schulter und redet euch ein, wie toll und wie klasse ihr seid (jemand anderes wird das nicht tun). Die, die wirklich klasse und gut sind, werden sicherlich oft genug gelobt!


So, zum eigentlichen Thema will ich nicht wirklich zurück, aber das was ich hier jetzt präsentieren möchte ist genau wegen dieses Threads hier entstanden.

Mittlweile habe ich mich auch durch einen Teil des Dateien-Geflechts von Arduino gekämpft und weiß, wo ich bei bestimmten Dingen ansetzen müßte, wenn ich das denn umsetzen wollte.

Warum bspw. bei einem CH32V003 in :

~/.arduino15/packages/WCH/hardware/ch32v/1.0.4/variants/CH32V00x/CH32V003F4/variant_CH32V003F4.h

das hier steht:

1
/* ENABLE Peripherals */
2
// #define                         ADC_MODULE_ENABLED
3
#define                         UART_MODULE_ENABLED
4
// #define                         SPI_MODULE_ENABLED
5
#define                         I2C_MODULE_ENABLED

erschließt sich mir nicht. "unkommentiert" man den ADC, funktioniert auch analogRead in Arduino (zuvor eben nicht).

Ich wüßte mittlerweile auch, wo ich ansetzen müßte um HardwareSerial die Read-Funktionen zu implementieren, laß das aber, weil ich hier dann lieber ein eigenes Serial als Library habe (und einem Anfänger nicht zumuten möchte, den Core zu patchen).


Wie dem auch sei, waren die Diskussionen hier sehr hilfreich, wie ein Arduino-User bestimmte Dinge vorfinden mag (bspw. einen geerbten Stream), oder eben auch, wie hier gerne die funktion loop gesehen wird. Einiges respektriere ich so und übernehme das auch so, bei anderen Dingen bin ich dann halt manchmal anderer Meinung.

Und weil in einem anderen Thread sogar moniert wurde, dass ein \n\r nicht richtig sei (obwohl das von mir sogar ganz bewußt so eingesetzt wird.... mit allen Mikrocontrollern die ich verwende), nur weil die User scheinbar noch nie eine Terminalemulation wie PuTTY, minicom oder TeraTerm verwendet haben.

Weil ich gerne bestimmte Dinge (und nein, ich kann auch mit OpenOCD umgehen) dann einfach nur auf die Schnelle auf einem Terminal ausgeben mag um korrekte Funktionsweise zu überprüfen, ist es mitunter hochangenehm, wenn man im Terminal Farben verwenden und den Textcursor positionieren kann.

Hierfür ist dann der "serielle Monitor" von Arduino (man möge es mir verzeihen, das soll kein Bashing sein) dann wirklich allerübelster Schrott und es hätte der Arduino-IDE gut zu Gesicht gestanden, hier ein halbwegs vernünftiges Terminal zu integrieren.

Hier ist also mal das Ergebnis (und smile, ich schreibe das von meinem Urlaub aus in einem südlichen Land) für solche Ausgaben, die mit unterschiedlichen Controllern, namentliche Arduino-nano, STM32F411 Nucleo und Eigenbau CH32V003 getestet sind und doch tatsächlich auf allen gleich funktionieren.

Es dreht sich hier um eine Ausgabemöglichkeit mittels ESC-Sequenzen auf einem Terminal (meistens eine Terminalemulation), die weit weniger aufwändig (aber auch weniger leistungsfähig) ist als ein mcurses von Frank M.(ukw) https://www.mikrocontroller.net/articles/MCURSES und zudem auch eben noch aus Arduino heraus funktioniert.

Es würde mich sehr freuen, wenn ihr konstruktive Kritik an meinen Dateien üben würdet, insbesondere von Arduino F. / Veit / Kirnbichler würds mich sehr freuen. Allerdings kann ich natürlich nicht erwarten, dass ihr euch diese Menge auch ansehen werdet.

Für alle anderen: es kann durch aus richtig Spaß machen, mit den Ansi-Sequenzen auf Arduino zu spielen.

Viele Grüße, Ralph

#8026869
Lesenswert?

Alexander schrieb:

Hast Du Dich im Thread vertan? Der ist hier

Beitrag "Re: CH32V003 und Arduino"

nein, habe ich nicht. Dort hätte es zwar auch gepasst, aber die Library hier jetzt funktioniert mit jedem Controller für den es einen Arduino-Core und ein HardwareSerial gibt (und ist von daher genau eines nicht: CH32V003 spezifisch!).

Hier hätte ich jetzt eher eine Aussage erwartet wie: Warum hast du die msgbox und die txtbox nicht als eigenständige Klassen gemacht und die entsprechenden Methoden vererbt: Einzig, weil es dann irgendwann "unübersichtlich" wird und es einen Overhead produziert, der für kleine bis sehr kleine Controller garantiert kontraproduktiv ist.


Ähem Alexander, hast du in irgendeinem Thread auch irgendetwas konstruktives beizutragen ?

#8026878
Lesenswert?

Alexander schrieb:

War das nicht konstruktiv genug\n\r

Das war eine Anmerkung von dir, die MIR zeigt, dass es manche Leute hier gibt, die xzy (zensiert) und dann abc (genauso zensiert) ... und überhaupt zensiert ist.

Kurz: du hast schlicht überhaupt keine Ahnung und weißt nicht, dass es außerhalb des Tellerrandes weitergeht, denn es gibt noch etwas anderes als schlicht nur den seriellen Monitor von Arduino ... und du hast auch mit keiner Faser verstanden, für was das ist und warum bspw. PuTTY standardmäßig es trennt, dieses LF und CR (oder eben auch \n \r) ... und es überhaupt keine Rolle spielt, ob es zuerst eine neue Zeile gibt und dann an den Anfang der Zeile gesprungen wird, oder ob zuerst an den Anfang einer Zeile gesprungen wird und dann eine neue Zeile.

Dort hatte ich auch dargelegt, dass es absolut ABSICHT ist ... also ist dein Minieinwand, dass etwas von dir konstruktiv ist absolut daneben. Erst nix verstehen, dann sich selbst als Experten darstellen und überhaupt noch nichts gezeigt haben. Ich bitte dich: verschone mich mit deinen Expertenaussagen.


@Arduino F. ich muß etwas schmunzeln, weil ich angenommen habe, dass du gefühlt 100 Vorschläge machen könntest. Wäre nett, wenn du mal den größten nennen würdest.

Beim Schreiben habe ich mir vieles überlegt, wie man etwas machen könnte. Wie gesagt könnte man bspw. aus den Elementen aus AnsiOut eigene Klassen herstellen. Das hätte dann den Vorteil, dass es kein struct benötigen würde, weil das dann schlichtweg Variable der Klasse wären.

Außerdem ist es etwas "gefährlich", die Farbnamen so zu beschreiben wie ich das gemacht hab (obwohl du dann schon zugeben mußt, dass ich wenigstens constexpr gemacht habe).

Und ich gebe zu, dass es wohl doch ein "arger" Mix aus C und C++ ist (und ich bin immer noch kein Freund von C++ auf kleinen Mikrocontrollern).

Im Übrigen funktioniert dein Vorschlag im Verlauf dieses Threads zum Belegen der Instanz einer struct nur mit einem Compiler, der C++20 unterstützt. Der AVR-GCC Compiler Version 7.3 der der Arduino-IDE 1.8 hinterlegt ist, kann das nicht. Der benutzte RISC-V Compiler für CH32V003 kann es.

Im Demo hätte man anstelle einen 12-Bit ADC auf 10 zu reduzieren, eine 10-Bit Auflösung pseudomäßig mittes wert << 2 auf einen 12-Bit Wert skalieren können, so dass bei einem 12-Bit ADC keine Auflösung verschenkt wird.

Man kann die Instanzen von progbar_t und tbox_t bereits im Konstruktor mit Werten belegen.

Ich habe mir viele Sachen überlegt wie man ein printf und ein AnsiOut realisieren kann, so dass es für Arduino-User "okay" ist.

Aber ohne Käse, mach einfach mal ein paar Vorschläge... und dann auch mal eine Einschätzung darüber wie sinnvoll diese Library ist....

Uuuuuund: ist es legitim, wenn ich "Treiber" für bspw. DHT11 / 22 oder DS18B20 , BM280 mache, dass die Beispiele für diese "Treiber" dieses extendedSerial verwenden dürfen oder ist es hier besser doch nur HardwareSerial von Arduino zu verwenden.

Und: für ein vollwertiges Serial für einen CH32V003 lieber den Core patchen oder eine eigenständige Library für Serial.


Es geht mir nicht darum, dass man mir zeigt wie man etwas programmiert, sondern es geht mir daraum, was denn für den geneigten Anwender das pragmatischtes und durchschaubarste ist?

#8026890
Lesenswert?

Am sinnvollsten Düfte Core patchen sein, die Frage welches serial für die Treiber erübrigt sich dadurch, die Nutzer kennen das Benennungsschema, kommen so in "gewohnter Umgebung" besser zurecht

Ralph S. schrieb:

Für alle anderen: es kann durch aus richtig Spaß machen, mit den Ansi-Sequenzen auf Arduino zu spielen.

Ich werde demnächst mal einen PY32F002 dafur verwenden und das ausprobieren. :-)

#8026920
Lesenswert?

Ralph S. schrieb:

s dreht sich hier um eine Ausgabemöglichkeit mittels ESC-Sequenzen auf einem Terminal (meistens eine Terminalemulation),

Ralph, wenn du magst, dann schau dir auch mal das DEC TCS an. Macht die Ausgaben noch etwas hübscher.

1
#!/usr/bin/python3
2
# vim: fileencoding=utf-8: ts=4: sw=4: expandtab:
3
#┌────────────────────────────────────────────────────────────────────────────┒
4
#│      DEC VT100                                                             ┃
5
#│      Technical Character Set                                               ┃
6
#┕━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
7
TCS_ON = '\x1b(0'
8
TCS_OFF = '\x1b(B'
9

10
def showtable():
11
    for i in range(0x20,0x7f):
12
        if i%16==0 and i>0x20:
13
            print()
14
        print(chr(i),end=' ')
15
    print('\n')
16

17
showtable()
18
print(TCS_ON,end='')
19
showtable()
20
print(TCS_OFF,end='')
1
  ! " # $ % & ' ( ) * + , - . / 
2
0 1 2 3 4 5 6 7 8 9 : ; < = > ? 
3
@ A B C D E F G H I J K L M N O 
4
P Q R S T U V W X Y Z [ \ ] ^ _ 
5
` a b c d e f g h i j k l m n o 
6
p q r s t u v w x y z { | } ~ 
7

8
  ! " # $ % & ' ( ) * + , - . / 
9
0 1 2 3 4 5 6 7 8 9 : ; < = > ? 
10
@ A B C D E F G H I J K L M N O 
11
P Q R S T U V W X Y Z [ \ ] ^   
12
◆ ▒ ␉ ␌ ␍ ␊ ° ± ␤ ␋ ┘ ┐ ┌ └ ┼ ⎺ 
13
⎻ ─ ⎼ ⎽ ├ ┤ ┴ ┬ │ ≤ ≥ π ≠ £ ·
#8027029
Lesenswert?

Norbert schrieb:

Ralph, wenn du magst, dann schau dir auch mal das DEC TCS an. Macht die Ausgaben noch etwas hübscher.

Grüß dich Norbert,

:-) na ja, gibt die Ascii-Tabelle mittels Programm in Python auf der Linux-Konsole aus. Mir ging es ja hier eigentlich um Arduino und Mikrocontroller.

Natürlich kann man das auch mit MicroPython auf einem Controller machen (sagen wir ab sSTM32F411), aber das war nicht das Ziel hier.

Zudem :-) nichts für ungut, dein Pythonprogramm ist so schön "unfarbig". Vllt. bis du auch nur der Meinung, ich sollte die Ascii-Tabelle mit Arduino machen ?

#8027049
Lesenswert?

1
╔═════════════════════════╗
2
║    er findet das schöner     ║
3
║                              ║
4
║    Arduino mit AnsiOut       ║
5
║    230400 bd 8N1             ║
6
║                              ║
7
║   15.03.2026 by R. Seelig    ║
8
║                              ║
9
╚═════════════════════════╝
(Firma: Gast) #8027082
Lesenswert?

Ralph S. schrieb:

@Arduino F. ich muß etwas schmunzeln, weil ich angenommen habe, dass du gefühlt 100 Vorschläge machen könntest. Wäre nett, wenn du mal den größten nennen würdest.

Naja... Hauptsächlich kleinere. Stil Dinge.

Wie immer: "Das Prinzip der geringsten Verwunderung" Eine Programm- bzw. Libsammlung ist verständlicher, wenn überall der gleiche Stil verwendet wird. Und da hat sich ein quasi Standard herausgebildet.

Das fängt an bei den selbstgewählten Bezeichnern für alle möglichen Dinge.

  1. Keine Unterstriche in Bezeichnern. (also kein xyz_t)
  2. Datentypen beginnen mit einem Großbuchstaben (also kein xyz_t)
  3. Andere, mit Kleinbuchstaben ( DatenType variable = 23;)
  4. KamelHöckerSchreiweise
  5. Kein typedef für Strukturen, eigentlich gar kein typedef mehr. "typedef" ist eine Sammlung unnützer Buchstaben.

C Stil: typedef uint16_t meintype_t;

Ab C++11/Arduino Stil: using MeinType = uint16_t;

using kann sogar etwas mehr, als typedef, Templates!

Natürlich ist der alte C Stil in Arduino nutzbar, aber eher ungewohnt für geübte Arduin User.


Die Aufteilung in *.h und *.cpp vermeiden. Warum?

Methoden in *.h only sind per default inline.

Man hat nur eine Datei zu pflegen und nicht zwei.

Die Verlängerung der Kompilezeit spielt meist keine Rolle. Bei großen Desktop Anwendungen schon eher.

Da zwecks Portabilität sowieso der Quellcode mit in der Lib sein muss, macht das Ausliefern von proprietären *.a Dateien wenig Sinn. Das geheimhalten/verbergen von Quellcode ist eher nicht Ziel in der Arduino Welt.


Das sind alles nur persönliche Ansichten. Keine Religion, kein Muss.

: Bearbeitet durch User
#8027109
Lesenswert?

Ralph S. schrieb:

Natürlich kann man das auch mit MicroPython auf einem Controller machen (sagen wir ab sSTM32F411), aber das war nicht das Ziel hier.

Zudem :-) nichts für ungut, dein Pythonprogramm ist so schön "unfarbig".

Ach um die Programmiersprache geht's doch gar nicht. Auch nicht um die Farbe. ;-) Py war nur gerade zur Hand, bequem und schnell.

Es geht um die zusätzliche TCS Funktionalität mit ESC(0 und ESC(B (für Grafikzeichen), welche alle VT100 oder besser haben. Eben auch die richtigen Hardware-Dinger, falls man da mal dran möchte. Die können nämlich mit UTF-8 nicht wirklich etwas anfangen und der Bildschirm sieht dann aus wie ausgekotze Buchstabensuppe.

Für eine (ausschließliche) Emulation braucht man das natürlich nicht. Die halten sich sowieso kaum an Standards.

#8027111
Lesenswert?

Alexander schrieb:

1
> ╔═════════════════════════╗
2
> ║    er findet das schöner     ║
3
> ║                              ║
4
> ║    Arduino mit AnsiOut       ║
5
> ║    230400 bd 8N1             ║
6
> ║                              ║
7
> ║   15.03.2026 by R. Seelig    ║
8
> ║                              ║
9
> ╚═════════════════════════╝

Das üben wir aber noch einmal!

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren