Как использовать переменные и функции в нескольких файлах .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?

, 👍2

Обсуждение

Вы имеете в виду несколько файлов .INO *в одном эскизе* или каждый в совершенно отдельном эскизе?, @Majenko

В том же эскизе см. редактирование., @William Roy

По-прежнему возникает вопрос: «ПОЧЕМУ?» (почему вам нужны два файла эскизов и зачем разделять переменные между ними), поскольку, возможно, вы пытаетесь эмулировать что-то, что уже присутствует и в гораздо лучшей и более удобной форме., @gilhad


5 ответов


1

В 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


2

Когда вы компилируете несколько файлов в 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


0

Arduino ide обладает ужасными возможностями управления проектами. Итак, два решения.

  1. Переключиться на настоящую идею.
  2. Используйте внешний атрибут.
,

1

Проще всего поместить только один файл .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.

,

0

Вы можете упростить эту задачу, назвав только основной файл эскиза «.ino», а все остальные файлы кода — «.cpp». Компилятор должен знать о «a», прежде чем вы его используете, поэтому объявите «a» в файле .ino как «extern int a;». перед его первым использованием, чтобы сообщить ему, что такое «а». Отсутствие этого является причиной сообщения об ошибке.

,