How to escape a string that starts with a # and includes backslashes inside the platformio.ini?

I’m trying to inject some credentials via the platformio.ini into my build.
Unfortunately, I’m having issues with the escaping of my WiFi password:

The password looks like #blaBla\lol%Hi (not my real password, obs).
Interestingly, the # is interpreted as a comment start, so I have to escape it with a \ backslash. This seems to kind of change the way the rest is being read, because then I also need to escape the % by adding another % in front of it. But there seems to be no way to escape the \. No matter how many \ I add before it, they are all being ignored.

platformio.ini:

[string_defines]
wifi_ssid = myssid
wifi_pass = \#blaBla\\\lol%%Hi

[env:esp32cam]
platform = espressif32
board = esp32cam
framework = arduino
monitor_speed = 115200
build_flags = 
  -D WIFI_SSID=\"${string_defines.wifi_ssid}\"
  -D WIFI_PASS=\"${string_defines.wifi_pass}\"

[platformio]
description = take pictures and upload them to the web

main.cpp:

#ifdef WIFI_SSID
#pragma message WIFI_SSID
#endif

#ifdef WIFI_PASS
#pragma message WIFI_PASS
#endif

compiler output:

src\main.cpp:5:30: note: #pragma message: "myssid"
 #pragma message WIFI_SSID
                              ^
                 ^
src\main.cpp:9:30: note: #pragma message: "#blaBlalol%Hi"
 #pragma message WIFI_PASS
                              ^

build_flags are intended for the C-preprocessor but there is an additional layer of interpretation by the PIO commands and setup tools. So I suggest to use just numbers and letters which give 36 symbols to play with.

But, in my opinion, it is risky to put plain text passwords in development files. If you are not going on the internet, there is an ESP32 option called ESPNOW which uses MAC addresses of local devices. That worked for me.

What I’m looking for is some way of defining environment variables somewhere where it’s easy to exclude from version control (like an .env file) and including the values at compile time.
Changing the password is unfortunately not an option (and generally the method should better work with any password without having to escape stuff).

Maybe I should just write some header and include it?

Yes, you can define the passwords in a header file which is located outside your project folder.
#define PW1 “~!@#%^&*()-+{}|<>?” “more” “\0”

Serial.println(PW1)
~!@#%^&*()-+{}|<>?more

1 Like

Yeah, ended up, putting an env.h in the default include folder, filling it up with default stuff, committing that, then putting in my own conf and setting git to ignore changes for that file.