Директива #include

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

А вот скажите мне уважаемые, периодически всплывает написание этой директивы двумя образами:
#include <Wire.h> и #include "Wire.h"
и в первом и во втором случае всё компилируется и работает, а как правильно???

 

El
Offline
Зарегистрирован: 10.03.2016

https://msdn.microsoft.com/ru-ru/library/36k2cdd4.as - первое, что вылезло в поисковике

"В приведенном ниже примере демонстрируется включение файлов с помощью угловых скобок:

#include <stdio.h>  

В этом примере в исходную программу добавляется содержимое файла с именем STDIO.H. Угловые скобки указывают препроцессору, что файл STDIO.H необходимо искать сначала в каталогах, заданных в параметре компилятора /I, а затем — заданных в переменной среды INCLUDE.

В следующем примере демонстрируется включение файлов, заданных в кавычках:

#include "defs.h"  

В этом примере в исходную программу добавляется содержимое файла с именем DEFS.H. Кавычки означают, что препроцессор сначала попытается найти этот файл в каталоге, содержащем родительский исходный файл."

Jeka_M
Jeka_M аватар
Offline
Зарегистрирован: 06.07.2014

"Если подключаемый файл указан в <>, то поиск будет происходить в стандартных каталогах, предназначенных для хранения заголовочных файлов. В случае, если подключаемый файл заклю­чен в двойные кавычки, поиск будет происходить в текущем рабочем каталоге. Если файл не найден, то поиск продолжается в стандартных каталогах."

"Различие в том, где препроцессор будет начинать поиск файла some.h. Если использовать директиву #include "some.h", то сначала будут просмотрены локальные (по отношению к проекту) папки включения файлов. Если использовать #include <some.h>, то сначала будут просматриваться глобальные (по отношению к проекту) папки включения файлов. Глобальные папки включения - это папки, прописанные в настройке среды разработки, локальные - это те, которые прописаны в настройках проекта."

jahmal
Offline
Зарегистрирован: 01.06.2016

как для новичка, вы написали две одинаковые вещи :D

to El.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Благодарю!
Теперь понятно куда засовывать уникальные для проекта библиотеки и как их объявлять )))

Клапауций 234
Offline
Зарегистрирован: 24.10.2016

ua6em пишет:

Благодарю!
Теперь понятно куда засовывать уникальные для проекта библиотеки и как их объявлять )))

достаточно именовать файлы библиотек уникальными именами.

diakin
diakin аватар
Offline
Зарегистрирован: 04.06.2016

А как организовать подключение внешних файлов через  #include ?

Допустим часть кода помещается во внешний файл, назовем его IntSendCom.inc  
Логично было бы поместить его в каталог с файлом .ino и написать что-то вроде
 

#include "IntSendCom.inc"

void setup() {
  // put your setup code here, to run once:
}
void loop() {
  // put your main code here, to run repeatedly:
}

чтобы вместо строки #include "IntSendCom.inc" в данное место подставлялся текст из этого файла.
Однако облом

C:\Users\777\Documents\Arduino\sketch_jan13a\sketch_jan13a.ino:2:1: fatal error: IntSendCom.inc: No such file or directory

Если указать полный путь, то все работает

#include "C:\Users\777\Documents\Arduino\sketch_jan13a\IntSendCom.inc" // 

void setup() {
  // put your setup code here, to run once:
}

void loop() {
  // put your main code here, to run repeatedly:
}

Полный путь не очень удобно. Как-нибудь еще можно сделать?

 

sadman41
Offline
Зарегистрирован: 19.10.2016
#include "src/dispatcher.h"

Обратите внимание на расширение файла.

 

 

diakin
diakin аватар
Offline
Зарегистрирован: 04.06.2016

sadman41 пишет:

#include "src/dispatcher.h"

Обратите внимание на расширение файла.

#include  с полным путем работает с любым расширением, а не только с библиотеками.

sadman41
Offline
Зарегистрирован: 19.10.2016

Вам что надо-то - include сделать или свое расширение использовать?

diakin
diakin аватар
Offline
Зарегистрирован: 04.06.2016

А как организовать подключение внешних файлов через  #include ?

Допустим часть кода помещается во внешний файл, назовем его IntSendCom.inc  
Логично было бы поместить его в каталог с файлом .ino и написать что-то вроде
 

1 #include "IntSendCom.inc"
2  
3 void setup() {
4   // put your setup code here, to run once:
5 }
6 void loop() {
7   // put your main code here, to run repeatedly:
8 }

чтобы вместо строки #include "IntSendCom.inc" в данное место подставлялся текст из этого файла.

diakin
diakin аватар
Offline
Зарегистрирован: 04.06.2016

При установке IDE где-то прописываются пути, по которым ищется файлы прописанные в #include <IntSendCom777.inc>

Например, если поместить файл IntSendCom777.inc в папку "C:\Users\777\AppData\Local\Arduino15\packages\arduino\hardware\sam\1.6.9\system\libsam\", то  #include <IntSendCom777.inc> срабатывает, файл находится.
Наверное где-то в реестре прописываются пути.

nik182
Offline
Зарегистрирован: 04.05.2015

А описание слабо прочитать а не гадать и собственные хотелки озвучивать? Например https://msdn.microsoft.com/ru-ru/library/36k2cdd4.aspx

diakin
diakin аватар
Offline
Зарегистрирован: 04.06.2016

Подобная проблема обсуждалась и здесь- http://arduino.ru/forum/programmirovanie/arduino-ide-ne-vidit-faily-v-papkakh  
Поэтому попробуй сначала проверить, что и как в Arduino IDE, если не слабо, конечно. 

sadman41
Offline
Зарегистрирован: 19.10.2016

Читайте внимательно то, на что ссылаетесь.

Начиная с какого-то из релизов ветки 1.6 (на 1.6.11 - точно) все файлы, которые понимает компилятор, переносятся в во временный каталог компиляции. Даже будучи вложенными в каталоги. И прекрасно после этого инклюдятся и компилируются. Если вы решили научить Arduino IDE обрабатывать нестандартные расширения - правьте код IDE.

diakin
diakin аватар
Offline
Зарегистрирован: 04.06.2016

>Если вы решили научить Arduino IDE обрабатывать нестандартные расширения - правьте код IDE.

Если прописать полный путь, то в Arduino IDE "прекрасно после этого инклюдятся и компилируются" нестандартные расширения без всякой правки кода IDE.

sadman41
Offline
Зарегистрирован: 19.10.2016

Отлично, прописывайте. 

diakin
diakin аватар
Offline
Зарегистрирован: 04.06.2016

Не хочу прописывать. Хочу не прописывать.

зы. В 1.6.8 вот так прокатывает

#include <..\..\inc\IntSendCom777.inc> если в папке sketchbook создать папку sketchbook\inc и положить туда IntSendCom777.inc

и так
#include <..\IntSendCom777.inc> если IntSendCom777.inc положить в папку sketchbook\libraries 
 

 

diakin
diakin аватар
Offline
Зарегистрирован: 04.06.2016

Нет, етишкин кот, не все так просто. Надо чтобы строкой выше была подключена какая-нибудь библиотека. Например так

#include <memorysaver.h>
#include <..\IntSendCom999.inc>
тогда работает.

Вот так - 
//#include <memorysaver.h>
#include <..\IntSendCom999.inc>
не работает

зы. Проверил в последней версии 1.8.5 - картина та же самая. 
То есть можно инклюдить произвольные файлы с относительным путем.

b707
Онлайн
Зарегистрирован: 26.05.2017

diakin пишет:

То есть можно инклюдить произвольные файлы с относительным путем.

не страдайте идиотизмом. Существует простой способ добавления файлов в проект. Если вы хотите положить часть кода (кода на С/ C++!) в оотдельный файл, расширение у него должно быть .c .cpp или .h. Это не прихоть создателей ардуино - это стандарт языка.

diakin
diakin аватар
Offline
Зарегистрирован: 04.06.2016

b707 пишет:

diakin пишет:

То есть можно инклюдить произвольные файлы с относительным путем.

не страдайте идиотизмом. Существует простой способ добавления файлов в проект. Если вы хотите положить часть кода (кода на С/ C++!) в оотдельный файл, расширение у него должно быть .c .cpp или .h. Это не прихоть создателей ардуино - это стандарт языка.

Пример работающего кода пришлите, плз. 
 

#include <add.cpp>
void setup() {
  // put your setup code here, to run once:

}

void loop() {
  // put your main code here, to run repeatedly:

}

Не работает - sketch_jan15a.ino:1:19: fatal error: add.cpp: No such file or directory

b707
Онлайн
Зарегистрирован: 26.05.2017

прежде чем писать "не работает", может стоит прочитать хотя бы ту ветку, в который вы это пишете? - обратите особое внимание на сообщения #1 и #2

diakin
diakin аватар
Offline
Зарегистрирован: 04.06.2016

Прежде чем давать идиотские советы, неплохо бы самому задуматься на тем что пишешь.

 

> Существует простой способ добавления файлов в проект. Если вы хотите положить часть кода (кода на С/ C++!) в оотдельный файл, расширение у него должно быть .c .cpp или .h. Это не прихоть создателей ардуино - это стандарт языка.

Это кто писал?

 

b707
Онлайн
Зарегистрирован: 26.05.2017

diakin пишет:

.Это кто писал?

Вы мне не тыкайте. Судя по задаваемым вопросам. ваш уровень в программировании - нулевой. А судя по последнему сообщению, вы и читать не умеете.

Прочитайте сообщения #1 #2 ветки. Чтобы превратить ваш пример в работающий - нужно изменить 2 (два) символа. Найдите их сами - это, так сказать, тест на интеллект. Если не пройдете - не вижу смысла в дальнейшем общении, я не люблю общаться с тупицами.

diakin
diakin аватар
Offline
Зарегистрирован: 04.06.2016

Поменьше апломба, умник.
 

#include <memorysaver.h>
#include "add.h"
void setup() {
  // put your setup code here, to run once:

}

void loop() {
  // put your main code here, to run repeatedly:

}
sketch_jan15a.ino:2:17: fatal error: add.h: No such file or directory

Еще предложения?
b707
Онлайн
Зарегистрирован: 26.05.2017

diakin пишет:

sketch_jan15a.ino:2:17: fatal error: add.h: No such file or directory


файл-то создали в каталоге? :) или вхолостую пробовали?
diakin
diakin аватар
Offline
Зарегистрирован: 04.06.2016

Возьми сам и попробуй, прежде чем писать. lol

Заодно перечитай

https://msdn.microsoft.com/ru-ru/library/36k2cdd4.aspx
и найди там упоминания о "стандартных расширениях"  .h, .cpp и прочем.

 

зы. на форумах стандартно обращение на ты. На вы - опционально, или Вы - когда уж до мордобоя доходит.

b707
Онлайн
Зарегистрирован: 26.05.2017

diakin пишет:

Возьми сам и попробуй, прежде чем писать. lol

Основной код

#include "Task.h"
#define LED_PIN 13
#define BTN_PIN 9

//#1 кнопка кнопка  -> 9 (btn1_pin) 0  нажата / 1 нет
const int btn1_pin = BTN_PIN;
bool btn1, btn1_old; //нажатие кнопки
bool bounce_btn1 = 0; // антидребезговый флаг
// светодиод на пине 13
bool ledON =LOW;

// Tasks - задачки
// предварительно обьявляем процедуры для наших задачек
void blink();            // процедура мигания светодиодом
void check_button();     //  процедцра проверки состояния кнопки

// создаем обьекты класса Task - параметры: ссылка на процедуру и периодичность запуска в мс
Task blink_task(&blink,200);
Task test_btn(&check_button,200);

void setup() {
pinMode(BTN_PIN, INPUT_PULLUP);
pinMode(LED_PIN, OUTPUT); 
btn1 = digitalRead(BTN_PIN);
Serial.begin(9600);

blink_task.start(); // запускаем таймеры обоих задач
test_btn.start();
}
/*************************************************************/
void loop() {
 
 for (int i = 0; i < 2500; i++){ // крутим цикл или делаем что-то сложное
  //ds.requestTemperatures(); // например считываем температуру с датчиков
  Serial.print("Cycle count: ");
  // или подключаемся к инету и ждем ответа...
  Serial.print(i);
  Serial.println();
  nblk_Delay(1000);  // и тут - делей 1s
  }
}

/*************************************************************/
void nblk_Delay(unsigned long d) {
unsigned long timeout = millis() + d;
while (timeout > millis()) {
  if (blink_task.timeout() ) { continue;}  //метод .timeout проверяет, не пришло ли время запуска
  if (test_btn.timeout() )   {continue;}   //если да - запускает задачку и возвращает true
                                           //если нет - переходим к следующей
}
}
/*************************************************************/
//процедуры задачек
void blink() {       //мигаем диодом
digitalWrite(LED_PIN, ledON);
ledON = ! ledON;
};  

void check_button() {   // по нажатию кнопки диод перестает мигать, 
                        // при следующем нажатии снова мигает

// код работы с кнопками полностью утащил из ветки про кнопки, автор qwone (c)                        

if (! bounce_btn1 && btn1 != digitalRead(btn1_pin)) { // если прошел фронт изм на выводн
  bounce_btn1 = 1;                                    // выставить флаг
  test_btn.start(20);                                 // ставим след. отсчет кнопки через 20мс
}
else if ( bounce_btn1  ) { // если прошло антидребезговое время 20 ms
 bounce_btn1 = 0;          // то снять флаг
 test_btn.start(200);      // восстанавливаем период опроса кнопки
 btn1_old = btn1;
 btn1 = digitalRead(btn1_pin) ; // прочитать реальное значение на выводе
 if (btn1_old && ! btn1) {      // если обнаружилось что это было нажатие 
   if (blink_task.is_active()) { //и светодиод мигает
     digitalWrite(LED_PIN, LOW); //гасим его
     ledON =LOW;
     blink_task.stop();}         // и останавливаем блинк
   else {
     blink_task.start();}
   }
       
  }
}

Подключаемый файл:

#include <Arduino.h>  
   
class Task {  
        void (* taskP)();
        unsigned long iTimeout;
        unsigned long iDelay;
        bool active;  
      public:  
      	Task (void (* fp)(), unsigned long d = 200);
        void start (unsigned long t);
        void start ();
        void stop ();
        void restart ();
        bool timeout (void); 
        bool is_active (void); 
        unsigned long Time(void);  
    };  

Компилируется, ошибок нет.

ЗЫ: Код мой, с этого же форума, к вопросу отношения не имеет.

diakin
diakin аватар
Offline
Зарегистрирован: 04.06.2016

Ну хоспади, боже, это понятно что библиотеки подключаются без проблем.
Я  ж чо пишу, русским по белому, в сообщении #6

>А как организовать подключение внешних файлов через  #include ?
>Допустим часть кода помещается во внешний файл, назовем его IntSendCom.inc 
>Логично было бы поместить его в каталог с файлом .ino и написать что-то вроде
>#include "IntSendCom.inc"

>чтобы вместо строки #include "IntSendCom.inc" в данное место подставлялся текст из этого файла.
>Если указать полный путь, то все работает

Проблема с относительным путем, но путем шаманства она как-то решилась.

 

b707
Онлайн
Зарегистрирован: 26.05.2017

diakin пишет:

Ну хоспади, боже, это понятно что библиотеки подключаются без проблем.

в чем вопрос-то тогда? Файл Task.h в моем примере - это не "библиотека", это часть моего кода. который я поместил в другой файл. Ровно то, что вы хотели. Проблема ваша только в том, что вы хотите своим подключаемым файлам давать нестандартные расширения.

Тут два пути:

 - либо делать как все - .c .cpp .h

- либо править исходники IDE

Второе, как мне кажется по дискуссии - вам недоступно. Так что не привередничайте, пользуйтесь стандартным методом.

diakin
diakin аватар
Offline
Зарегистрирован: 04.06.2016

> Файл Task.h в моем примере - это не "библиотека", это часть моего кода. который я поместил в другой файл.

Продолжение марлезонского балета

#include <memorysaver.h>
#include "task.h"
void setup() {
  // put your setup code here, to run once:

}

void loop() {
  // put your main code here, to run repeatedly:

}

sketch_jan15a.ino:2:18: fatal error: task.h: No such file or directory

Где у тебя находится task.h, в какой папке?

 

b707
Онлайн
Зарегистрирован: 26.05.2017

diakin пишет:

Где у тебя находится task.h, в какой папке?

 

в той же, где скетч

diakin
diakin аватар
Offline
Зарегистрирован: 04.06.2016

 

А версия Arduino IDE какая?

DIYMan
DIYMan аватар
Онлайн
Зарегистрирован: 23.11.2015

Кириллических символов в пути к скетчу - лучче не надо.

diakin
diakin аватар
Offline
Зарегистрирован: 04.06.2016

Там нет кириллических символов.

зы. Вроде как на версиях младше 1.6.9 include таким способом работает.

b707
Онлайн
Зарегистрирован: 26.05.2017

diakin пишет:

версия Arduino IDE какая?

1.8.2

Вы там, наверно, в регистре уже покопались, пока файлы .inc пытались запустить - вот и не работает.

Подключение внешних файлов даже смешно обсуждать - зайдите в раздел "Проекты", там мимнимум половина поделок используют разбиение кода на несколько файлов и никаких проблем это не вызывает. Если у вас не работает - проблема в вас или в вашем компе.

diakin
diakin аватар
Offline
Зарегистрирован: 04.06.2016

>Вы там, наверно, в регистре уже покопались,
Телепаты на марше.

Ладно, свою проблему я решил, переливать дальше смысла нет.

b707
Онлайн
Зарегистрирован: 26.05.2017

diakin пишет:

>Вы там, наверно, в регистре уже покопались,
Телепаты на марше.

Ладно, свою проблему я решил, переливать дальше смысла нет.

не по делу - интересно. сколько вам лет? Вы на любые замечания реагируете, словно подросток 15-летний...

Это вообще признак неуверенности в себе - так взрываться по любому поводу. Сами в глубине души знаете, что не тянете, а показать стыдно.

diakin
diakin аватар
Offline
Зарегистрирован: 04.06.2016

И это говорит человек, который пишет "не страдайте идиотизмом", "ваш уровень в программировании - нулевой", "тупица" и при этом требует обращения на вы. )))
Одни понты...

 

DIYMan
DIYMan аватар
Онлайн
Зарегистрирован: 23.11.2015

Diakin, поспокойнее, а то ведь и нахер послать могут - тут борзых не очень любят, так уж повелось.

diakin
diakin аватар
Offline
Зарегистрирован: 04.06.2016

Да я и сам могу послать, борзых-то.. 

b707
Онлайн
Зарегистрирован: 26.05.2017

diakin пишет:

И это говорит человек, который пишет "не страдайте идиотизмом", "ваш уровень в программировании - нулевой", "тупица" и при этом требует обращения на вы. )))

"не страдайте" и правда было резковато. а дальше совершенно по делу.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016
diakin
diakin аватар
Offline
Зарегистрирован: 04.06.2016

Файлы со стандартными расширениями можно и не инклюдить, они и так подхватываются.
Но в закладках появляются через раз. Но даже есди в закладках не появляются, то они компилятся, да.
Но даже если и добавить include, все равно порядок компиляции файлов не зависит от того, в какой последовательностьи #include вставлены в исходник. Порядок компиляции зависит от имени файлов.

Поэтому это не совсем, то что надо. 

DIYMan
DIYMan аватар
Онлайн
Зарегистрирован: 23.11.2015

diakin пишет:

Но в закладках появляются через раз.

Поэтому это не совсем, то что надо. 

Что там у вас творится - одному богу известно. Всё прекрасно появляется/компилится, вот пруф из рабочего проекта, можно посчитать, сколько файлов валяется рядом с *.ino: https://github.com/Porokhnya/GreenhouseProject/tree/master/Main

b707
Онлайн
Зарегистрирован: 26.05.2017

diakin - Поставьте с нуля Ардуино ИДЕ на пустом компе, где ардуино еще не было. Просто ради теста - например на работе. И проверьте, как будут работать инклюды. У вас сейчас явно "сломана" ИДЕ.

diakin
diakin аватар
Offline
Зарегистрирован: 04.06.2016

Установлена и на работе и дома. Разные версии 1.85, 1.77. Установлены и portable и полная установка.
Portable по идее должна быть полностью автономна.
Ну попробуйте у себя-то ради интереса,  код минимальный.

#include "add2.h"
#include "add1.cpp"

void setup() {
  // put your setup code here, to run once:

}

void loop() {
  // put your main code here, to run repeatedly: bossac.exe
}


Один файл с ошибкой

uuuuuu
///ййййй
//const byte PinOut[4] = {7, 6, 5, 4}; //
//const byte PinIn[5] = {12, 11, 10, 9, 8}; //

Второй доп.файл с другой ошибкой

     
zzzzz
//const byte PinOut[4] = {7, 6, 5, 4}; // 
//const byte PinIn[5] = {12, 11, 10, 9, 8}; // 

Отрыть\закрыть скетч несколько раз, удалть\добавить доп.файлы в папку и т.п.
Без include подхватываются файлы? В какой последовательности компилируются? В закладках при каждом открытии отображаются файлы? И тд. 
Несложно же.

DIYMan
DIYMan аватар
Онлайн
Зарегистрирован: 23.11.2015

#include "add1.cpp" - так файлы не подключают. Подключают *.h-файл, в котором объявления находятся. В *.cpp-файле - определения.

diakin
diakin аватар
Offline
Зарегистрирован: 04.06.2016

Файлы *.cpp и *.h можно не подключать через #include и они все равно будут компилироваться. По факту. Если они лежат в папке скетча.

DIYMan
DIYMan аватар
Онлайн
Зарегистрирован: 23.11.2015

diakin пишет:

Файлы *.cpp и *.h можно не подключать через #include и они все равно будут компилироваться. По факту. Если они лежат в папке скетча.

Так точно. Но если захотите воспользоваться интерфейсами, реализованными в *.cpp - в файле, в котором пользуются интерфейсы, надо подключить *.h-файл, содержащий их объявления.

sadman41
Offline
Зарегистрирован: 19.10.2016

Да он, наверное, сигарету с фильтра прикуривает.