Как присвоить текст, хранящийся в локальном файле, строке во время компиляции
Я разрабатываю программу, которая использует HTML-сервер в библиотеке WiFi101.
На моем оборудовании нет хранилища на SD-карте, поэтому весь исходный HTML-код должен храниться в виде строк в скетче во время компиляции. Чтобы помочь в разработке, я хочу хранить свои HTML-файлы отдельно от скетча и включать их во время компиляции.
Есть ли способ использовать #include в Arduino IDE и назначить включенный файл константе массива string / char? Если да, то может ли путь к включенному файлу быть относительным к пути скетча?
Примечания: Аналогичный вопрос о переполнении стека: https://stackoverflow.com/questions/410980/include-a-text-file-in-a-c-program-as-a-char
Редактировать: Здесь есть много отличных ответов, чтобы решить эту проблему более надежным способом. Правильная вещь, которую нужно сделать, - это настроить правильную систему сборки. Если бы я должен был настроить это, у меня возникло бы желание попробовать что-то вроде Gulp , поскольку вы могли бы легко сократить / сократить свой веб-контент. Поскольку это небольшой проект, я закончил тем, что просто запустил HTML через службу minifier и скопировал / вставил в строки.
@Geordie, 👍6
Обсуждение4 ответа
Лучший ответ:
Вероятно, это не будет работать с Arduino IDE. Если вы готовы выполнить рабочий процесс на основе Makefile, вы можете установить этот универсальный Arduino Makefile, который должен упростить задачу.
С этим файлом Makefile, установленным в /usr/share/arduino/Arduino.mk
,
следующий тест работал на Arduino Uno. Он основан на
трюке objcopy из статьи Встраивание двоичных данных в
программы.
Makefile проекта:
BOARD_TAG = uno
MONITOR_PORT = /dev/ttyACM0
OTHER_OBJS = text.o
include /usr/share/arduino/Arduino.mk
text.o: text.txt
avr-objcopy -I binary -O elf32-avr -B avr:5 $< $@
text.txt:
Hello, World!
включить-blob.ino
extern "C" const uint8_t _binary_text_txt_start[];
extern "C" const uint8_t _binary_text_txt_size;
void setup() {
Serial.begin(9600);
Serial.write(_binary_text_txt_start, (size_t) &_binary_text_txt_size);
}
void loop(){}
Программа просто печатает “Привет, мир!”, Но если вы измените text.txt и
повторно введите make
, он напечатает все, что у вас было в этом файле. Пожалуйста, обратите внимание,
что текст не заканчивается нулем, поэтому вы должны использовать символ
_binary_ *_size
, чтобы узнать его размер.
В C ++ есть "необработанные строковые литералы". Вы можете поместить постоянную строку, не экранируя специальные символы, в исходный код между открывающим и закрывающим тегом. Вы можете выбрать тег как нечто, чего нет в необработанной строке. В следующем примере тег =====
.
const char* s1 = R"=====(Hello
"World")=====";
это то же самое, что и
const char* s2 = "Hello\n\"World\"";
Таким образом, вы можете поместить свои большие строки в отдельные файлы .h и включить их. В AVR используйте PROGMEM для экономии оперативной памяти.
Как это поможет вам включить содержимое файла в этот строковый литерал?, @Majenko
@Majenko, тогда файл h - это файл., @Juraj
Но файл h - это не тот файл. HTML-файл - это и есть файл. OP не хочет вручную преобразовывать этот HTML-файл в заголовочный файл для включения (и я могу это понять, если есть много HTML-файлов, которые он хочет часто редактировать)., @Majenko
@Majenko, это вариант, если он не хочет использовать SD-карту или другую файловую систему, @Juraj
Простой способ сделать это - написать программу на языке Си для преобразования ваших файлов, которые вы хотите включить в исходный код, в форму, которая выглядит следующим образом:
byte file_001[] = { 0x00, 0x01, 0x02, 0x04, 0x0A, 0x00, 0x01, 0x02, 0x04, 0x0A,
0x01, 0x01, 0x02, 0x04, 0x0A, 0x00, 0x01, 0x02, 0x04, 0x0C,
...
0x03, 0x01, 0x02, 0x04, 0x0A, 0x00, 0x01, 0x02, 0x04, 0x0C };
Преобразованный файл может содержать двоичные данные без проблем, а не только ASCII.
Затем вы можете получить прямой доступ к файлу, используя: file_001[индекс]
Я нашел другой способ включить буквальный файл (html, css или другой) и присвоить ему постоянную строку, не прибегая к созданию файлов:
Добавьте одну строку кода поверх вашего HTML-файла (css, js и т.д.), А другую - внизу и сохраните его с дополнительным расширением .h . Затем включите этот файл в IDE Arduino. Это может быть легко сделано с помощью (выполняемого вручную) скрипта при каждом изменении этих файлов.
const char *indexHtml = R"====( // добавлено скриптом
<html> <!-- original .html file -->
.
.
.
</html> <!-- end .html -->
)===="; // добавлено скриптом
Имя переменной может быть производным от исходного имени файла. Результат сохраняется с дополнительным расширением .h. Затем в файл .ino (или .cpp) вы можете включить этот файл:
#include index.html.h
Это будет скомпилировано в Arduino IDE.
- устаревшее преобразование из строковой константы в 'char*'
- Как запрограммировать ардуино на чистом C/C++?
- Количество элементов в массиве char
- Несколько клиентских серверов через Wi-Fi
- WebSocketsServer.h: No such file or directory
- Как получить данные из базы данных моего сервера в переменную в моем Arduino?
- Регистры ввода-вывода SAM3X8E (Arduino Due)
- как быстро loop() работает в Arduino
посмотрите на пример
toneMelody
в IDE, @jsotolaПроверьте [это](https://www.devever.net /~hl/incbin). Однако не уверен, что это легко адаптировать к Arduino IDE., @Edgar Bonet
Нет никакого способа для того, что вы хотите в Arduino IDE. Тем не менее, UECIDE поддерживает это... - хотя UECIDE еще не поддерживает платы SAMD * пока *., @Majenko
в архитектуре SAMD Arduino вы можете использовать FlashStorage вместо SD-карты, @Juraj