arduino ошибка условной компиляции в NewLiquidCrystal
- Войдите на сайт для отправки комментариев
добрый день
есть некий 100% рабочий проект на "ардуине"
используется "стандартный" 16х2 LCD дисплей (в 4х битном режиме)
все ноги проца занятые, решил допилить проект под себя, добавить (и ногами разжиться подключив LCD по I2c):
- энкодер (шаговичек от флопика)
- подключить дисплей с пом-ю I2C
http://www.ebay.com/itm/New-IIC-I2C-Serial-Interface-Board-Module-For-Ar...
с энкодером проблем нет, а вот с дисплеем ... :о)
точнее не с самим дисплеем а с условной компиляцией
I2C модуль хорошо стыкуется с библиотекой (обновленной LiquidCristall, мой моуль нормально стыкуется только с этой либой)
https://bitbucket.org/fmalpartida/new-liquidcrystal
тупо заменить код на нужный (это не есть тру)
поэтому хочу сделать более универсальный вариант: лобо стандартное подключение либо I2C...
добавляю примерно следующий код:
// ==> CUT
// определяем переменную для того, что бы собрать I2C-версию
// use I2C LCD interface
#define LCD_I2C
#define LCD_I2C_ADDR 0x20 // I2C module addres
#ifdef LCD_I2C
#include <Wire.h> // обязательно надо было подключить
#include <LiquidCrystal_I2C.h>
#else
#include <LiquidCrystal.h>
#endif
...
#ifdef LCD_I2C
LiquidCrystal_I2C lcd(LCD_I2C_ADDR, 4, 5, 6, 0, 1, 2, 3, 7, NEGATIVE);
#else
LiquidCrystal lcd(PINS_LCD_RS, PINS_LCD_ENABLE, PINS_LCD_DB4, PINS_LCD_DB5, PINS_LCD_DB6, PINS_LCD_DB7);
#endif
// ==> CUT
LCD_I2C - определена, сборка проходит нормально
LCD_I2C - задизеблена, сборка затыкается, причем ошибки валят... я бы сказал "левые"...
глянул "код уже в обертке", можно посмотреть в логах ардуины где он находится, ни чего подозрительного не нашел
потыкавшись нашел закономерность - если переменная в условии #ifdef - не определена, то вываливается "эта самая ошибка"
причем, если воткнуть тот или иной код без "препроцессора" то все соберется нормально
т.е. если вставить код
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(LCD_I2C_ADDR, 4, 5, 6, 0, 1, 2, 3, 7, NEGATIVE);
или
#include <LiquidCrystal.h>
LiquidCrystal lcd(PINS_LCD_RS, PINS_LCD_ENABLE, PINS_LCD_DB4, PINS_LCD_DB5, PINS_LCD_DB6, PINS_LCD_DB7);
...
проверял на нескольких версиях ардуины ИДЕ (1.,0.5 , 1.5.2 , ночная сборка... )
коллизии со старой либой "ликвид" - исключены (заменена на новую)
смылс переменной, надеюсь понятен:
- если она определена, то происходит "I2C сборка"
- если переменная не определена, то "нормальная сборка"
причем, очень странно, тут же в коде есть
#ifdef BOARD_ARDUINO_MEGA // For ArduinoMega compatibility
#define PINS_FLASH1 56 // Mega pin 56 = Duemilanove 16 (digital pin)
#define PINS_FLASH2 55 // Mega pin 55 = Duemilanove 15 (digital pin)
#define PINS_DEVICE 54 // Mega pin 54 = Duemilanove 14 (digital pin)
#else
#define PINS_FLASH1 16 //(digital pin)
#define PINS_FLASH2 15 //(digital pin)
#define PINS_DEVICE 14 //(digital pin)
#endif
и с этим собирается нормально
т.е. простые препроцессорные вкропления обрабатываются нормально, а включение непосредственного кода... увы
пробовал на пустых проектах подключать отработать "условную компиляцию" - все нормально, как только подключаю эту самую новую библиотеку "New LiquidCrystal" - то вываливаются ошибки
выкус ошибок
Photoduino:511: error: ‘sysexCallback’ was not declared in this scope
Photoduino.ino: In function ‘void loop()’:
Photoduino:522: error: ‘config_init’ was not declared in this scope
Photoduino:523: error: ‘backlight_init’ was not declared in this scope
Photoduino:524: error: ‘device_init’ was not declared in this scope
Photoduino:525: error: ‘controller_run’ was not declared in this scope
config_manager.ino: In function ‘void config_init()’:
config_manager:20: error: ‘config_loadBackup_all’ was not declared in this scope
config_manager:24: error: ‘backlight_toggle’ was not declared in this scope
config_manager:25: error: ‘display_printResetting’ was not declared in this scope
config_manager:30: error: ‘display_printProgressBar’ was not declared in this scope
config_manager:43: error: ‘config_loadDefaults_all’ was not declared in this scope
причем "sysexCallback" - ноги от нее растут из системной библиотеки
$ARDUINO/libraries/Firmata/
хотя в проекте используется "локальная, упрощенная" ее версия
FirmataLite.h
FirmataLite.ino
ни каких ссылок на подключение системной библиотеки "Firmata" - ни где нет...
### ADD
есть подозрения что ноги растут как раз из новой библиотеки NewLiquidCrystal
- заменил ее на старую, стандартную, из пакета Arduino
- подправил текст программы, что бы подключались нужные файлы и заменил на соотв. конструкторы...
#include <LiquidCrystal_I2C.h>
-->
#include <LiquidCrystal.h>
и усе собралось, как по маслу с определенной переменной так и с дизебленной
библиотека, которая замещает исходную ардуиновскую - NewLiquidCrystal
https://bitbucket.org/fmalpartida/new-liquidcrystal
i'm use LiquidCrystal_V1.2.1.zip
будем изучать код библиотеки, буть он неладен...
если кто глянет более опытным глазом, будем благодарны (все, кто сталкнется с таким же... :о)
### add
перерыл весь код NewLiquideCristall, все тщетно, придраться не к чему
### пособие по повторению косяков
значит такь, записывайте:
1. библиотека, которая замещает исходную ардуиновскую NewLiquidCrystal
https://bitbucket.org/fmalpartida/new-liquidcrystal
i'm use LiquidCrystal_V1.2.1.zip
2. проект который я "рихтую"
http://sourceforge.net/projects/photoduino/files/firmware/photoduino.shi...
3. мои изменения в патче Photoduino.diff
// cut ==>
319a320,323
>.
> //#define LCD_I2C
> #define LCD_I2C_ADDR 0x20 // I2C module addres
>.
322c326,334
< #include <LiquidCrystal.h> // For LCD Display use.
---
>.
> //#include <LiquidCrystal.h> // For LCD Display use.
> #ifdef LCD_I2C
> #include <Wire.h> // обязательно надо было подключить, непомню уже как до этого дошел :о) !!! но и без него нормально собирается
> #include <LiquidCrystal_I2C.h>
> #else
> #include <LiquidCrystal.h>
> #endif
>.
327a340,343
> //LiquidCrystal lcd(PINS_LCD_RS, PINS_LCD_ENABLE, PINS_LCD_DB4, PINS_LCD_DB5, PINS_LCD_DB6, PINS_LCD_DB7);
> #ifdef LCD_I2C
> LiquidCrystal_I2C lcd(LCD_I2C_ADDR, 4, 5, 6, 0, 1, 2, 3, 7, NEGATIVE);.
> #else.
328a345
> #endif
// cut ==>
p.s.
linux slackware 12.2 kernel 2.6.29.6 kde3 trinity
arduino 1.0.5, 1.5.2, nightly_build
проц, озу, диски - по самое неболуй-предостаточно
спасибо
Ответил в теме на ee.
http://s2.ipicture.ru/uploads/20130721/so5xvZ1N.jpg
http://s2.ipicture.ru/uploads/20130721/hNWtr3k6.jpg
ну, будут идеи почему с "неопределенной константой" вываливается ошибка???
Странно, я точно помню, что в пятницу на форума изиелектроникс писал подробный ответ, что происходит, но сейчас его там нет.
К сожалению, все эксперименты остались на работе, поэтому могу только по памяти изложить основные тезисы.
Когда Arduino IDE видит в тексте строчку "#include <LiquidCrystal.h>", то в отличие от "обычного" компилятора он не только включает в текузий файл содержмое указанного хедера, но и добавояет в проект соответствующий хедеру .cpp
При этом на #ifdef он, похоже плюет (что впрочем понятно - формитрование мейкфайла происходит раньше, чем работает препроцессор)
Это случается даже, если написать что-то типа:
В обычных ситацуациях это не создает проблем, так как линкер все равно не включит лишние скомпилированные объектники в итоговый hex, но в данном случае LiquidCrystal.h и LiquidCrystal_I2C.h - это наследники одного базового класса, определенного в LCD.h
Соответственно, одному ктулху ведомо, в какой из двух файлов с одинаковыми функциями лезет линкер за их телом (по идее, должен в первый из встреченых, но я могу и ощибаться, а линкер может иметь свое собственное мнение по этому поводу).
Плюс к этому, какие файлы и в каком порядке будут скармилваться препроцессору/компилятору в случае с ArduinoIDE тоже непонятно.
Так что я бы просто создал Makefile для проекта, тщательно почистил его и компилировал ручками с помощью обычного мейка идущим в составе ардуины avrgcc. Мэйкфайл можно, скорее всего, вытащить из временных файлов, создаваемых IDE.
"ошибка условной компиляции" устранена, решение следующее:
1. добавляем хедер файл в главный модуль
#include "inc.h"
2. добавляем в inc.h описания всех функций используемых в проекте (проект состоит из нескольких INO-файлов, подключаемых Arduino-IDE "от балды на автомате" :о)))
ну вообщем то и все... сборка прошла нормально
будем грысть проект далее
п.с. думаю вся проблема в Arduino-IDE, которая некорректно "упаковывает" код (есть такое мнение, не мое, в инете об этом пишут...)
спасибо всем откликнувшимся, удачи