контент» не захватывается
Я пытаюсь создать переменную, которую можно будет изменять с сервера, используя ESP8266.
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>
const char* ssid = "********";
const char* password = "*********";
ESP8266WebServer server(80);
const int led = 13;
void handleRoot() {
digitalWrite(led, 1);
server.send(200, "text/plain", "hello from esp8266!");
digitalWrite(led, 0);
}
void handleNotFound() {
digitalWrite(led, 1);
String message = "File Not Found\n\n";
message += "URI: ";
message += server.uri();
message += "\nMethod: ";
message += (server.method() == HTTP_GET)?"GET":"POST";
message += "\nArguments: ";
message += server.args();
message += "\n";
for (uint8_t i=0; i<server.args(); i++){
message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
}
server.send(404, "text/plain", message);
digitalWrite(led, 0);
}
}
void setup(void) {
pinMode(led, OUTPUT);
digitalWrite(led, 0);
Serial.begin(115200);
WiFi.begin(ssid, password);
Serial.println("");
// Ожидаем соединения
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.print("Connected to ");
Serial.println(ssid);
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
if (MDNS.begin("esp8266")) {
Serial.println("MDNS responder started");
}
String content = "Basic";
content += "<html><body><form action='action_page.php' method='POST'><br>";
content += "User:<input type='text' name='USERNAME' placeholder='user name'> <br>";
content += "<input type='submit' name='SUBMIT' value='Submit'></form><br>";
server.on("/led", [](){
server.send(200, "text/html", content);
Serial.println(USERNAME);
}
server.on("/", handleRoot);
server.on("/inline", [](){
server.send(200, "text/plain", "this works as well");
});
server.onNotFound(handleNotFound);
server.begin();
Serial.println("HTTP server started");
}
void loop(void){
server.handleClient();
}
Когда я его компилирую, он говорит
"контент" не сохраняется
Я подумал, что это может быть из-за ввода, и для начала попытался назвать его «Базовым», но все равно не получилось.
@Mihai Barbu, 👍2
Обсуждение2 ответа
Лучший ответ:
Давайте рассмотрим более простой пример:
void setup ()
{
String content = "Basic";
attachInterrupt (digitalPinToInterrupt (2),
[]()
{
Serial.println(content);
},
FALLING );
} // конец настройки
void loop () { }
Это дает ошибку:
/tmp/arduino_modified_sketch_182173/sketch_jan25a.ino: In lambda function:
sketch_jan25a:8: error: 'content' is not captured
Serial.println(content);
Почему? Потому что вы используете локальную переменную content
в лямбда-функции, которая выполняется в глобальной области видимости. То есть, content
недоступен для нее, потому что находится внутри setup
.
Чтобы захватить его, вы можете поместить его в список захвата:
attachInterrupt (digitalPinToInterrupt (2),
[content]() // захват контента
Однако я обнаружил, что мой пример даже в этом случае не компилируется.
Я думаю, причину этого можно найти здесь: Лямбда-функции в C++11 - полное руководство
Как реализуются лямбда-замыкания?
Так как же на самом деле работает магия захвата переменных? Оказывается, лямбда-выражения реализуются путем создания небольшого класса; этот класс перегружает оператор(), так что он действует как функция. Лямбда-функция является экземпляром этого класса; когда класс создается, все переменные в окружающей среде передаются в конструктор класса лямбда-функции и сохраняются как переменные-члены.
Вы не можете передать экземпляр класса в attachInterrupt
, поскольку существует скрытая переменная *this
, которую необходимо передать экземплярам класса, а ISR этого не делают.
Ваш пример не является ISR, но, вероятно, применимы те же замечания.
Я не думаю, что здесь есть огромный смысл использовать лямбда-функции. Если вам это необходимо, переместите content
внутрь лямбды, поскольку именно там вы его используете.
Или, если это невозможно, сделайте это глобальным.
Самое близкое, что я смог получить к чему-то компилируемому, это:
void setup ()
{
const int content = 42;
attachInterrupt (digitalPinToInterrupt (2),
[=]()
{
Serial.println(content);
},
FALLING );
} // end of setup
void loop () { }
Честно говоря, я думаю, что использование лямбда-функций здесь просто делает ваш код непонятным.
Я написал led вместо lcd. Я пытаюсь сделать следующее: вызвать страницу из esp8266, которая дает мне поле ввода и кнопку отправки. Я хочу напечатать на lcd то, что написано в этом поле., @Mihai Barbu
Спасибо, это решило мою ошибку, но теперь у меня есть еще одна: 'void setup()': lcdWirelessPrint:69: ошибка: ожидается «)» перед «сервер» server.on("/", handleRoot); ^ статус выхода 1 «Пользователь» не был объявлен в этой области действия. Другой вопрос, как/где мне объявить имя переменной, которой я хочу присвоить имя входных данных., @Mihai Barbu
Это звучит как другой вопрос. Предлагаю вам начать новый вопрос и опубликовать этот новый код., @Nick Gammon
Ладно, я не хотел открывать слишком много, думал, что это будет раздражать., @Mihai Barbu
Вы смотрите на последнюю ошибку компилятора? Первая — самая важная. В настройках можно включить вывод компилятора, чтобы показать больше. Затем прокрутите вверх, чтобы увидеть первую ошибку компилятора. У компилятора проблемы с `` в самом конце вашего скетча.
Они нормальные», они изменились, когда я вставлял сюда. Я все равно завтра проверю., @Mihai Barbu
- Что означает аргумент []() в функции?
- Где определить функции обратного вызова веб-сервера, чтобы они могли получить доступ к объекту сервера? (библиотека ESP8266WebServer)
- Несколько клиентских серверов через Wi-Fi
- Передача функции-члена класса в качестве аргумента
- Как получить параметры запроса от ESPAsyncWebServer?
- esp32 Stack canary watchpoint срабатывает
- Преобразование byte* в int в Arduino
- Как разрешить междоменные запросы на ESP8266 WebServer
@jwpat7 Этот код (большая часть) взят из других примеров из библиотек, и я не (очень) хорош в этом, поэтому не могу понять, что вы подразумеваете под его исправлением., @Mihai Barbu
Возможно, [Лямбда лямбды: функция не захватывается](http://stackoverflow.com/q/13461538) будет более полезной, чем мой предыдущий комментарий., @James Waldby - jwpat7
И это будет использоваться здесь следующим образом: " server.on("/led" , [content](){..... " ?, @Mihai Barbu
Что-то в этом роде. Но я недостаточно знаком с лямбда-синтаксисом C++, чтобы сказать, возможно, кто-то еще знает., @James Waldby - jwpat7
Хорошо, я в любом случае не тороплюсь. Большое спасибо !, @Mihai Barbu