Так все компилируется: Код (Text): #define DISPLAY #ifdef DISPLAY #include <Wire.h> #include <LiquidCrystal_I2C.h> LiquidCrystal_I2C lcd(0x20,16,2); #else Serial.begin(9600); #endif void setup(){ pinMode(13, OUTPUT); } void loop(){ } Так не компилируется (отличие только в первой строке): Код (Text): //#define DISPLAY #ifdef DISPLAY #include <Wire.h> #include <LiquidCrystal_I2C.h> LiquidCrystal_I2C lcd(0x20,16,2); #else Serial.begin(9600); #endif void setup(){ pinMode(13, OUTPUT); } void loop(){ } Почему?
Если я верно понял то тут проблема вот в чем. Во втором случае код для компилятора после препроцессора получается идентичным этому: Код (Text): Serial.begin(9600); void setup(){ pinMode(13, OUTPUT); } void loop(){ } На данном этапе объект Serial еще не существует, отсюда и беда. Я не знаю точно в какой момент именно создается объект Serial, но по всей видимости где то в промежутке межу данными объявленными пользователем в глобальной области видимости и вызовом функции setup. Решить эту проблему можно как вариант так: Код (Text): #define DISPLAY #ifdef DISPLAY #include <Wire.h> #include <LiquidCrystal_I2C.h> LiquidCrystal_I2C lcd(0x20,16,2); #endif void setup(){ #ifndef DISPLAY Serial.begin(9600); #endif pinMode(13, OUTPUT); } void loop(){ }
Потому что знак // этот означает, что после этого знака идёт комментарий, а комментарий проверять не надо.
Суть не в Serial... Так тоже не работает: Код (Text): //#define DISPLAY #ifdef DISPLAY #include <Wire.h> #include <LiquidCrystal_I2C.h> LiquidCrystal_I2C lcd(0x20,16,2); #else #include <Wire.h> #endif void setup(){ pinMode(13, OUTPUT); } void loop(){ }
Это может быть связано с багом Arduino IDE, который возникает в моиент преобразования скетча в програииу на си для скармливания компилятору. Если это оно, то перед первой директивой условной компиляции надо вставить хитрую комбинацию. Где-то на форуме уже упоминалось.
если вы про эту магию: Код (Text): // BOF preprocessor bug prevent - insert me on top of your arduino-code #if 1 __asm volatile ("nop"); #endif то не срабатывает, хотя некоторые уже сталкивались с аналогичной проблемой. Даже если максимально упростить, все равно ругается: Код (Text): //#define DISPLAY #ifdef DISPLAY #include <Wire.h> #include <LiquidCrystal_I2C.h> LiquidCrystal_I2C lcd(0x20,16,2); #endif void setup(){ pinMode(13, OUTPUT); } void loop(){ } v2_0.ino: In function 'void setup()': v2_0:14: error: 'OUTPUT' was not declared in this scope v2_0:14: error: 'pinMode' was not declared in this scope
Поробовал на Arduino IDE 1.0.6 и 1.6.1. Только #include <LiquidCrystal_I2C.h> LiquidCrystal_I2C lcd(0x20,16,2); Заменил на аналогичное для простого LiquidCrystal. Без "магии" выдает именно такие ошибки, с ней ошибка пропадает. "Магию" применять сразу после //#define DISPLAY
Добавьте первой строчкой в скетч #include <Arduino.h> и не используйте макрос DISPLAY (выберите другое имя, это уже используется внутри Wiring)
В данном случае ошибки в IDE нет, просто при склеивании скетча с main.cpp получается неверная структура кода, #include и код, использующий библиотеки, получаются перемешаны.