HTTP Server to control various "programs"

Hi, am very new to Arduino IDE and am having troubles getting to grips with some of the programming. I have a project where I am looking for some guidance fo rhow best it should be done.

Essentially what I already have working is:
NodeMCU board running HTTP server connected to WiFI network.
Different URLs setup eg <<IP_Address>>/programA
<<IP_Address>>/programB etc
I also have some WS8266 LEDs connected and have working programs using the Adafruit NeoPixel commands.

What I need to happen is:
If a URL of /programA is called, I need it to run one Adafruit led program (eg rainbow) and keep repeating that "program".
But I need it to be able to stop and run a different program if a different URL is called eg /programB.

I'm confused as to which parts should go in void setup and which parts in voip loop

I'm assuming I need something like:
When URL /programA is called, set variable "program_name" to "A".
Then have a loop that says while "program_name" = "A" run (and loop) this sub-program (eg rainbow led).
Then when URL /programB is called, change the variable and have a different "while" loop run a different sub-program.

But every time I play around with this, once the first program is running, nothing is able to override it and stop it ready to run another program, the loop just runs endlessly.

I've tried it just with the very simple blink test but once a simple program such as:

  digitalWrite(LED_BUILTIN, LOW);
  Serial.print("LED is BLINK ON\n");
  delay(500);  
  digitalWrite(LED_BUILTIN, HIGH);
  Serial.print("LED is BLINK OFF\n"); 
  delay(500);

has been triggered via the URL, it just runs endlessly (which is what I want), but it cannot be stopped or overridden by a different URL being called.

Any suggestions greatly appreciated.

Does it ever get a chance to read the URL again or is it stuck in a loop ?

Stuck in a loop and doesn't respond to any other URLs.

These are my blink "programs" which work because they don't repeat in any way. They just run once at the moment.

>   server.on("/blink-fast", []() {
>     digitalWrite(LED_BUILTIN, LOW);
>     Serial.print("LED is BLINK ON\n");
>     delay(500);  
>     digitalWrite(LED_BUILTIN, HIGH);
>     Serial.print("LED is BLINK OFF\n"); 
>     delay(500);
>   });
> 
>   server.on("/blink-slow", []() {
>     digitalWrite(LED_BUILTIN, LOW);
>     Serial.print("LED is BLINK ON\n");
>     delay(5000);  
>     digitalWrite(LED_BUILTIN, HIGH);
>     Serial.print("LED is BLINK OFF\n"); 
>     delay(5000);
>   });

And they are inside of void setup

If I put any type of for or while commands on these blink programs, they run continuously and cannot be stopped, or another URL (or "program") cannot be run in their place.

The void loop just has

void loop(void) {
  server.handleClient();
  MDNS.update();
}

In short, I just want a ESP8266 HTTP Webserver, that will run different programs (on repeat - because they are LED effects) when different HTTP url's are called.

I think I've start off far too complicated and have tried so many "example" files that I've lost track of which ones work and are needed, and which ones are completely the wrong thing :rofl:

Can you post the full code of what you've got so far?

#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>

#ifndef STASSID
#define STASSID "my_network"
#define STAPSK  "my_password"
#endif

const char* ssid = STASSID;
const char* password = STAPSK;

ESP8266WebServer server(80);

const int led = 13;

void handleRoot() {
  digitalWrite(led, 1);
  server.send(200, "text/plain", "hello from esp8266!\r\n");
  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.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  Serial.println("");

  pinMode(LED_BUILTIN, OUTPUT);     // Initialize the LED_BUILTIN pin as an output

  // 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");
  }

  server.on("/", handleRoot);


  server.on("/led-on", []() {
    server.send(200, "text/plain", "LED is ON");
    digitalWrite(LED_BUILTIN, LOW);   // Turn the LED on
    Serial.print("LED is ON ");
  });

  server.on("/led-off", []() {
    server.send(200, "text/plain", "LED is OFF");
    digitalWrite(LED_BUILTIN, HIGH);
    Serial.print("LED is OFF ");
  });

  server.on("/blink-fast", []() {
    server.send(200, "text/plain", "LED blink fast");
    digitalWrite(LED_BUILTIN, LOW);
    Serial.print("LED is BLINK ON\n");
    delay(500);  
    digitalWrite(LED_BUILTIN, HIGH);
    Serial.print("LED is BLINK OFF\n"); 
    delay(500);
  });

  server.on("/blink-slow", []() {
    while(true) {
      server.send(200, "text/plain", "LED blink slow");
      digitalWrite(LED_BUILTIN, LOW);
      Serial.print("LED is BLINK ON\n");
      delay(5000);  
      digitalWrite(LED_BUILTIN, HIGH);
      Serial.print("LED is BLINK OFF\n"); 
      delay(5000);
    }
  });

  server.onNotFound(handleNotFound);

  server.begin();
  Serial.println("HTTP server started");
}

void loop(void) {
  server.handleClient();
  MDNS.update();
}

On the above code:

  • HTTP requests to /led-on or /led-off function correctly.
  • HTTP requests to /blink-fast work, but only run once as there is no loop/repeat.
  • If you HTTP request /blink-slow it repeats the blink as expected, but it then prevents any future requests (due to the while loop) so you are stuck until a manual reset of the system.

There appears to be some confusion in your code between an LED on pin 13, which is the built in LED of most AVR based boards and LED_BUILTIN which is pin D2

It's actually a NodeMCU board, and the LED does work okay with the settings above. I'm only using the LED as an example, once I can go the coding sorted the "blink" function will actually be controlling a line of LEDs using the Adafruit Neopixel. But I just wanted to get the HTTP functions to work first.

this has it ESP-IDF Programming Guide - ESP32 - — ESP-IDF Programming Guide latest documentation