Bug with compiler or code error?

Good morning all,
I have attached two files, both of which contain the same "index_html" raw string literal (one may be renamed but it is the same text).
In one ino file, the string literal compiles fine (but that code is busted so does nothing for us). In the other, it throws an error about a random piece of html code inside the string literal (shouldn't be complaining about anything inside the string literal because it's just part of a string, I think). We need the non-working code to compile because that is the one that we intended to upload once the issue(s) are corrected.

Anyone else able to duplicate this issue? Is there a fix? Did I mess something up?

EDIT: This is with ESP32 board on arduino compiler, using DOIT ESP23 DEVKIT V1, libraries for DallasTemperature by miles and OneWire by paul stroffregen. It should compile with those libraries.

Hines_AP_Wifi_Hybrid.ino (11.4 KB)
NewTemperatureWifiWebServer.ino (17.0 KB)

Please post your code inline with ‘code tags’.
Otherwise some sods like me can’t see it on mobile devices.

can you post those error? use </>

I have not been able to find all the libraries to get it to compile, but there is no difference in the actual rawliteral string except for the line endings used by the editors.

From memory, there is a bug in the Arduino builder.

Again from memory, place your rawliteral in a .h file and include the .h file.


/*********
Main sources for code are below (I attempted to merge and am receiving errors)
Code that shows how to use AP mode.
  https://electropeak.com/learn
  https://electropeak.com/learn/create-a-web-server-w-esp32/ 
Code that shows how to get sensor readings, but it is using STA mode. 
  https://RandomNerdTutorials.com  
*********/


//***********************************************************************************************************************************************************************************************************************************
//INCLUDES
//***********************************************************************************************************************************************************************************************************************************
// Import required libraries
  #include <WiFi.h>
  #include <WebServer.h>
  #include <OneWire.h> 
  #include <DallasTemperature.h>
  #include <WiFiClient.h>
  #include <WiFiAP.h>
  

//***********************************************************************************************************************************************************************************************************************************
//DECLARATIONS
//***********************************************************************************************************************************************************************************************************************************
// Data wire is connected to GPIO 4
#define ONE_WIRE_BUS 4

// Setup a oneWire instance to communicate with any OneWire devices
OneWire oneWire(ONE_WIRE_BUS);

// Pass our oneWire reference to Dallas Temperature sensor 
DallasTemperature sensors(&oneWire);

// Variables to store temperature values
String temperatureF = "";
String temperatureC = "";

// Timer variables
unsigned long lastTime = 0;  
unsigned long timerDelay = 1000;
unsigned long wifiTimeout = 5000;//how long to wait for a wifi connection

// SSID & Password
const char* ssid = "Cool_Project";  // Enter your SSID here
const char* password = "123456789";  //Enter your Password here

// IP Address details
IPAddress local_ip(192, 168, 1, 1);
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 255, 0);

WebServer server(80);  // Object of WebServer(HTTP port, 80 is defult)
void handleRoot();     // function prototypes for HTTP handlers
void handleNotFound();
void handleTemperatureF();
void handleTemperatureC();
void handleWifi();
void handleScan();


//***********************************************************************************************************************************************************************************************************************************
//PROGRAM ENTRY POINT
//***********************************************************************************************************************************************************************************************************************************
void setup(){
  // Serial port for debugging purposes
  Serial.begin(115200);
  Serial.println();

  //disconnect old wifi
  WiFi.disconnect();

  // Create SoftAP
  WiFi.mode(WIFI_AP);
  WiFi.softAP(ssid, password);
  WiFi.softAPConfig(local_ip, gateway, subnet);

  Serial.print("Connect to My access point: ");
  Serial.println(ssid);

  server.on("/", handleRoot);        // Call the 'handleRoot' function when a client requests URI "/"
  server.onNotFound(handleNotFound); // When a client requests an unknown URI (i.e. something other than "/"), call function "handleNotFound"
  server.on("/temperaturec", handleTemperatureC);//To get update of C Value only
  server.on("/temperaturef", handleTemperatureF);//To get update of F Value only
  server.on("/scan", handleScan);
  server.on("/wifi", handleWifi);
  

  server.begin();
  Serial.println("HTTP server started");
  delay(100);

   // Start up the DS18B20 library
  sensors.begin();

  temperatureC = readDSTemperatureC();
  temperatureF = readDSTemperatureF();
}

void loop() {
  server.handleClient();
  if ((millis() - lastTime) > timerDelay) {
    temperatureC = readDSTemperatureC();
    temperatureF = readDSTemperatureF();
    lastTime = millis();
  }  
}

String readDSTemperatureC() {
  // Call sensors.requestTemperatures() to issue a global temperature and Requests to all devices on the bus
  sensors.requestTemperatures(); 
  float tempC = sensors.getTempCByIndex(0);

  if(tempC == -127.00) {
    Serial.println("Failed to read from DS18B20 sensor");
    return "--";
  } else {
    Serial.print("Temperature Celsius: ");
    Serial.println(tempC); 
  }
  return String(tempC);
}

String readDSTemperatureF() {
  // Call sensors.requestTemperatures() to issue a global temperature and Requests to all devices on the bus
  sensors.requestTemperatures(); 
  float tempF = sensors.getTempFByIndex(0);

  if(int(tempF) == -196){
    Serial.println("Failed to read from DS18B20 sensor");
    return "--";
  } else {
    Serial.print("Temperature Fahrenheit: ");
    Serial.println(tempF);
  }
  return String(tempF);
}


//***********************************************************************************************************************************************************************************************************************************
//WEB PAGES
//***********************************************************************************************************************************************************************************************************************************

const char ap_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML><html>
<head>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.2/css/all.css" integrity="sha384-fnmOCqbTlWIlj8LyTjo7mOUStjsKC4pOpQbqyi7RrhN7udi9RwhKkMHpvLbHG9Sr" crossorigin="anonymous">
  <style>
    html {
     font-family: Arial;
     display: inline-block;
     margin: 0px auto;
     text-align: center;
    }
    h2 { font-size: 3.0rem; }
    p { font-size: 3.0rem; }
    .units { font-size: 1.2rem; }
    .ds-labels{
      font-size: 1.5rem;
      vertical-align:middle;
      padding-bottom: 15px;
    }
  </style>
</head>
<body>
  <h2>Temperature Monitoring Site</h2>
  <p>
    <i class="fas fa-thermometer-half" style="color:#059e8a;"></i> 
    <span class="ds-labels">Temperature Celsius</span> 
    <span id="temperaturec">%TEMPERATUREC%</span>
    <sup class="units">&deg;C</sup>
  </p>
  <p>
    <i class="fas fa-thermometer-half" style="color:#059e8a;"></i> 
    <span class="ds-labels">Temperature Fahrenheit</span>
    <span id="temperaturef">%TEMPERATUREF%</span>
    <sup class="units">&deg;F</sup>
  </p>
</body>
<script>
function askForTempC() {
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
      document.getElementById("temperaturec").innerHTML = this.responseText;
    }
  };
  xhttp.open("GET", "/temperaturec", true);
  xhttp.send();
}
function askForTempF() {
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
      document.getElementById("temperaturef").innerHTML = this.responseText;
    }
  };
  xhttp.open("GET", "/temperaturef", true);
  xhttp.send();
}
askForTempF();
setInterval(askForTempF, 1000);
askForTempC();
setInterval(askForTempC, 1000);
</script>
</html>)rawliteral";


const char wifi_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML><html>
<head>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.2/css/all.css" integrity="sha384-fnmOCqbTlWIlj8LyTjo7mOUStjsKC4pOpQbqyi7RrhN7udi9RwhKkMHpvLbHG9Sr" crossorigin="anonymous">
  <style>
    html {
     font-family: Arial;
     display: inline-block;
     margin: 0px auto;
     text-align: center;
    }
    h2 { font-size: 3.0rem; }
    p { font-size: 3.0rem; }
    .units { font-size: 1.2rem; }
    .ds-labels{
      font-size: 1.5rem;
      vertical-align:middle;
      padding-bottom: 15px;
    }
  </style>
</head>
<body>
  <h2>Temperature Monitoring Site</h2>
  <p>
    <i class="fas fa-thermometer-half" style="color:#059e8a;"></i> 
    <span class="ds-labels">Temperature Celsius</span> 
    <span id="temperaturec">%TEMPERATUREC%</span>
    <sup class="units">&deg;C</sup>
  </p>
  <p>
    <i class="fas fa-thermometer-half" style="color:#059e8a;"></i> 
    <span class="ds-labels">Temperature Fahrenheit</span>
    <span id="temperaturef">%TEMPERATUREF%</span>
    <sup class="units">&deg;F</sup>
  </p>
</body>
<script>
function askForTempC() {
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
      document.getElementById("temperaturec").innerHTML = this.responseText;
    }
  };
  xhttp.open("GET", "/temperaturec", true);
  xhttp.send();
}
function askForTempF() {
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
      document.getElementById("temperaturef").innerHTML = this.responseText;
    }
  };
  xhttp.open("GET", "/temperaturef", true);
  xhttp.send();
}
askForTempF();
setInterval(askForTempF, 1000);
askForTempC();
setInterval(askForTempC, 1000);
</script>
</html>)rawliteral";


//***********************************************************************************************************************************************************************************************************************************
//WEB REQUEST HANDLERS
//***********************************************************************************************************************************************************************************************************************************
void handleRoot() {
  if (WiFi.status() == WL_CONNECTED)
    server.send(200, "text/html", wifi_html);
  else
    server.send(200, "text/html", ap_html);
}

void handleWifi(){
  String qsid = server.arg("ssid");
  String qpass = server.arg("pass");
  
  WiFi.begin(ssid, password);
  unsigned long starttime = millis();
  
  while ((WiFi.status() != WL_CONNECTED) && ((millis() - starttime) < 5000 ) ) { //5 seconds timeout
    delay(500);
    Serial.print(".");
  }

  if (WiFi.status() == WL_CONNECTED)
  {
    Serial.println("Connected to wifi successfully");
    server.send(200, "text/html", wifi_html);//now send with updated data
  }
  else
  {
    Serial.println("Failed to connect to wifi");
    server.send(200, "text/html", ap_html);//now send with updated data    
  }
}

void handleScan(){
  IPAddress ip = WiFi.softAPIP();
  String ipStr = String(ip[0]) + '.' + String(ip[1]) + '.' + String(ip[2]) + '.' + String(ip[3]);
  String content = "<!DOCTYPE HTML>\r\n<html>go back";
  server.send(200, "text/html", content);
}

void handleTemperatureF() {
  server.send(200, "text/plain", temperatureF);//Send F value only to client ajax request
}

void handleTemperatureC() {
  server.send(200, "text/plain", temperatureC);//Send C value only to client ajax request
}

void handleNotFound(){
  server.send(404, "text/plain", "404: Not found"); // Send HTTP status 404 (Not Found) when there's no handler for the URI in the request
}


I'm not at my compiler currently but the error was about the java function in the string. Something like "function does not declare a type", on the line of the function inside the html script.

That seems plausible, I'll give it a try when I'm at home again

as mentioned create a html.h file in the same folder as your sketch with this

#ifndef _HTML_
#define _HTML_
//***********************************************************************************************************************************************************************************************************************************
//WEB PAGES
//***********************************************************************************************************************************************************************************************************************************

const char ap_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML><html>
<head>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.2/css/all.css" integrity="sha384-fnmOCqbTlWIlj8LyTjo7mOUStjsKC4pOpQbqyi7RrhN7udi9RwhKkMHpvLbHG9Sr" crossorigin="anonymous">
  <style>
    html {
     font-family: Arial;
     display: inline-block;
     margin: 0px auto;
     text-align: center;
    }
    h2 { font-size: 3.0rem; }
    p { font-size: 3.0rem; }
    .units { font-size: 1.2rem; }
    .ds-labels{
      font-size: 1.5rem;
      vertical-align:middle;
      padding-bottom: 15px;
    }
  </style>
</head>
<body>
  <h2>Temperature Monitoring Site</h2>
  <p>
    <i class="fas fa-thermometer-half" style="color:#059e8a;"></i> 
    <span class="ds-labels">Temperature Celsius</span> 
    <span id="temperaturec">%TEMPERATUREC%</span>
    <sup class="units">&deg;C</sup>
  </p>
  <p>
    <i class="fas fa-thermometer-half" style="color:#059e8a;"></i> 
    <span class="ds-labels">Temperature Fahrenheit</span>
    <span id="temperaturef">%TEMPERATUREF%</span>
    <sup class="units">&deg;F</sup>
  </p>
</body>
<script>
function askForTempC() {
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
      document.getElementById("temperaturec").innerHTML = this.responseText;
    }
  };
  xhttp.open("GET", "/temperaturec", true);
  xhttp.send();
}
function askForTempF() {
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
      document.getElementById("temperaturef").innerHTML = this.responseText;
    }
  };
  xhttp.open("GET", "/temperaturef", true);
  xhttp.send();
}
askForTempF();
setInterval(askForTempF, 1000);
askForTempC();
setInterval(askForTempC, 1000);
</script>
</html>)rawliteral";


const char wifi_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML><html>
<head>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.2/css/all.css" integrity="sha384-fnmOCqbTlWIlj8LyTjo7mOUStjsKC4pOpQbqyi7RrhN7udi9RwhKkMHpvLbHG9Sr" crossorigin="anonymous">
  <style>
    html {
     font-family: Arial;
     display: inline-block;
     margin: 0px auto;
     text-align: center;
    }
    h2 { font-size: 3.0rem; }
    p { font-size: 3.0rem; }
    .units { font-size: 1.2rem; }
    .ds-labels{
      font-size: 1.5rem;
      vertical-align:middle;
      padding-bottom: 15px;
    }
  </style>
</head>
<body>
  <h2>Temperature Monitoring Site</h2>
  <p>
    <i class="fas fa-thermometer-half" style="color:#059e8a;"></i> 
    <span class="ds-labels">Temperature Celsius</span> 
    <span id="temperaturec">%TEMPERATUREC%</span>
    <sup class="units">&deg;C</sup>
  </p>
  <p>
    <i class="fas fa-thermometer-half" style="color:#059e8a;"></i> 
    <span class="ds-labels">Temperature Fahrenheit</span>
    <span id="temperaturef">%TEMPERATUREF%</span>
    <sup class="units">&deg;F</sup>
  </p>
</body>
<script>
function askForTempC() {
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
      document.getElementById("temperaturec").innerHTML = this.responseText;
    }
  };
  xhttp.open("GET", "/temperaturec", true);
  xhttp.send();
}
function askForTempF() {
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
      document.getElementById("temperaturef").innerHTML = this.responseText;
    }
  };
  xhttp.open("GET", "/temperaturef", true);
  xhttp.send();
}
askForTempF();
setInterval(askForTempF, 1000);
askForTempC();
setInterval(askForTempC, 1000);
</script>
</html>)rawliteral";
#endif

and at the start of your sketch do #include "html.h"

the IDE is trying to be too smart probably and creating function's prototype and get confused by your javascript functions

PS/ you should drop the whole indentation and extra spaces in your HTML, that's tons of byes you'll need to send over which does nothing but slows down your connexion and use up more memory than needed

Thanks all, the compiler/IDE bug was fixed with the header added. I would have marked both your answers as correct but only could mark one so I marked the one with more info in it so other users will get a larger description. I appreciate the assists.

1 Like