2

I try to make a variable that can be modified from the server, using and 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("");

    // Wait for connection
    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();
}

When I compile it, it says

'content' is not captured

I thought it may be from the input, and I tried to name it "Basic" for the start, but it still failed.

  • @jwpat7 This code is (in most of its part) took from other examples from libraries and I am not (very) good at this so I can't figure out what do you mean by corecting it. – Mihai Barbu Jan 24 '17 at 20:10
  • Possibly Lambda of a lambda : the function is not captured will be more useful than my previous comment. – James Waldby - jwpat7 Jan 24 '17 at 20:17
  • And that would be used here like : " server.on("/led" , [content](){..... " ? – Mihai Barbu Jan 24 '17 at 20:21
  • Something like that -- But I'm not familiar enough with C++ lambda syntax to say, perhaps someone else will know. – James Waldby - jwpat7 Jan 24 '17 at 20:26
  • Ok , I am not in a hurry anyway. Many thanks ! – Mihai Barbu Jan 24 '17 at 20:27
3

Let's look at a simpler example:

void setup ()
{
  String content = "Basic";

  attachInterrupt (digitalPinToInterrupt (2),
                   []()
  {
    Serial.println(content);
  }, 

  FALLING );

}  // end of setup

void loop () { }

This gives the error:

/tmp/arduino_modified_sketch_182173/sketch_jan25a.ino: In lambda function:
sketch_jan25a:8: error: 'content' is not captured
     Serial.println(content);

Why? Because you are using a local variable content in a lambda function which runs at global scope. That is, content is not available to it, because it is inside setup.

To capture it, you can put it in the capture list:

  attachInterrupt (digitalPinToInterrupt (2),
                   [content]()  // capture content

However I found that my example doesn't compile even then.


I think the reason for that can be found here: Lambda Functions in C++11 - the Definitive Guide

How are Lambda Closures Implemented?

So how does the magic of variable capture really work? It turns out that the way lambdas are implemented is by creating a small class; this class overloads the operator(), so that it acts just like a function. A lambda function is an instance of this class; when the class is constructed, any variables in the surrounding enviroment are passed into the constructor of the lambda function class and saved as member variables.

You can't pass an instance of a class to attachInterrupt because there is a hidden *this variable that needs to be passed to class instances, and ISRs don't do that.

Now your example isn't an ISR, but probably the same remarks apply.


I don't think there is an enormous amount of point of using lambda functions here. If you must, move content inside the lambda, since that is where you are using it.

Or failing that, make it global scope.


The closest I could get to something that compiled was:

void setup ()
{
  const int content = 42;

  attachInterrupt (digitalPinToInterrupt (2),
                   [=]()
  {
    Serial.println(content);
  },

  FALLING );

}  // end of setup

void loop () { }

Honestly though, I think using lambda functions here just makes your code obscure.

| improve this answer | |
  • I wrote led instead of lcd. What I am trying to do is : calling a page from the esp8266 that gives me an input box and a submit button. I want to print on the lcd what is written in that box. – Mihai Barbu Jan 25 '17 at 19:26
  • Thanks , it solved my error , but , now I have another one : 'void setup()': lcdWirelessPrint:69: error: expected ')' before 'server' server.on("/", handleRoot); ^ exit status 1 'User' was not declared in this scope Another question is , how/where do I declare the name of the variable that I want to have the name of the input . – Mihai Barbu Jan 25 '17 at 19:46
  • This sounds like a different question. I suggest you start a new question and post this new code. – Nick Gammon Jan 25 '17 at 20:39
  • Ok , I didn't wanted to open too many , thought it would be anoying. – Mihai Barbu Jan 25 '17 at 20:53
0

Are you looking at the last compiler error ? The first one is the most most important one. In the preferences, the compiler output can be turned on to show more. Then scroll up to see the first compiler error. The compiler has troubles with the `` at the very end of your sketch.

| improve this answer | |
  • They are normal " , they changed when I pasted here. I'll check it tomorrow anyway. – Mihai Barbu Jan 24 '17 at 20:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.