Как использовать переменные и функции в нескольких файлах .ino
У меня есть 2 файла .ino (2 вкладки) для одного проекта/скетча Arduino: MySketch_File1.ino и MySketch_File2.ino.
Я объявил в MySketch_File2 переменные и функции, которые хочу использовать в MySketch_File1, но получаю следующее сообщение об ошибке:
ошибка: 'a' не было объявлено в этой области
//MySketch_File1.ino
void setup(){
Serial.begin(9600);
Serial.println(String(a));
}
void loop(){
}
Второй файл:
//MySketch_File2.ino
int a;
Как я могу объявить переменные и функции один раз в одном файле .ino и использовать их в нескольких файлах .ino?
@William Roy, 👍2
Обсуждение5 ответов
В Arduino sketch.ino
— это основная (и единственная) программа, работающая на процессоре.
Если вы загрузите в HW еще один скетч, то предыдущий будет перезаписан и больше не будет существовать на HW. Таким образом, они не могут использовать общие переменные, поскольку они никогда не запускаются одновременно. (Вы можете хранить некоторые значения в EEPROM или на внешних устройствах, но это другое дело).
Возможно, вы захотите использовать второй файл в качестве библиотеки
, которая представляет собой набор переменных и функций, которые могут использовать более чем одна программа. В любом случае используется текст библиотеки, а не значения, присвоенные переменным в одном sketch.ino
, поэтому другой sketch.ino
, использующий ту же библиотеку, будет иметь функции и переменные с тем же именем доступны, но поскольку они скомпилированы в другую программу, значения, присвоенные в одном скетче, не будут видны в другом скетче.
Можете ли вы указать, почему вы хотите использовать переменные и функции в нескольких файлах .ino?
Если просто не нужно набирать его снова и снова и исправлять найденные ошибки в каждой и каждой копии отдельно, то вам нужны библиотеки
.
Если вы также хотите совместно использовать значения (например, читать и вычислять значения в одном .ino, затем загружать другой .ino и использовать результат), вам нужны постоянные хранилища
(EEPROM на чипе, SD карту через какой-нибудь ридер или что-то в этом роде.
Если вы хотите, чтобы одновременно работало больше Arduino и разделяли некоторые значения, вам нужны сети
, такие как I2C, последовательная связь, Ethernet и т. д.
Если вы хотите запускать несколько программ на одном Arduino одновременно, вам нужен многозадачность
, где каждая программа неоднократно прерывается, а другая продолжается, достаточно быстро, чтобы пользователь не заметил, или для создайте больше функций и вызовите их из цикла() один за другим, например. прочитайте датчики, затем зажгите светодиоды, затем запустите двигатели. Автоматы состояний
могут облегчить вам путь.
Теперь, когда ФП разъяснил вопрос, это неправильный ответ. У него открыты две «вкладки», то есть у него есть два исходных файла одной и той же программы., @frarugi87
Хорошо, это переместило его куда-то еще, но все же я думаю, что это может иметь отношение к его намерениям - почему он хочет разделить два файла - использование вторичных файлов для объединения вместе с помощью какого-то хака IDE, в то время как он хочет подражать тому, как работает библиотека, - это не так. лучший подход, если он также может использовать библиотеки, @gilhad
Конечно... Даже если я обычно склонен разбивать (большие) программы на более мелкие части (например, один файл для основного цикла, один для одного из периферийных устройств, один для интерфейса,...), @frarugi87
Да, я думаю, что если я не могу увидеть весь соответствующий код на одном (максимум двух) экранах, то, вероятно, что-то не так. Вопрос в том, что не так - и поэтому ответы различаются. Если есть повторяющиеся части, ответ, вероятно, будет функцией. Если для одного периферийного устройства/протокола имеется множество функций, ответом будет библиотека. Если проблема просто сложная, то есть, если у вас много кода и функций, необходимо свернуть каждую функцию, а затем свернуть каждую группу свернутых функций. Итак, моя обычная программа включает в себя множество библиотек, и все функции свернуты, а также основной цикл/если., @gilhad
И все, что длиннее нескольких строк, означает лучший редактор, чем Arduino IDE. (Например, я использую VIM.), @gilhad
Когда вы компилируете несколько файлов в Arduno IDE, файлы сначала объединяются вместе.
Это происходит в алфавитном порядке, за исключением, что основной файл INO (тот, который называется так же, как и папка, в которой он находится) размещается первым.
В C имеет значение порядок, в котором элементы появляются в файле. По сути, вы должны убедиться, что вещи (например, переменные, функции и т. д.) определены перед их использованием.
Это становится сложнее, если у вас есть скрытая вещь, например, объединение файлов, которая все портит.
Среда Arduino IDE также пытается скрыть некоторые из них от вас, создавая прототипы функций, поэтому не имеет значения, в каком порядке вы определяете функции – однако эта «полезность» означает, что вы этого не делаете. узнать о правильной структуре программы на языке C.
И что же вы можете сделать? Ну, просто убедитесь, что все ваши глобальные переменные определены в файле main, если только вы не уверены, что они будут использоваться только внутри файла, в котором они определены.
Что произойдет, если вы попытаетесь сделать то, что должен делать программист на языке C? Я имею в виду, что в одном из исходных файлов (например, .ino) вы определяете переменную int a;
, затем в другом вы объявляете ее снова с помощью extern int a;
. Будет ли это работать, если 1) переменная определена в основном ino и 2) если она определена где-то еще, но объявлена в основном? У меня здесь не установлена IDE, чтобы проверить ее самостоятельно;), @frarugi87
Не уверен. Он может жаловаться на несколько определений одного и того же символа, но не может. Я проверю это., @Majenko
Он компилируется, так что да, вы *можете* это сделать, но зачем вам это делать, если вы все равно эффективно определяете его в обоих файлах? Просто определите это в первую очередь. Если вы хотите сделать что-то переносимым между эскизами, сделайте это библиотекой., @Majenko
Я думаю, что extern следует «игнорировать» (на самом деле вы обычно используете extern в заголовочном файле, который затем включается также в файл c, определяющий его), @frarugi87
Да, я согласен, что глобальные переменные следует помещать в первый файл, чтобы каждый мог получить к ним доступ. Или создать класс... Это было просто самое классическое решение (компиляторы C/C++ не добавляют исходные файлы), @frarugi87
Arduino ide обладает ужасными возможностями управления проектами. Итак, два решения.
- Переключиться на настоящую идею.
- Используйте внешний атрибут.
Проще всего поместить только один файл .ino в каталог с таким же именем. Почему файл `.ino` должен находиться в папке с тем же именем?
Вариант 1 (самый чистый): Создайте пользовательскую библиотеку.
Вариант 2 (обходной путь): Относительные пути для #include не поддерживаются но вы можете использовать символическую ссылку, чтобы создать впечатление, что в каждом каталоге есть один и тот же файл заголовка:
sketch1/
sketch1.ino
mylib.h
sketch2/
sketch2.ino
mylib.h (this is a symlink to sketch1/mylib.h)
Вариант 3. Полностью откажитесь от Arduino IDE и создайте сборку с использованием avr-gcc. Пример: http://thinkingonthinking.com/an-arduino-sketch-from-scratch/ и Будет ли Arduino Sketch .ino компилироваться непосредственно на GCC-AVR? Это намного сложнее, но поддерживает более крупные проекты с использованием Makefiles.
Вы можете упростить эту задачу, назвав только основной файл скетча «.ino», а все остальные файлы кода — «.cpp». Компилятор должен знать о «a», прежде чем вы его используете, поэтому объявите «a» в файле .ino как «extern int a;». перед его первым использованием, чтобы сообщить ему, что такое «а». Отсутствие этого является причиной сообщения об ошибке.
- Какие накладные расходы и другие соображения существуют при использовании структуры по сравнению с классом?
- Что лучше использовать: #define или const int для констант?
- Функции со строковыми параметрами
- Как работать с аналоговыми контактами в цикле?
- Какие есть другие IDE для Arduino?
- Как преобразовать скетч примера Arduino в полный проект C++?
- Разница между void setup() и void setup(void)
- Будет ли .ino-скетч ардуино компилироваться непосредственно на GCC-AVR?
Вы имеете в виду несколько файлов .INO *в одном эскизе* или каждый в совершенно отдельном эскизе?, @Majenko
В том же эскизе см. редактирование., @William Roy
По-прежнему возникает вопрос: «ПОЧЕМУ?» (почему вам нужны два файла эскизов и зачем разделять переменные между ними), поскольку, возможно, вы пытаетесь эмулировать что-то, что уже присутствует и в гораздо лучшей и более удобной форме., @gilhad