simple webpage using const char MAIN_page[] PROGMEM = R"=====(

I am working with a Raspberry Pi4 and the ESP8266. I am using a generic example of toggling a LED, but running into an issue

It seems there are issues with the compiling of
const char MAIN_page[] PROGMEM = R"=====(
when running on Windows vs MAC, but there is no mention of Linux

below is the code and below that is the result from the serial print

IT seems to tell me I called the webpage, but doesn't print the message to the serial printline. same results if I remove that.

Any help is appreciated.

*
 * ESP8266 NodeMCU LED Control over WiFi Demo
 *
 * https://circuits4you.com
 */
#include <ESP8266WiFi.h>
#include <WiFiClient.h>

//ESP Web Server Library to host a web page
#include <ESP8266WebServer.h>

//---------------------------------------------------------------
//Our HTML webpage contents in program memory
const char MAIN_page[] PROGMEM = R"=====(
<!DOCTYPE html>
<html>
<body>
<center>
<h1>WiFi LED on off demo: 1</h1>

Click to turn <a href="ledOn">LED ON</a>

Click to turn <a href="ledOff">LED OFF</a>

<hr>
</center>

</body>
</html>
)=====";
//---------------------------------------------------------------
//On board LED Connected to GPIO2
#define LED D1  

//SSID and Password of your WiFi router
const char* ssid = "SSID";
const char* password = "PWD";

//Declare a global object variable from the ESP8266WebServer class.
ESP8266WebServer server(80); //Server on port 80

//===============================================================
// This routine is executed when you open its IP in browser
//===============================================================
void handleRoot() {
 Serial.println("You called root page");
 String s = MAIN_page; //Read HTML contents
 Serial.println(s);
 server.send(200, "text/html", s); //Send web page
}
connected with SSID, channel 1
dhcp client start...
ip:10.0.1.67,mask:255.255.255.0,gw:10.0.1.1
.
Connected to SSID
IP address: 10.0.1.67
HTTP server started
pm open,type:2 0
You called root page
Fatal exception 3(LoadStoreErrorCause):
epc1=0x40208f7c, epc2=0x00000000, epc3=0x00000000, excvaddr=0x4023a0c2, depc=0x00000000

Exception (3):
epc1=0x40208f7c epc2=0x00000000 epc3=0x00000000 excvaddr=0x4023a0c2 depc=0x00000000

ctx: cont 
sp: 3ffffc90 end: 3fffffd0 offset: 01a0

>>>stack>>>
3ffffe30:  3ffe8c1b 402066c7 00000028 401007c6  
3ffffe40:  00000010 40204e25 3ffe8c1b 40204c24  
3ffffe50:  0000001c 3fff06a8 3ffeed5c 4020483c  
3ffffe60:  000000d0 3ffffec0 3ffffec0 402066c7  
3ffffe70:  4023a0c2 000000c9 3ffffec0 40206713  
3ffffe80:  3ffe8c19 00000000 3ffffec0 40206745  
3ffffe90:  00000001 00000001 3ffffec0 40206792  
3ffffea0:  4023a0c2 3fffff00 3ffeed80 40206344  
3ffffeb0:  3ffeed5c 00000001 3ffeed80 40202752  
3ffffec0:  3fff0714 000000cf 000000c9 401009e4  
3ffffed0:  00000001 40203d90 3ffeff84 4020744e  
3ffffee0:  00000000 3fffdad0 3ffeff84 40204832  
3ffffef0:  3ffeff84 3ffeeb7c 3fffff20 4020486e  
3fffff00:  00000000 00000000 00000000 40206874  
3fffff10:  3ffeff84 3ffeeb7c 3ffeeb38 402048f5  
3fffff20:  3fff037c 0000000f 00000001 00000000  
3fffff30:  00000000 3ffeeb38 401067e0 00029a2b  
3fffff40:  3ffeeb7c 00000001 3ffeeb3c 40203c00  
3fffff50:  00000001 00000000 40203d90 0000000f  
3fffff60:  00000000 3fff03bc 3ffeeb38 3ffeee58  
3fffff70:  00000001 3ffeeb60 3ffeeb38 40204aec  
3fffff80:  402077e0 00000000 00001388 40207444  
3fffff90:  00000000 3fff03bc 00000000 feefeffe  
3fffffa0:  3fffdad0 00000000 3ffeee50 4020298c  
3fffffb0:  3fffdad0 00000000 3ffeee50 4020720c  
3fffffc0:  feefeffe feefeffe 3ffe85e8 40100a45  
<<<stack<<<

 ets Jan  8 2013,rst cause:2, boot mode:(1,6)


 ets Jan  8 2013,rst cause:4, boot mode:(1,6)

wdt reset

That construct is an example of the C++ 11 raw string literal.
Did you get any compilation errors ?

See here for debugging your stack trace: My ESP crashes running some code. How to troubleshoot it? — ESP8266 Arduino Core 3.1.1-21-g32323e55 documentation

It looks like the crash happened in one of these two lines:

  String s = MAIN_page; //Read HTML contents
  Serial.println(s);

Does the ESP8266 compiler keep track of which strings are in PROGMEM and which aren't? The AVR compiler certainly doesn't. On the AVR processors it it up to the programmer to keep track of which things are in PROGMEM and call the special PROGMEM version of functions. Does the code work if you take the PROGMEM keyword off your character array? If so, you need to find a way to populate a String from a character array in PROGMEM. You may have to do that byte by byte. Of course there is no reason to put a string in PROGMEM if you are just going to copy it into RAM anyway.

I am not sure if it does or not. I am not good with these chips and figured the exapmles worked. The code came from the guy using a 8266 chip so i assumed it works. Ill dig in when i get home. Also from 6v6gts recommendation on the debugging link the recommendation is to use progmem.

Don’t use const char * with literals. Instead, use const char[] PROGMEM. This is particularly true if you intend to, e.g.: embed html strings.

I am embeding html to send back to the browser

I actually have had a similar example running where the declaration of the page is declared the same way (but in a separate header file) and it worked fine for me, the pleasure of doing it like this is that you can write 'straight' html-code, without having to worry about the " in there, which does make it a lot more readable. In the end it does go into a String ad actually on an ESP that is fine (for sure if declared locally within the callback just to create a webpage to be send. Disadvantage is that the Webpage now is static and can not display variables from within the code and/or user input, So in the end usually this method is not the final choice. Still i am also a little puzzled by why it is not working for you, mind you there are a few things missing from your sketch (or the part that you posted) which might hold some clues to that. On second thought, what happens when you comment out this line :Serial.println(s);i have a vague recollection of me trying the same thing and the size of s is a bit more than what the println (part of the stream class ? ) can hold.

You have also got the send_P() method of the ESP8266WebServer class. You can directly use a progmem construct and don't need the intermediate String (unless you need to edit the html before sending it) :

There is a (non-trivial) example here: Arduino ESP8266 Speaking Clock - Exhibition / Gallery - Arduino Forum

Look in the file : spck_v1.00p.zip then open WebServer.cpp and look in function handleRoot()

Ok, I got the stack trace done, and the results are as follows

Decoding stack results
0x402066b7: String::changeBuffer(unsigned int) at /home/pi/.arduino15/packages/esp8266/hardware/esp8266/2.4.2/cores/esp8266/WString.cpp line 156
0x401007c6: malloc at /home/pi/.arduino15/packages/esp8266/hardware/esp8266/2.4.2/cores/esp8266/umm_malloc/umm_malloc.c line 1676
0x40204e15: ESP8266WebServer::_parseArguments(String) at /home/pi/.arduino15/packages/esp8266/hardware/esp8266/2.4.2/libraries/ESP8266WebServer/src/Parsing.cpp line 283
0x40204c14: ESP8266WebServer::RequestArgument::RequestArgument() at /home/pi/.arduino15/packages/esp8266/hardware/esp8266/2.4.2/libraries/ESP8266WebServer/src/ESP8266WebServer.h line 160
0x4020482c: FunctionRequestHandler::handle(ESP8266WebServer&, HTTPMethod, String) at /home/pi/.arduino15/packages/esp8266/hardware/esp8266/2.4.2/libraries/ESP8266WebServer/src/detail/RequestHandlersImpl.h line 37
0x402066b7: String::changeBuffer(unsigned int) at /home/pi/.arduino15/packages/esp8266/hardware/esp8266/2.4.2/cores/esp8266/WString.cpp line 156
0x40206703: String::reserve(unsigned int) at /home/pi/.arduino15/packages/esp8266/hardware/esp8266/2.4.2/cores/esp8266/WString.cpp line 146
0x40206735: String::copy(char const*, unsigned int) at /home/pi/.arduino15/packages/esp8266/hardware/esp8266/2.4.2/cores/esp8266/WString.cpp line 175
0x40206782: String::String(char const*) at /home/pi/.arduino15/packages/esp8266/hardware/esp8266/2.4.2/cores/esp8266/WString.cpp line 36
0x40206334: Print::println(char const*) at /home/pi/.arduino15/packages/esp8266/hardware/esp8266/2.4.2/cores/esp8266/Print.cpp line 190
0x4020274e: handleRoot() at /home/pi/Arduino Projects/Garage Door/Garage_Door_Website/Garage_Door_Website.ino line 46
0x401009e4: free at /home/pi/.arduino15/packages/esp8266/hardware/esp8266/2.4.2/cores/esp8266/umm_malloc/umm_malloc.c line 1755
0x40203d80: FunctionRequestHandler::canHandle(HTTPMethod, String) at /home/pi/.arduino15/packages/esp8266/hardware/esp8266/2.4.2/libraries/ESP8266WebServer/src/detail/RequestHandlersImpl.h line 20
0x4020743e: std::_Function_handler ::_M_invoke(std::_Any_data const&) at /home/pi/.arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/1.20.0-26-gb404fb9-2/xtensa-lx106-elf/include/c++/4.8.5/functional line 2073
0x40204822: std::function ::operator()() const at /home/pi/.arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/1.20.0-26-gb404fb9-2/xtensa-lx106-elf/include/c++/4.8.5/functional line 2472
0x4020485e: FunctionRequestHandler::handle(ESP8266WebServer&, HTTPMethod, String) at /home/pi/.arduino15/packages/esp8266/hardware/esp8266/2.4.2/libraries/ESP8266WebServer/src/detail/RequestHandlersImpl.h line 44
0x40206864: String::String(String const&) at /home/pi/.arduino15/packages/esp8266/hardware/esp8266/2.4.2/cores/esp8266/WString.cpp line 41
0x402048e5: ESP8266WebServer::_handleRequest() at /home/pi/.arduino15/packages/esp8266/hardware/esp8266/2.4.2/libraries/ESP8266WebServer/src/ESP8266WebServer.cpp line 590
0x401067e0: millis at /home/pi/.arduino15/packages/esp8266/hardware/esp8266/2.4.2/cores/esp8266/core_esp8266_wiring.c line 183
0x40203bf0: WiFiServer::available(unsigned char*) at /home/pi/.arduino15/packages/esp8266/hardware/esp8266/2.4.2/libraries/ESP8266WiFi/src/WiFiServer.cpp line 111
0x40203d80: FunctionRequestHandler::canHandle(HTTPMethod, String) at /home/pi/.arduino15/packages/esp8266/hardware/esp8266/2.4.2/libraries/ESP8266WebServer/src/detail/RequestHandlersImpl.h line 20
0x40204adc: ESP8266WebServer::handleClient() at /home/pi/.arduino15/packages/esp8266/hardware/esp8266/2.4.2/libraries/ESP8266WebServer/src/ESP8266WebServer.cpp line 303
0x40207434: std::_Function_handler ::_M_invoke(std::_Any_data const&) at /home/pi/.arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/1.20.0-26-gb404fb9-2/xtensa-lx106-elf/include/c++/4.8.5/functional line 2069
0x4020297c: loop() at /home/pi/Arduino Projects/Garage Door/Garage_Door_Website/Garage_Door_Website.ino line 99
0x402071fc: loop_wrapper() at /home/pi/.arduino15/packages/esp8266/hardware/esp8266/2.4.2/cores/esp8266/core_esp8266_main.cpp line 125

line 99 for the Garage_door_website is the last line if my code, I am not sure if it follows the same numbering as the script, or if it skips comments and includes other include files as well.

line 46 is sending the HTML to the client

/*
 * ESP8266 NodeMCU LED Control over WiFi Demo
 *
 * https://circuits4you.com
 */
#include <ESP8266WiFi.h>
#include <WiFiClient.h>

//ESP Web Server Library to host a web page
#include <ESP8266WebServer.h>

//---------------------------------------------------------------
//Our HTML webpage contents in program memory
const char MAIN_page[] PROGMEM = R"=====(
<!DOCTYPE html>
<html>
<body>
<center>
<h1>WiFi LED on off demo: 1</h1>

Click to turn <a href="ledOn">LED ON</a>

Click to turn <a href="ledOff">LED OFF</a>

<hr>
</center>

</body>
</html>
)=====";
//---------------------------------------------------------------
//On board LED Connected to GPIO2
#define LED D1  

//SSID and Password of your WiFi router
const char* ssid = "SSID";
const char* password = "PASSWORD";

//Declare a global object variable from the ESP8266WebServer class.
ESP8266WebServer server(80); //Server on port 80

//===============================================================
// This routine is executed when you open its IP in browser
//===============================================================
void handleRoot() {
 Serial.println("You called root page");
 String s = MAIN_page; //Read HTML contents
 //Serial.println(s);
 server.send(200, "text/html", s); //Send web page <----------------------Line 46
}

void handleLEDon() { 
 Serial.println("LED on page");
 digitalWrite(LED,LOW); //LED is connected in reverse
 server.send(200, "text/html", "LED is ON"); //Send ADC value only to client ajax request
}

void handleLEDoff() { 
 Serial.println("LED off page");
 digitalWrite(LED,HIGH); //LED off
 server.send(200, "text/html", "LED is OFF"); //Send ADC value only to client ajax request
}
//==============================================================
//                  SETUP
//==============================================================
void setup(void){
  Serial.begin(115200);
  
  WiFi.begin(ssid, password);     //Connect to your WiFi router
  Serial.println("");

  //Onboard LED port Direction output
  pinMode(LED,OUTPUT); 
  //Power on LED state off
  digitalWrite(LED,HIGH);
  
  // Wait for connection
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.print(".");
  }

  //If connection successful show IP address in serial monitor
  Serial.println("");
  Serial.print("Connected to ");
  Serial.println(ssid);
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());  //IP address assigned to your ESP
 
  server.on("/", handleRoot);      //Which routine to handle at root location. This is display page
  server.on("/ledOn", handleLEDon); //as Per  <a href="ledOn">, Subroutine to be called
  server.on("/ledOff", handleLEDoff);

  server.begin();                  //Start server
  Serial.println("HTTP server started");
}
//==============================================================
//                     LOOP
//==============================================================
void loop(void){
  server.handleClient();          //Handle client requests
}

Suggest you update the core to the newest version.

The newest version worked, thanks all

void handleRoot() {
 Serial.println("You called root page");
 String s = MAIN_page; //Read HTML contents    // what a wasted RAM
 //Serial.println(s);    // you better commented this
 server.send(200, "text/html", s); //Send web page <----------------------Line 46
}

do this instead

void handleRoot() {

 Serial.println("You called root page");

 //Serial.println(s);

   server.send_P(200, "text/html", MAIN_page, sizeof(MAIN_page) ); //Send web page 
}