Несколько файлов .ino в одном скетче
Да, да, я знаю, что люди часто задают подобные вопросы, но я нигде не мог найти ответа.
Я понимаю, что может быть несколько файлов .ino
в одном скетче, но я не просто хочу, чтобы функции и переменные были разделены, я хочу функциональности.
Я пишу программу Брайля для NodeMCU - она принимает сообщение с обслуживаемого сайта и перемещает сервоприводы для эмуляции соответствующего шрифта Брайля. Я хочу иметь 2 файла: один для обслуживания сайта и получения от него входных данных (website.ino
), а другой для управления сервоприводами(шрифт Брайля.ino
). Единственная проблема в том, что я не могу понять, где объявить/прикрепить сервоприводы.
Я планирую иметь список сервоприводов в braille.ino
, который будет зацикливаться на каждом сервоприводе, устанавливаемом на другое значение. Если я объявлю их в файле website.ino
(мой "основной" файл, т.е. с setup
и loop
), мне придется каждый раз передавать их в свою braille
функцию. С другой стороны, если я решу объявить их глобальными в своем braille.ino
, куда их прикрепить? Можно мне еще один setup
на braille.ino
?
@Levi Lesches, 👍11
Обсуждение3 ответа
Лучший ответ:
Что не очевидно, так это то, что с помощью Arduino вы можете иметь обычные файлы C и C++ в том же каталоге, что и файл .ino. В них могут быть функции и переменные, и Arduino также свяжет их с основной программой. Вам нужен только один
файл .ino - все остальные могут быть в модулях с
расширением .c
или .cpp
(для C++).
Таким образом, вы можете сгруппировать "вспомогательные" функции в разных файлах по категориям - например, файл BrailleServo.c
. Они содержат функции и переменные только для этой категории.
Если вы не запрограммировали родной язык C/C++:
- Поместите функции и переменные в файл
BrailleServo.c
, а затем повторите заголовок функций в файлеBrailleServo.h
. Внутри файла
BrailleServo.c
, вверху, поместите следующую строку:#include "BrailleServo.h"
Обратите внимание на кавычки (
" "
), а не на угловые скобки (< >< >
)- Внутри файла
.ino
поместите ту жестроку #include. Это говорит модулю, что "в другом месте есть другие функции, и это их определения".
Единственная проблема? Получение глупой среды Arduino, позволяющей добавлять файлы .c
и .h
в этот каталог. Вы могли бы просто использовать Блокнот, но есть одна хитрость (если вы используете Windows):
- Выберите
Файл
|Открыть...
- Щелкните правой кнопкой мыши панель с файлами в ней и выберите
Создать >>
|Текстовый документ
- Дайте ему полное имя и убедитесь, что вы также заменили
часть имени .txt на
.c
или.h
. Вы можете получить предупреждение "Если вы измените расширение, файл может быть непригоден для использования" - просто нажмитекнопку ОК
. - Выберите новый (пустой) файл на панели файлов, и появится новая вкладка.
Обратите внимание, что 3. выше предполагается, что вы сказали проводнику файлов Windows НЕ скрывать расширения известных типов файлов. Я всегда так делаю - если нет, тебе придется. С помощью:
- Windows 10: На
вкладке Просмотр любой папки
установите флажок Расширения имен
файлов;- Windows 7: На
вкладке "Панель управления
|Внешний вид и персонализация
|Параметры папок
"снимитегалочку
" Скрыть расширения для известных типов файлов".
Вот три примера:
BrailleServo.h
//
// BrailleServo.h
//
// Call this function once in setup()
void BrailleInit();
// This function activates the six servos to form the passed-in pattern.
void BrailleShow(byte pattern);
BrailleServo.c
//
// BrailleServo.c
//
#include "BrailleServo.h"
// The number of servos
const byte NumServos = 6;
// These are the pins for the six servos
const byte servo[NumServos] = { 3, 4, 6, 7, 9, 10 };
// This initialises the six servos
void BrailleInit() {
for (byte i=0; i<NumServos; ++i) {
pinMode(servo[i], OUTPUT);
// Do what else you need to do with servo[i]
} // for
} // BrailleInit()
// This is how to use the six servos to form the passed-in pattern
void BrailleShow(byte pattern) {
// … Complicated code here …
} // BrailleShow(pattern)
Главная.ino
//
// Main.ino
//
#include "BrailleServo.h"
void setup() {
BrailleInit();
// Other stuff
} // setup()
void loop() {
BrailleShow('A');
delay(1000);
BrailleShow('B');
delay(1000);
} // loop()
Кстати, для получения идей вы, возможно, захотите ознакомиться с моим ответом на более общий вопрос Брайля.
Большое спасибо! Наверное, я на самом деле не думал о том, чтобы сервоприводы что-то делали, пока они не были прикреплены, но я думаю, что именно это происходит, когда вы работаете сверхурочно. Я не думаю, что буду утруждать себя перекодированием букв, так как у меня уже есть массивы true-false, но все равно спасибо!, @Levi Lesches
Я хотел того же, и моим решением было использовать MS Visual Studio с Arduino IDE от Visual Micro. Это упрощает использование нескольких файлов и имеет множество дополнительных преимуществ.
Лично я предпочитаю плагин "Stino" для Sublime Text, но это не отвечает на мой вопрос: куда идет настройка? Как мне передать сервоприводы по командной цепочке?, @Levi Lesches
Если вы идете по маршруту MS, код MS Visual Studio (потому что он кроссплатформенный) плюс platformio - особенно если вы используете nodemcu (и другие микроконтроллеры, отличные от arduino), @Jaromanda X
Важно знать, что файлы вкладок/ino объединяются в один с помощью конструктора. Порядок объединения такой же, как и порядок вкладок в IDE. Первый-это основной файл ino с тем же именем, что и у проекта. Остальные файлы объединены в алфавитном порядке.
Объединенный файл ino определяет видимость переменных. Все файлы ino "видят" переменные в основном файле ino, но переменные в других файлах ino видны только в файле ino с именами, расположенными далее в алфавитном порядке.
Для функций конструктор создает прототипы функций в начале результирующего файла cpp, поэтому, как обычно, все функции видны везде во всех файлах ino.
Один из способов работы с дополнительными вкладками-это группировать функции xySetup() и xyLoop() в файле xy.ino, а затем вызывать эти функции из основной настройки() и цикла(). Мой основной проект Arduino создан таким образом, так что это большой и сложный пример такого подхода.
Чтобы проиллюстрировать, это результирующий файл cpp, входящий в часть cpp набора инструментов сборки (прокрутите его до конца):
#include "Arduino.h"
#define I2C_ADC121 0x50
#include <Wire.h>
extern const unsigned long EVENTS_SAVE_INTERVAL_SEC;
extern const char eventLabels[];
extern const char* eventLongLabels[];
extern const char* eventLongLabels[];
#define EVENTS_FILENAME "EVENTS.DAT"
#include <Grove_LED_Bar.h>
#include <StreamLib.h>
#include <TimeLib.h>
#include <MemoryFree.h>
#include <UIPEthernet.h>
#define ETHERNET
#include <ArduinoOTA.h>
#include <SD.h>
#define FS SD
#define Serial SerialUSB
#include "consts.h"
#define BLYNK_PRINT Serial
#define BLYNK_NO_BUILTIN // Blynk doesn't handle pins
#include <BlynkSimpleUIPEthernet.h>
#include <RTCZero.h>
#define STATS_FILENAME "STATS.DAT"
void balboaSetup() ;
void balboaReset() ;
void balboaLoop() ;
void battSettLoop() ;
boolean battSettRead(FormattedPrint& out) ;
const char* bit2s(int value, byte mask) ;
int battSettControl(boolean chargeControlOn, boolean dischargeControlOn) ;
int battSettSetLimit(byte reg, int limit) ;
void beeperLoop() ;
void alarmSound() ;
void beep() ;
void beeperTone(int freq, uint32_t time) ;
void blynkSetup() ;
void blynkLoop() ;
void updateWidgets() ;
void buttonSetup() ;
void buttonLoop() ;
void csvLogSetup() ;
void csvLogLoop() ;
void csvLogPrintJson(FormattedPrint& out) ;
void elsensSetup() ;
void elsensLoop() ;
boolean elsensCheckPump() ;
byte overheatedSecondsLeft() ;
int readElSens() ;
unsigned short elsensAnalogRead() ;
void eventsSetup() ;
void eventsLoop() ;
void eventsWrite(int newEvent, int value1, int value2) ;
boolean eventsSaved() ;
void eventsSave() ;
byte eventsRealCount() ;
void eventsPrint(FormattedPrint& stream) ;
void eventsPrint(FormattedPrint& s, int ix) ;
void eventsPrintJson(FormattedPrint& stream) ;
void eventsPrintJson(FormattedPrint& stream, int ix) ;
void eventsBlynk() ;
int eventsCompare(const void * elem1, const void * elem2) ;
void ledBarSetup() ;
void ledBarLoop() ;
void manualRunLoop() ;
byte manualRunMinutesLeft() ;
void modbusSetup() ;
boolean modbusLoop() ;
void modbusClearData() ;
boolean requestSymoRTC() ;
boolean requestInverter() ;
boolean requestMeter() ;
boolean requestBattery() ;
boolean modbusError(int err) ;
int modbusRequest(byte uid, unsigned int addr, byte len, short *regs) ;
int modbusWriteSingle(unsigned int address, int val) ;
int modbusConnection() ;
void pilotLoop() ;
unsigned short power2pwm(int power) ;
void setup() ;
void loop() ;
void shutdown() ;
void handleSuspendAndOff() ;
void clearData() ;
boolean handleAlarm() ;
boolean restHours() ;
boolean turnMainRelayOn() ;
boolean networkConnected() ;
void statsSetup() ;
void statsLoop() ;
int statsEvalCurrentPower() ;
void statsAddMilliwats() ;
void statsSave() ;
int statsConsumedPowerToday() ;
void statsPrint(FormattedPrint& out) ;
void statsPrint(FormattedPrint& out, const char *label, Stats &stats) ;
void statsPrintJson(FormattedPrint& out) ;
void statusLedSetup() ;
void statusLedLopp() ;
void statusLedShortBlink() ;
void susCalibLoop() ;
void telnetSetup() ;
void telnetLoop(boolean log) ;
void valvesBackSetup() ;
void valvesBackReset() ;
void valvesBackLoop() ;
void valvesBackStart(int v) ;
boolean valvesBackExecuted() ;
unsigned short valvesBackTempSensRead() ;
void watchdogSetup() ;
void watchdogLoop() ;
void WDT_Handler(void) ;
void webServerSetup() ;
void webServerLoop() ;
void webServerRestRequest(char cmd, ChunkedPrint& chunked) ;
void webServerServeFile(const char *fn, BufferedPrint& bp) ;
void printValuesJson(FormattedPrint& client) ;
void printAlarmJson(FormattedPrint& client) ;
const char* getContentType(const char* ext);
void wemoLoop() ;
boolean wemoPowerUsage() ;
int wemoRequest(const char* service, const char* action, const char* param, const char* value, char* response, size_t size) ;
#include "Regulator.ino"
#include "Balboa.ino"
#include "BattSett.ino"
#include "Beeper.ino"
#include "Blynk.ino"
#include "Button.ino"
#include "CsvLog.ino"
#include "ElSens.ino"
#include "Events.ino"
#include "LedBar.ino"
#include "ManualRun.ino"
#include "Modbus.ino"
#include "PowerPilot.ino"
#include "Stats.ino"
#include "StatusLed.ino"
#include "SusCalib.ino"
#include "Telnet.ino"
#include "ValvesBack.ino"
#include "Watchdog.ino"
#include "WebServer.ino"
#include "WemoInsight.ino"
- Как настроить вход АЦП Arduino на A0 вместо использования по умолчанию?
- Сбой прерывания таймера инициализации Mega 2560
- Подключите Arduino к термопринтеру и подайте внешнее питание
- boards.txt - как создать подменю (НЕ новая плата!!!)
- Atmega 328pu на макетной плате. Что выбрать, чтобы загрузить код с помощью ftdi конвертера
- Восстановление Arduino со сломанным Setup()
- Что вызывает повторную инициализацию моей функции настройки esp8266?
Я хотел того же, и моим решением было использовать MS Visual Studio с Arduino IDE от Visual Micro. Это упрощает использование нескольких файлов и имеет множество дополнительных преимуществ. [![введите описание изображения здесь](https://i.stack.imgur.com/YQeBV.png)](https://i.stack.imgur.com/YQeBV.png), @Edgar
просто есть код в "main" .ino, вызывающий функцию, которую вы определяете в любом последующем .ino, @Jaromanda X
Вы можете использовать VS-код с расширением "vscode-arduino". Это позволит вам управлять несколькими файлами .ino в виде вкладок, как это делается в среде IDE Arduino. Плюс преимущества intellisense. Проверьте производителя.профессиональный веб-сайт о том, как: https://maker.pro/arduino/tutorial/how-to-use-visual-studio-code-for-arduino, @Miguel Silva