Go Down

Topic: "#define" oder "int"? (Read 3063 times) previous topic - next topic

bob-o

Guten Abend.

Als ziemlicher Anfänger der Arduino-Sprace bin ich beim Lesen vieler Beispiel-Sketche auf folgendes gestossen:
Z.B. Festlegung des Pins für die interne LED

Manchmal wird das so angegeben:
int ledPin = 13;
und an anderen Stellen:
#define ledPin 13

Mir erscheint die zweite Möglichkeit sinnvoller, ist doch dieser Pin für die LED hardwaremäßig festgelegt und wird beim kompilieren in AVR-Maschinensprache dort hineincodiert.
Und warum deklariert man bei der ersten Version eine Integer-Variable (=2 Byte, 16 Bit)?
Macht das Sinn, was habe ich da nicht verstanden?
Über eine Antwort würde ich mich sehr freuen.

Bobo

mike_pa

Hallo,

Du hast völlig recht, die #define Variante ist platzsparender und eleganter. Der Typ int wird vermutlich deswegen verwendet, weil die Funktionen (z.B. pinMode() als Parameter eine int erwarten, der Compiler wandelt aber auch deb Typ byte automatisch in int um. Aber in der Referenz zum Arduino ist halt die int-Variante verwendet worden.

#define a b teilt dem Compiler nur mit, dass er alle nachfolgenden a durch b ersetzen soll. Im Prinzip kann man auch die #defines weglassen und die Pinnummern direkt in die Funktionsaufrufe schreiben. Davon würde ich allerdings abraten. Ändert sich ein Pin (oder jemand anders will den Code mit anderer Pinbelegung nutzen) ist es wesentlich einfacher, nur die Angabe im #define Statement zu ändern.

Viele Grüße
Michael

bob-o

Hi Michael,
vielen Dank für die schnelle Antwort! :)

Quote
Im Prinzip kann man auch die #defines weglassen und die Pinnummern direkt in die Funktionsaufrufe schreiben. Davon würde ich allerdings abraten. Ändert sich ein Pin (oder jemand anders will den Code mit anderer Pinbelegung nutzen) ist es wesentlich einfacher, nur die Angabe im #define Statement zu ändern.


Also, das sehe ich genauso. So etwas wie eine Pin-Belegung sollte an genau einer Stelle im Code eindeutig deklariert werden. Und ich sehe auch normalerweise nicht die Notwendigkeit, sie während der Programmlaufzeit zu ändern.

Quote
Der Typ int wird vermutlich deswegen verwendet, weil die Funktionen (z.B. pinMode() als Parameter eine int erwarten


Ist das so? Das habe ich in der Referenz nirgens gefunden. Und nach meiner Erwartung werden die 8-Bit-Ports beim AVM-Prozessor mit 8-Bit-Werten angesteuert. Da würde sich ja "byte" als Variablentyp anbieten.

Quote
der Compiler wandelt aber auch deb Typ byte automatisch in int um.


OK, und jetzt beginnt für mich das Mysterium, wie der Compiler den C-Code in Assembler umwandelt. Gibt es die Möglichkeit, sich den vom Compiler übersetzten Assembler-code anzuschauen? Am besten mit den im C-code verwendeten Namen!?
Habe halt früher (lang,lang ists her...) mal in Assembler programmiert, und es erscheint mir als eine faszinierende Aussicht, die wirklich einfache und  übersichtliche Programmierung des Arduino in C mit der schnellen und ressourcensparenden Assemblersprache zu ergänzen. Da habe ich auch im englischsprachigen Forum noch nicht wirklich etwas gefunden.

Grüße  Bobo

marleaux

Hi,

es wird zwar tatsächlich ein int in pinMode() verwendet, allerdings ein uint8_t, welches nur 8bit lang ist. (Die Doku sollte wohl mal entsprechend vervollständigt werden.)

In hardware\cores\arduino\wiring.h wird pinMode() wie folgt deklariert:
Code: [Select]
typedef uint8_t byte;
void pinMode(uint8_t, uint8_t);
void digitalWrite(uint8_t, uint8_t);
int digitalRead(uint8_t);
int analogRead(uint8_t);
void analogReference(uint8_t mode);
void analogWrite(uint8_t, int);


Ich gehe davon aus, dass du demnach wirklich ein Byte sparst, wenn du #define ledPin 13 verwendest, anstatt int ledPin = 13;

Gut aufgepasst. Davon abgesehen kann es natürlich Anwendungsfälle geben, bei denen man auch zur Laufzeit den pinMode ändern möchte. Dann würde man halt "uint8_t ledPin = 13;" verwenden...

Gruß,
marleaux

Udo Klein

Du könntest auch

const int pin = 13;

schreiben. Keine Ahnung ob der Compiler dann Platz für eine Variable belegt. Das Problem mit Makros ist, dass die Zahl dann nicht getypt ist. Häufig macht das keinen Unterschied. Solange der Speicherplatz aber nicht kritisch ist würde ich keine Makros nehmen.

Grund: starke Typisierung ist bei der Fehlersuch oft hilfreich.

Viele Grüße, Udo

P.S. Bei meinem ersten Spielprojekt bin ich schon am Limit und nehme Makros ;) Aber ich habe auch schon die Libraries etwas eingedampft.
Check out my experiments http://blog.blinkenlight.net

madworm

Wenn du das von der arduino software compilierte .elf file mit

avr-objdump -D -S filename.elf

behandelst, dann bekommst du machine code + source code mix.
• Upload doesn't work? Do a loop-back test.
• There's absolutely NO excuse for not having an ISP!
• Your AVR needs a brain surgery? Use the online FUSE calculator.
My projects: RGB LED matrix, RGB LED ring, various ATtiny gadgets...
• Microsoft is not the answer. It is the question, and the answer is NO!

bob-o

Hallo Leute,

vielen Dank für die vielen, schnellen und kompetenten Antworten.

@marleaux,
von dem Datentyp "uint8_t" habe ich bisher noch nichts gehört, das schaue ich mir mal genauer an. Das wiring.h ist auch einen Blick wert, aber das wäre jetzt gerade etwas viel auf einmal.

@Udo klein,
sind Makros gleichbedeutend mit libraries? Der Begriff Makro ist mir im Zusammenhang mit Arduino noch nicht begegnet. Auch da muß ich mich erstmal schlauer machen.

@madworm
Oh,oh, funktioniert das von der Eingabeaufforderung (Windows) aus? Bei mir nicht, und ich habe AVR Studio 4 bei mir installiert. please help, denn Dein Tip klingt gut!

Nun, meine Motivation, etwas genauer hinter die Arduino-Kulissen zu schauen, ist folgende:
Als Anzeide für einen Frequenzzähler habe ich erstmal ein 8x7-Segment-LED-Display aufgebaut. Die 8 digits werden gemultiplext. Um Arduino-Pins zu sparen, werden sowohl die 8-Bit Segment-Daten als auch die 3-Bit Digit-Informationen in zwei Schieberegister am Display mit shiftOut() übertragen. Da brauche ich nur 3 Arduino-Pins + Spannungsversorgung. Das klappt auch prima, aber die Anzeige flackert, "so als ob da eine Interferenz mit dem Display-Takt durchläuft". Versorgungsspannung ist OK, und diese Störung tritt bei jeder getesteten Multiplex-Frequenz auf. Meine Vermutung: irgend ein Prozess im Hintergrund stört mein Timing. Seitdem versuche ich etwas genauer zu ergründen, was sich alles auf dem Arduino abspielt.
Und das wird so langsam immer weniger "KISS" >:(

Vielen dank für eure Ideen.

Bobo


dh1ao

Quote
KISS
ist bei uns Amateurfunkern sogar ein Protokoll und wird
"keep it simple and stupid" genannt. Und manchmal werden Dinge echt "stupid"

@Udo
const int blubb=8; belegt Speicherplatz, allerdings nicht im RAM sondern im Flash, da der Linker an dem const erkennt das nix sich ändert

LG
Peter
Erkläre es mir, ich werde es vergessen. Zeige es mir, ich werde es vielleicht behalten. Lass es mich tun, und ich werde es können. Indisches

mike_pa

Hallo,

MACRO hat nicht speziell etwas mit Arduino zu tun. Es ist ein allgemein üblicher Begriff, hier aber speziell im Zusammenhang mit der Sprache C zu sehen.

#define a b

belegt übrigens keinen Speicherplatz während

int a = b

im Ram Platz für eine integer Variable belegt.

Grüße
Michael

Udo Klein

Klar belegt CONST Platz. Aber es liefert  auch typsicherheit. Mein Punkt war ja nur: wenn genügend Platz da ist würde ich CONST nehmen. Wenn Platz knapp ist führt an Macros kaum ein Weg vorbei. Wenn Platz ganz besonders knapp ist --> Assembler oder größeren Controller kaufen  :)
Check out my experiments http://blog.blinkenlight.net

bohne

Also dem Anfänger würde ich kein #define in den Code packen, da das ein Schlüsselwort ist, das am Anfang kaum von Bedeutung sein sollte.
Der Anfänger hat schon genug damit zu tun Schlüsselwörter wie int zu begreifen.

Ich erinnere mich noch an eine Diskussion in der Arduino Developer Mailinglist, wo vorgeschlagen wurde sogar auf int zu verzichten und das stattdessen led zu nennen. Da im Blink Beispiel ja die meisten Pins eh für LEDs benutzt würden...
http://www.dorkbot.de
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1236434254
http://www.luminet.cc

Jomelo

Quote

Ich erinnere mich noch an eine Diskussion in der Arduino Developer Mailinglist, wo vorgeschlagen wurde sogar auf int zu verzichten und das stattdessen led zu nennen. Da im Blink Beispiel ja die meisten Pins eh für LEDs benutzt würden...


Das wäre ja grausamm geworden.

Go Up