This is where it gets outside of my realm of knowledge. As far as I know it should be, you can run two seperate wepages. Just not using the Arduino command line. I came across this tutorial where they use NodeMCU to serve multiple pages: ESP8266 Webserver Serving Multiple Pages : 5 Steps - Instructables
Which devices were you using to control the motors? iPhones etc. I youre on an Apple device you can use ‘Guided Access’ to limit the functionality of the screen so each device is only able to control one motor by blocking touches to the other buttons.
Hi guys,
the following issue occurs with the current sketch setup:
Running two devices on the web page at the same time works until one device seems to ‘take over’ and then will not allow the other device to control either of the buttons. Even if the ‘master’ device that took over is disconnected from the ESP32 microcontroller, the second device seems only to ‘wake up’ and regain control when I’ve pressed on the reset button on the microcontroller. Obviously not ideal as I will not have access to the reset button in the final setup of the project.
Another thing, can the code be changed so that the pushbuttons on the web page work momentarily? That is, the motor has power while the button is pushed and then turns off when the finger is removed from the button.
I’m still have not worked out how to run two web pages simultaneously with one button on each web page.
Oops, I thought I had linked the tutorial on the reply above, should be there now!
The methods that are being used to serve the webpage are perfect for one device - providing up to date information for one client is easy but two at the same time is a bit harder. The easiest get out of jail free card would be to grab another ESP32 to host a seperate server for another device. David has an awesome guide on getting a cheaper ESP32 working on this topic: FireBeetle ESP32-E IoT Microcontroller with header (Supports Wi-Fi & Bluetooth) (DFR0654-F)
As for making the buttons momentary, the webpage is constructed using pure HTML(and a little bit of CSS to clean up the formatting). While simple it doesnt allow for a momentary property to be set, more about buttons here:HTML button tag
NodeMCU might have some functionality where you can setup a momentary button though.
I’ve been doing some research (others call it: watching YouTube videos!) and I’ve come across this one:
I was wondering if it was along the lines of what I am trying to achieve?
I can’t tell if it is and I’m a little concerned about mucking around with the code which works perfectly (on one device).
I will be trying to have the two motors working on two different devices at the same time, or remove the code for one motor altogether and just have one ESP32 controlling one motor via one device.
No good Liam… I’m not getting my head around what code I need to use to modify the existing code. I can’t seem to grasp the concepts of adding Techturialsx’s code to your code and have it working on two different web pages.
All I’m getting is brain drain… I’m either nodding off or getting a headache trying to comprehend the tutorials.
// Load Wi-Fi library
#include <WiFi.h>
#include <ESPAsyncWebServer.h>
// Replace with your network credentials
const char* ssid = "ESP32-Access-Point";
const char* password = "123";
// Set web server port numbers to 80 and 81
AsyncWebServer server1(80);
AsyncWebServer server2(81);
// Variable to store the HTTP request
String header;
// Auxiliar variables to store the current output state
String output27State = "off";
String output15State = "off";
// --------------------------------- Setting up the motors ---------------------------------
// Motor A
int motor1Pin1 = 27;
int motor1Pin2 = 33;
// Motor B
int motor2Pin1 = 15;
int motor2Pin2 = 32;
void setup() {
Serial.begin(115200);
// --------------------------------- Init. the motor pins ---------------------------------
// sets the pins of Motor A as outputs:
pinMode(motor1Pin1, OUTPUT);
pinMode(motor1Pin2, OUTPUT);
// sets the pins of Motor B as outputs:
pinMode(motor2Pin1, OUTPUT);
pinMode(motor2Pin2, OUTPUT);
// --------------------------------- Init. the Wifi point and connect to WiFi --------------------------------
Serial.print("Setting AP (Access Point)..."); // Connect to Wi-Fi network with SSID and password
WiFi.softAP(ssid, password); // Remove the password parameter, if you want the AP (Access Point) to be open
IPAddress IP = WiFi.softAPIP();
Serial.print("AP IP address: ");
Serial.println(IP);
server1.on
server2.on
server1.begin();
server2.begin();
}
void loop() {
WiFiClient client = server.available(); // Listen for incoming clients
if (client) { // If a new client connects,
Serial.println("New Client."); // print a message out in the serial port
String currentLine = ""; // make a String to hold incoming data from the client
while (client.connected()) { // loop while the client's connected
if (client.available()) { // if there's bytes to read from the client,
char c = client.read(); // read a byte, then
Serial.write(c); // print it out the serial monitor
header += c;
if (c == '\n') { // if the byte is a newline character
// if the current line is blank, you got two newline characters in a row.
if (currentLine.length() == 0) { // that's the end of the client HTTP request, so send a response:
client.println("HTTP/1.1 200 OK"); // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
client.println("Content-type:text/html"); // and a content-type so the client knows what's coming, then a blank line:
client.println("Connection: close");
client.println();
// turns the GPIOs on and off
// **************************** Here is the code we are after, all of the code surrounding this handles the webserver itself ********
if (header.indexOf("GET /27/on") >= 0) { // Start motor A
Serial.println("Motor on GPIO 27 starting");
output27State = "on";
digitalWrite(motor1Pin1, HIGH);
digitalWrite(motor1Pin2, LOW);
} else if (header.indexOf("GET /27/off") >= 0) { // Stop motor A
Serial.println("Motor on GPIO 27 stopping");
output27State = "off";
digitalWrite(motor1Pin1, LOW);
digitalWrite(motor1Pin2, LOW);
} else if (header.indexOf("GET /15/on") >= 0) { // Start motor B
Serial.println("Motor on GPIO 15 starting");
output15State = "on";
digitalWrite(motor2Pin1, HIGH);
digitalWrite(motor2Pin2, LOW);
} else if (header.indexOf("GET /15/off") >= 0) { // Stop motor B
Serial.println("Motor on GPIO 15 stopping");
output15State = "off";
digitalWrite(motor2Pin1, LOW);
digitalWrite(motor2Pin2, LOW);
}
// Display the HTML web page
client.println("<!DOCTYPE html><html>");
client.println("<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">");
client.println("<link rel=\"icon\" href=\"data:,\">");
// CSS to style the on/off buttons
// Feel free to change the background-color and font-size attributes to fit your preferences
client.println("<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}");
client.println(".button { background-color: #4CAF50; border: none; color: white; padding: 16px 40px;");
client.println("text-decoration: none; font-size: 30px; margin: 2px; cursor: pointer;}");
client.println(".button2 {background-color: #e80e1c;}</style></head>");
// Web Page Heading
client.println("<body><h1>POWER ANCHOR</h1>");
// Display current state, and ON/OFF buttons for GPIO 27
client.println("<p>UPPER RINGS - State " + output27State + "</p>");
// If the output27State is off, it displays the ON button
if (output27State == "off") {
client.println("<p><a href=\"/27/on\"><button class=\"button\">ON</button></a></p>");
} else {
client.println("<p><a href=\"/27/off\"><button class=\"button button2\">OFF</button></a></p>");
}
// Display current state, and ON/OFF buttons for GPIO 15
client.println("<p>LOWER RINGS - State " + output15State + "</p>");
// If the output15State is off, it displays the ON button
if (output15State == "off") {
client.println("<p><a href=\"/15/on\"><button class=\"button\">ON</button></a></p>");
} else {
client.println("<p><a href=\"/15/off\"><button class=\"button button2\">OFF</button></a></p>");
}
client.println("</body></html>");
// The HTTP response ends with another blank line
client.println();
// Break out of the while loop
break;
} else { // if you got a newline, then clear currentLine
currentLine = "";
}
} else if (c != '\r') { // if you got anything else but a carriage return character,
currentLine += c; // add it to the end of the currentLine
}
}
}
// Clear the header variable
header = "";
// Close the connection
client.stop();
Serial.println("Client disconnected.");
Serial.println("");
}
}
If I wanted the ‘button’ on my iPhone to act like a momentary on button, that is, the button stays on while depressed and turns off when finger is lifted, do I do this by changing the IF code to a WHILE code?
Serial.println("Motor on GPIO 27 starting");
output27State = "on";
digitalWrite(motor1Pin1, HIGH);
digitalWrite(motor1Pin2, LOW);
} else if (header.indexOf("GET /27/off") >= 0) { // Stop motor A
Serial.println("Motor on GPIO 27 stopping");
output27State = "off";
digitalWrite(motor1Pin1, LOW);
digitalWrite(motor1Pin2, LOW);
Or, if not the above, what command or code would do it?
Unfortunately this one rests on how a webpage works instead of the Arduino itself.
I breifly touched on it here but wasnt too in depth as I’m not sure if there are any ways around it.
I did however come across these receiver and transmitter boards which went live on the Core site very recently. You cant pair two transmitters to the one receiver from the looks of it but the Gravity connector will let you make a long wire to connect two buttons so students can be sitting apart a bit.