Modifying a sketch

Hello, I am new to arduino sketch and i need a little help modifying this sketch. This is a sketch that runs on a esp8266 and talks to a raspberry PI to work with Amazon echo to turn on and off lights . This code is setup to tun GPIO 2 HIGH or LOW accordingly to the web address is gets /gpio/0 or /gpio/1. Now what i am tying to do is control multiple pins with adding more web addresses /gpio/2,/gpio/3. This is how the raspberry pi sends the commands [‘lights’, rest_api_handler(‘http://192.168.0.31/gpio/1’, ‘http://192.168.0.31/gpio/0’)],
what i want to do is use the same ip address but a different extension to activate a different pin. i hope this makes sense to you guys. The problem that i get is when Amazon echo sends a commend to raspberry pi then raspberry pi sends it to the arduino its needs a response back. The way the sketch is right now works perfectly fine i just want to control more pins on the same MCU. Thank you in advance.

WiFiWebServer.ino (2.17 KB)

If there's only a small amount of code, please just post it, in code tags.

sorry

#include <ESP8266WiFi.h>

const char* ssid = "xxx";
const char* password = "xxx";

// Create an instance of the server
// specify the port to listen on as an argument
WiFiServer server(80);

void setup() {
  Serial.begin(115200);
  delay(10);

  // prepare GPIO2

   pinMode(2, OUTPUT);
  digitalWrite(2, 0);
  
   
  // Connect to WiFi network
  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);
  
  WiFi.begin(ssid, password);
  
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");
  
  // Start the server
  server.begin();
  Serial.println("Server started");

  // Print the IP address
  Serial.println(WiFi.localIP());
}

void loop() {
  // Check if a client has connected
  WiFiClient client = server.available();
  if (!client) {
    return;
  }
  
  // Wait until the client sends some data
  Serial.println("new client");
  while(!client.available()){
    delay(1);
  }
  
  // Read the first line of the request
  String req = client.readStringUntil('\r');
  Serial.println(req);
  client.flush();

  // Match the request
  int val;
  if (req.indexOf("/gpio/0") != -1)
    val = 0;
  else if (req.indexOf("/gpio/1") != -1)
    val = 1;
  else {
    Serial.println("invalid request");
    client.stop();
    return;
  }

  // Set GPIO2 according to the request
 
  digitalWrite(2, val);
  client.flush();


  // Prepare the response
  String s = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\n<html>\r\nGPIO is now ";
  s += (val)?"high":"low";
  s += "</html>\n";

  // Send the response to the client
  client.print(s);
  delay(1);
  Serial.println("Client disonnected");

  // The client will actually be disconnected 
  // when the function returns and 'client' object is detroyed
  if (req.indexOf("/gpio/0") != -1)
    val = 0;
  else if (req.indexOf("/gpio/1") != -1)
    val = 1;
  else if (req.indexOf("/gpio/2") != -1)
    val = 2;
  else if (req.indexOf("/gpio/3") != -1)
    val = 3;

... and so on and so forth, all the way up the Yangtze.

thank you for the replay but isnt the val=0 and val=1 the High and LOW for digital pin? digitalWrite(2, val);

You can create any system of encoding for control that you like. It's completely arbitrary and up to you. For example, you could digitalWrite(3, LOW) when val=3.

but isnt the val=0 and val=1 the High and LOW for digital pin? digitalWrite(2, val);

You tell US. You know what you are sending, and why. What do you intend to send for the next pin? What IS the next pin?

you just have to be smarter in that part of the code

 // Match the request
  int val;
  if (req.indexOf("/gpio/0") != -1)
    val = 0;
  else if (req.indexOf("/gpio/1") != -1)
    val = 1;
  else {
    Serial.println("invalid request");
    client.stop();
    return;
  }

what this does is to check the URI that was sent to your ESP and scan for "/gpio/0" or "/gpio/1" because it knows it has only one GPIO pin to play with

what you want to do is declare another variable int pinToChange=-1;

scan for

"/gpio2/0" or "/gpio2/1" --> then set the pinToChange = 2; and val = 0 or 1 according to the end of the string "/gpio5/0" or "/gpio5/1" --> then set the pinToChange = 5; and val = 0 or 1 according to the end of the string "/gpio8/0" or "/gpio8/1" --> then set the pinToChange = 8; and val = 0 or 1 according to the end of the string (and if no match print the invalid request and stop the client)

after that, if pinToChange is not == -1 then you have in pinToChange the pin to which you need to impact and in val the value you need to set so instead of doing

digitalWrite(2, val);

you do

digitalWrite(pinToChange, val);

this is brute force, you can be a bit smarter in parsing the URL to extract gpio## and what the value is with a small parser.

@PaulS

['lights', rest_api_handler('http://192.168.0.31/gpio/1', 'http://192.168.0.31/gpio/0')], for GPIO 2

['outside lights', rest_api_handler('http://192.168.0.31/gpio/2', 'http://192.168.0.31/gpio/3')], for GPIO 5

so basically http://192.168.0.31/gpio/2 will set GPIO pin 5 to HIGH and http://192.168.0.31/gpio/3 will set GPIO pin to LOW

J-M-L: "/gpio2/0" or "/gpio2/1" --> then set the pinToChange = 2; and val = 0 or 1 according to the end of the string

Like that.

Thank you all. looks like something as simple is this worked.

  int val;
  if (req.indexOf("/gpio/0") != -1)
    digitalWrite(2, 1);
    val = 0;
  if (req.indexOf("/gpio/1") != -1)
    digitalWrite(2, 0);
    val = 1;
      if (req.indexOf("/gpio/2") != -1)
    digitalWrite(5, 1);
    val = 0;
   if (req.indexOf("/gpio/3") != -1)
    digitalWrite(5, 0);
    val = 1;

Yes. Why are you still using val? It is now redundant.

Yes, you don't need val anymore (especially the way you save it, it's the opposite of what you actually set the pin to)

Only challenge with the code you have now though is that the code is hard to maintain and from the client side difficult to understand what you are actually requesting - you'll need to read the doc everytime :).

That's why I was suggesting to change the URL to be clearer.

"/gpio2/1" so that your URL tells you which pin you want to play with and what value to set it to.

@J-m-l you are absolutely right. Hooking it up to a 6 chanel relay will be nightmare creeping track of the pins like this.
The reason why I have high and low that way cuz they are in relay NC so in case the wifi is out I will still be able to use the outlet just can’t controle it.

@aarg it will works without Val the relay switches on and off but Amazon Echo responds “sorry the device is snot responding” My guess is she needs a feedback from this part of the code

// Prepare the response
String s = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n\r\n\r\nGPIO is now ";
s += (val)?“high”:“low”;
s += “\n”;

Thanks again.

indeed - you use bar there but is it used server side to represent visually the value of the PIN?

if not just return “OK”

 String s = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\n<html>[b]OK[/b]</html>\n";

@J-M-L Tbh I don't know if you do what will be in the python code and I know nothing at far as python coding. If you want I can upload the python code.

Feel free to share

Toi can also be bold and just try the line I provided and see if all works :-)

Perfect the code that you gave me worked. Thank you :slight_smile:

// Match the request
  int val;
  if (req.indexOf("/gpio/2/0") != -1)
    digitalWrite(2, 1);
  if (req.indexOf("/gpio/2/1") != -1)
    digitalWrite(2, 0);
  if (req.indexOf("/gpio/5/0") != -1)
    digitalWrite(5, 1);
  if (req.indexOf("/gpio/5/1") != -1)
    digitalWrite(5, 0);
  
  
  client.flush();


  // Prepare the response
 String s = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\n<html>OK</html>\n";

  // Send the response to the client
  client.print(s);
  delay(1);
  Serial.println("Client disonnected");

this is what i get on serial monitor

WiFi connected
Server started
192.168.0.25
new client
GET /gpio/5/0 HTTP/1.1
Client disonnected
new client
GET /gpio/2/1 HTTP/1.1
Client disonnected
new client
GET /gpio/2/0 HTTP/1.1
Client disonnected
new client
GET /gpio/5/1 HTTP/1.1
Client disonnected

python code is to long to upload link to gethub

this is how i have it

FAUXMOS = [
    ['lights', rest_api_handler('http://192.168.0.31/gpio/1', 'http://192.168.0.31/gpio/0')],
	['printer', rest_api_handler('http://192.168.0.21/gpio/1', 'http://192.168.0.21/gpio/0')],
	['table', rest_api_handler('http://192.168.0.25/gpio/2/1', 'http://192.168.0.25/gpio/2/0')],
	['chair', rest_api_handler('http://192.168.0.25/gpio/5/1', 'http://192.168.0.25/gpio/5/0')],