Ошибка чтения из PROGMEM
Я пытался запустить код с этого https://circuits4you. .com/2018/03/10/esp8266-jquery-and-ajax-веб-сервер/
Я вставляю это сюда.
/*
* ESP8266 NodeMCU jQuery CDN Demo
*
* https://circuits4you.com
*/
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
//Библиотека веб-сервера ESP для размещения веб-страницы
#include <ESP8266WebServer.h>
//------------------------------------------------ ---------------
// Содержимое нашей веб-страницы в формате HTML в памяти программы
const char MAIN_page[] PROGMEM = R"=====(
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
$(document).ready(function(){
$("p").click(function(){
$(this).hide();
});
});
</script>
</head>
<body>
<p>If you click on me, I will disappear.</p>
<p>Click me away!</p>
<p>Click me too!</p>
<br><hr>
<a href="https://circuits4you.com">circuits4you.com</a>
</body>
</html>
)=====";
//------------------------------------------------ ---------------
// Встроенный светодиод подключен к GPIO2
#define LED 2
//SSID и пароль вашего WiFi роутера
const char* ssid = "circuits4you.com";
const char* password = "yourWiFipassword";
// Объявить глобальную объектную переменную из класса ESP8266WebServer.
ESP8266WebServer server(80); //Сервер на порту 80
//=============================================== ===============
// Эта процедура выполняется, когда вы открываете его IP в браузере
//=============================================== ===============
void handleRoot() {
Serial.println("You called root page");
String s = MAIN_page; //Чтение HTML-содержимого
server.send(200, "text/html", s); //Отправить веб-страницу
}
//=============================================== ==============
// НАСТРАИВАТЬ
//=============================================== ==============
void setup(void){
Serial.begin(115200);
WiFi.begin(ssid, password); //Подключитесь к вашему Wi-Fi роутеру
Serial.println("");
// Бортовой светодиодный порт Выход направления
pinMode(LED,OUTPUT);
//Включение светодиода выключено
digitalWrite(LED,HIGH);
WiFi.mode(WIFI_STA); //Режимная станция WiFi (подключение только к Wi-Fi роутеру
WiFi.begin(ssid, password);
// Ждем соединения
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
//Если подключение успешное, показать IP-адрес в последовательном мониторе
Serial.println("");
Serial.print("Connected to ");
Serial.println(ssid);
Serial.print("IP address: ");
Serial.println(WiFi.localIP()); //IP-адрес, присвоенный вашему ESP
server.on("/", handleRoot); // Какую процедуру обрабатывать в корневом каталоге. Это страница дисплея
server.begin(); //Запускаем сервер
Serial.println("HTTP server started");
}
//=============================================== ==============
// ПЕТЛЯ
//=============================================== ==============
void loop(void){
server.handleClient(); //Обработка запросов клиентов
}
Когда я развертываю это на моем nodemcu esp-12e, я получаю сообщение об ошибке ниже
Я использовал декодер исключений
Exception 3: LoadStoreError: Processor internal physical address or data error during load or store
PC: 0x4000bf64
EXCVADDR: 0x4023d581
Декодер говорит, что эта строка вызывает ошибку
void handleRoot() {
Serial.println("You called root page");
String s = MAIN_page; //<<<<<<<<<<<<<<<<<<<<< Ошибка в этой строке
server.send(200, "text/html", s);
}
Похоже, он не может прочитать переменную в PROGMEM..
Я заменил эту строку этим кодом и преобразовал ее в строку, и ошибка исчезла.
String MAIN_page = R"=====(
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
$(document).ready(function(){
$("p").click(function(){
$(this).hide();
});
});
</script>
</head>
<body>
<p>If you click on me, I will disappear.</p>
<p>Click me away!</p>
<p>Click me too!</p>
<br><hr>
<a href="https://circuits4you.com">circuits4you.com</a>
</body>
</html>
)=====";
Есть ли что-то неправильное в коде, который я использую для чтения переменной из флэш-памяти PROGMEM?
@Mark Estrada, 👍0
Обсуждение2 ответа
Лучший ответ:
Вы не можете назначить строку PROGMEM непосредственно объекту String. Кроме того, вся концепция не имеет смысла, так как объекты String независимо хранят свои данные в оперативной памяти.
Если вы хотите использовать PROGMEM, вам нужно использовать const char *
, а не String
.
String s = (const __FlashStringHelper*) MAIN_page;
будет работать и использует ОЗУ только временно. может быть полезно заменить некоторые части строки. Но весь подход ОП к этому неверен., @Juraj
Да, я просто следил за всем по этой ссылке. Я просто не уверен, как они могут заставить это работать в конце концов., @Mark Estrada
Смысл использования PROGMEM заключается в сохранении оперативной памяти для других целей. Если у вас есть огромная строка, которая переполнит вашу оперативную память, PROGMEM необходим. Однако, если строка не слишком велика и программа работает нормально, просто используйте String вместо PROGMEM.
- Как заставить 5-вольтовое реле работать с NodeMCU
- ESP8266 не подключается к Wi-Fi
- Разница между этими двумя платами NodeMCU?
- NodeMCU - использовать кнопку flash в качестве входного сигнала в loop()
- Как определить размер Flash?
- Как изменить имя модуля ESP8266-12E по умолчанию
- Простой запрос GET с ESP8266HTTPClient
- В ESP-12E NodeMCU, какой выход PIN A0?
server.send_P(200, "текст/html", MAIN_page);
, @Juraj[В ESP32 все, что объявлено как const, попадет в сегмент родата, который затем перейдет во флэш-память и будет считан непосредственно из него.](https://esp32.com/viewtopic.php?f=13&t=4780) . Не знаю про ESP8266., @Gerben
https://arduino-esp8266.readthedocs.io/en/latest/PROGMEM.html PS почему тег UNO?, @Gerben