1

I'm developing a program that uses the HTML server in the WiFi101 library.

My hardware does not have SD card storage so all source html needs to be stored as strings in the sketch at compile time. To aid in development I want to keep my html files separate from the sketch and include them at compile time.

Is there a way to use #include in the Arduino IDE and assign the included file to a string/char array constant? If so can the path to the included file be relative to the sketch's path?

Notes: Similar question on Stack overflow: https://stackoverflow.com/questions/410980/include-a-text-file-in-a-c-program-as-a-char

Edit: There are lots of great answers here to solve this in a more robust fashion. The correct thing to do is setup a proper build system. If I were to set this up I'd be temped to try something like Gulp since you could easily minify/lint your web content. As this is a small project I ended up just running the HTML through a minifier service and copy/pasted into strings.

  • look at the toneMelody example in the IDE – jsotola Jan 27 at 8:58
  • Check this. Not sure it is easy to adapt that to the Arduino IDE though. – Edgar Bonet Jan 27 at 9:12
  • No way for what you want in the Arduino IDE. UECIDE supports it though... - although UECIDE doesn't support the SAMD boards yet. – Majenko Jan 27 at 11:01
  • on SAMD Arduino architecture you could use FlashStorage instead of SD card – Juraj Jan 27 at 11:12
1

This will probably not work with the Arduino IDE. If you are willing to go through a Makefile-based workflow, you can install this generic Arduino Makefile, which should make things easier.

With that Makefile installed in /usr/share/arduino/Arduino.mk, the following test worked on an Arduino Uno. It is based on the objcopy trick from the article Embedding of binary data into programs.

Project's 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!

include-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(){}

The program just prints “Hello, World!”, but if you modify text.txt and retype make, it will print whatever you had in this file. Please note that the text is not NUL-terminated, so you have to use the _binary_*_size symbol to know its size.

1

C++ has 'raw string literals'. You can put a constant string, without escaping special characters, into the source code between an opening and closing 'tag'. You can choose the tag to be something that is not in the raw string. In following example the tag is =====.

const char* s1 = R"=====(Hello
"World")=====";

is same as

const char* s2 = "Hello\n\"World\"";

This way you can put your large strings into separate .h files and include them. On AVR use PROGMEM to save RAM.

  • How does that help you include the contents of a file into that string literal? – Majenko Jan 27 at 11:08
  • @Majenko, the h file is The File then. – Juraj Jan 27 at 11:09
  • But the h file isn't the file. The .html file is the file. The OP doesn't want to have to manually convert that .html file into a header file for inclusion (and I can understand that if there are lots of HTML files that he wants to edit often). – Majenko Jan 27 at 11:18
  • @Majenko, this is an option if he doesn't want to use a SD card or other file system – Juraj Jan 27 at 11:27
0

An easy way to do this is to write a C program to convert your files that you want included into your source into a form that looks like:

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 };

The converted file can contain binary data without issue instead of just ASCII.

You can then access the file directly using: file_001[index]

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.