Frage zur bedingten Compilierung (#ifdef) ...

Hallo,
ich verwende in meinem Sketch auch Compiler-Anweisungen zur bedingten Compilierung, also

#ifdef I2C_LCD_Vorhanden
(beliebiger Code für das LCD...)
#endif

Funktioniert prima. Jetzt möchte ich aber auch noch nicht benötigte Librarys "weglassen", also schreibe ich folgendes:

#ifdef I2C_LCD_Vorhanden
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#endif

Aber egal, wie "I2C_LCD_Vorhanden" gesetzt ist, die beiden Librarys werden immer mit eingebunden? Warum?

Viele Grüße, paulinchen

Hallo paulinchen,

ich mache das auch so und es funktioniert. Hier der entsprechende Teil aus einem Code

#define I2CDISPLAY

#define MAXLINES 4    // defines the number of display lines
#define LCD_CHARACTERS 20

#ifdef I2CDISPLAY
#include <Wire.h> 
#include <LiquidCrystal_I2C.h>
#define LCD_ADRESS 0x27
LiquidCrystal_I2C lcd(LCD_ADRESS,LCD_CHARACTERS,MAXLINES);  // I2C LCD address is 0x27
#else
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);  // RS, E, D4, D5, D6, D7 - the standard connection
#endif

Fehlt bei dir eventuell ein
#define I2C_LCD_Vorhanden
?

Gruß Reinhard

Aber egal, wie "I2C_LCD_Vorhanden" gesetzt ist, die beiden Librarys werden immer mit eingebunden? Warum?

Diese Möglichkeiten sehe ich:

  1. Sobald #define I2C_LCD_Vorhanden vorkommt, ist es definiert, auch wenn du schreibst
    #define I2C_LCD_Vorhanden false

Hast du ein
#undef I2C_LCD_Vorhanden
oder hast du die Zeile gelöscht / auskommentiert ?
(diese Möglichkeit nur der Vollständigkeit halber )

  1. Ein anderer Modul in dem Sketch macht auch ein #include
    ( Insbesondere Wire.h könnte auch anderweitig referenziert werden )

  2. Die Ardiuino IDE will dir helfen und baut aus deiner .ino eine .cpp Datei.
    Dabei macht sie manches, was jemand der eigentlich selbst die include - Abhängigkeiten im Griff haben will, eher verwirrt.
    ( Kann sein, dass da #ifdef ignoriert wird )
    Sind sie Libraries weg, wenn du die undefinierten #ifdef - Blöcke ganz löschst ?

@Reinhard: Ich versteh das so, dass Paulinchen das grade nicht drinhaben will. So wie bei dir kann das jeder :wink:

... auskommentiert, hätte ich natürlich anmerken sollen - damit sollte das "kann jeder" geklärt sein, oder?
"Sobald #define I2C_LCD_Vorhanden vorkommt, ist es definiert" -> korrekt
Wenn ich die Zeile auskommentiere, wird die Lib definitiv nicht geladen. Ich habe versuchsweise einen Aufruf einer Funktion aus der Lib gemacht, da meckert der Compiler.

Wenn man

#define I2C_LCD_vorhanden

schreibt, ist es definiert (wie define schon sagt). Welchen Wert es ggfs. noch bekommt (true, false, 4711, "Ich bin ein String") spielt da keine Rolle.

Aber nimmt doch statt #ifdef mal den Bruder #if. Syntax siehe hier http://www2.informatik.uni-halle.de/lehre/c/c_if.html oder auch
hier http://msdn.microsoft.com/en-us/library/ew2hz0yd(v=vs.80).aspx

Das folgende müsste dann funktionieren:

#define I2C_LCD_Vorhanden false     // oder alternativ    #define I2C_LCD_Vorhanden true  

#if I2C_LCD_vorhanden == true         // #if I2C_LCD_Vorhanden reicht auch bei boolschen Werten
  #include <Wire.h>
  #include <LiquidCrystal_I2C.h>
#else     // false
// wenn nicht true, wird nichts eingefügt;  #else-Zweig kann dann natürlich weggelassen werden
#endif

Ich kanns im Augenblick nicht ausprobieren, aber so sollte es gehen.

Wolfgang

Hallo,
danke für Eure Hilfe.

Ich habe jetzt die #if-Variante probiert:

#define I2C_LCD_4_20 false //LCD-Display 4x20 am I2C-Bus

#include <SPI.h>
#include <Ethernet.h>
#include <EthernetUdp.h>
#include <SD.h>
#include <DS1307.h>
#include <Flash.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <Base64.h>

#if I2C_LCD_4_20 == true
  #include <Wire.h> 
  #include <LiquidCrystal_I2C.h>
#endif

Das Ergebnis ist leider das gleiche. Erst wenn ich die beiden #include-Zeilen auskommentiere, wird der Sketch kleiner.

Hat noch jemand eine Idee?

Viele Grüße, paulinchen

Das Problem scheint die <Wire.h> zu sein.

Kann es sein, daß diese im Sketch geladen wird, auch wenn ich diese nicht mit #include einbinde?

Viele Grüße, paulinchen

DS1307 braucht auch Wire.h und wird wahrscheinlich im File DS1307.cpp eingebunden

OK, aber warum wird dann mein Sketch kleiner, wenn ich die Zeile auskommentiere:

//#include <Wire.h>

Der Sketch lässt sich ja auch ohne die Zeile fehlerfrei compilieren.

Fragen über Fragen, paulinchen

DS1307 braucht auch Wire.h und wird wahrscheinlich im File DS1307.cpp eingebunden

Wenn ich das Wire-Library Verzeichnis umbenenne und den Sketch ohne LCD compiliere, passt die Größe und es kommt kein Fehler. Also wird doch die Wire.h außer vom LCD nicht gebraucht, oder?

Nutzt du denn überhaupt Funktionen aus der DS1307 Lib?
Hast du mal die anderen Libs geprüft, ob die auch noch Wire.h benötigen?

Ich nutze alle Libs, welche ich eingebunden habe. Verwende ich kein LCD, kann ich die "wire-lib" im library-Verzeichnis umbenennen, ohne das beim compilieren ein Fehler auftritt. Also wird diese von den anderen Libs nicht gebraucht, oder?

Nutze ich jetzt zusätzlich das LCD, benötige ich noch die "wire.h" und die "LiquidCrystal_I2C.h".
So weit auch alles OK.

Wenn ich nun das LCD nicht einbinden will und diese beiden Libs mit der "#if"-Compilerdirektive abschalten will, wird trotzdem die "wire.h" geladen. Erst wenn ich die "#include <Wire.h>" auskommentiere, wird diese nicht mehr geladen.

Ich verstehe es einfach nicht...Gute N8, paulinchen

paulinchen, kannst du noch folgendes ausprobieren:

#if I2C_LCD_4_20 == true
#pragma message ("Wir durchlaufen den Zweig für I2C_LCD_4_20 gleich true")
// oder brutaler: #error Wir wollen den Zweig für I2C_LCD_4_20 gleich true durchlaufen
#include <Wire.h> 
#include <LiquidCrystal_I2C.h>
#else
#pragma message ("Wir durchlaufen den Zweig für I2C_LCD_4_20 gleich false")
// oder brutaler: #error Wir wollen den Zweig für I2C_LCD_4_20 gleich false durchlaufen
#endif

Die Meldungen erscheinen im Compiler-Output. Wie man den in der Arduino-IDE anzeigt, weiss ich nicht genau, da ich schon seit einiger Zeit nur noch das Atmel Studio 6.0 als Entwicklungsumgebung verwende.

Damit sollten wir erkennen können, welcher Zweig ausgeführt wird und ob die #if-Direktive richtig ausgeführt wird.
Vielleicht kann man zumindest hier einen Hinweis bekommen, ob wire.h eingefügt wird oder nicht.

Weiterhin kannst du ja zur Fehlersuche temporär am Anfang der Datei wire.h (liegt im Arduino-Libraries-Verzeichnis) oder in anderen Header-Files etwas einfügen wie

#pragma message ("Wir sind jetzt in wire.h - wollen wir das?????")

um zu sehen, wo es lang geht.

Eventuell auch mal nachsehen, ob es auf deinem System mehrere Versionen von wire.h gibt und dort jeweils einen unterschiedlichen Text bei #pragma message verwenden, um zu sehen welche Version eingefügt wird.