Help with just manipulating a string variable..i bet its an easy answer!

Hi all,

Been playing around with arduinos and esp8266s for about 8 months now and started with nodemcu and scripting in lua. I needed to do a different project and decided to use the arduino ide instead. However, nodemcu and arduino programming is just different enough in terms of using global variables where I cant seem to figure out how to do something as simple as changing a global variable! Please help. My code is below.

What Im trying to do is have the state of the door show up in the webpage always show the last state, even when visiting the page again at a later time. Can someone point me in the right direction?

EDIT: I have not defined a global variable in the sketch for "relay_status" as i know it does not work outside the two handleroot and relaycontrol functions.

The pertinent bits are in the void handleroot and void relaycontrol functions

#include <DNSServer.h>
#include <WiFiManager.h>
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <WiFiUDP.h>
#include <Servo.h> 

// Web Page Data
String form1 = "<html><center><head><meta content='text/html; charset=utf-8'><title>PROJECTOR DOOR</title></head><body><h1 style='font-family:verdana;'>PROJECTOR DOOR</h1><form action='led' method='GET'><table border=\'1\' width=\'400\' bordercolorlight=\'#000000\' bordercolordark=\'#008000\' height=\'137\'><tr><td style=\'border-style: solid; border-width: 1px\' width=\'91\' bgcolor=\'#339FFF\' align=\'center\'><b><font face=\'Verdana\' size=\'2\' color=\'#FFFF99\'>PROJECTOR DOOR:</font><p><font face=\'Verdana\' size=\'6\' color=\'#FFFFFF\'>";
String form2 = "</font><p></b></td></tr><tr><td style=\'border-style: solid; border-width: 1px\' width=\'91\' align=\'center\'><p>
<input type='submit' name='state' value='OPEN' style='height:100px; width:300px; font-size: 30px;'><p>
</b></font></a></td><tr><td style=\'border-style: solid; border-width: 1px\' width=\'91\' align=\'center\'><p>
<input type='submit' name='state' value='CLOSE' style='height:100px; width:300px; font-size: 30px;'><p>
</b></font></td><font face=\'Verdana\'></b></font></td></tr></table></form>";
 
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------

...


//-----------------------------------------------------------------------
// HTTP Server
//-----------------------------------------------------------------------


// ROOT PAGE
void handleRoot()

{
  Serial.println("handleRoot");

  String form3 = form1;
  form3 += form2;
  
  server.send(200, "text/html", form3);
}

// RELAY CONTROL ROUTINE
void relaycontrol() 
{
  Serial.println("relaycontrol");

  String state=server.arg("state");
  if (state == "OPEN") 
  {
    myservo.write(servo_on_pos);
    delay(15);
    Serial.println("door open");
    String relay_status = "OPEN";
        
    String form3 = form1;
    form3 += relay_status;
    form3 += form2;
    
    server.send(200, "text/html", form3);
  }

  else if (state == "CLOSE") 
  
  {
    myservo.write(servo_off_pos);
    delay(15);
    Serial.println("door closed");
    String relay_status = "CLOSED";
    
    String form3 = form1;
    form3 += relay_status;
    form3 += form2;
    
    server.send(200, "text/html", form3);
  }
 
    String form3 = form1;
    form3 += form2;

    server.send(200, "text/html", form3);
}



void handleNotFound()
{
  Serial.println("handleNotFound()");
  
  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);
}


//-----------------------------------------------------------------------
//-----------------------------------------------------------------------

void setup()
{
  // Open serial communications and wait for port to open:
  Serial.begin(115200);
  Serial.println();

  // Initialize LED pin
  pinMode(SERVO_PIN, OUTPUT);
  //digitalWrite(SERVO_PIN, 0);

  // Initialize Servo
  myservo.write(servo_start_pos); //set initial servo position if desired
  myservo.attach(SERVO_PIN, servo_min, servo_max);

  
  //WIFI configuration captive portal
  WiFiManager wifiManager;
  //set custom ip for portal
  wifiManager.setAPStaticIPConfig(IPAddress(192,168,2,1), IPAddress(192,168,2,1), IPAddress(255,255,255,0));
  wifiManager.setSTAStaticIPConfig(IPAddress(192,168,1,36), IPAddress(192,168,1,1), IPAddress(255,255,255,0));
  wifiManager.autoConnect("PROJDOOR", "snowy123");
  //wifiManager.startConfigPortal("OnDemandAP");
  
  // print your WiFi info
  IPAddress ip = WiFi.localIP();
  Serial.println();
  Serial.print("Connected to ");
  Serial.print(WiFi.SSID());
  Serial.print(" with IP: ");
  Serial.println(ip);
  
  //UDP Server
  Udp.beginMulticast(WiFi.localIP(),  ipMulti, portMulti);
  Serial.print("Udp multicast server started at ");
  Serial.print(ipMulti);
  Serial.print(":");
  Serial.println(portMulti);
  
  //Web Server
  server.on("/", handleRoot);
  server.on("/led", relaycontrol);
  server.on("/setup.xml", handleSetupXml);
  server.on("/upnp/control/basicevent1", handleUpnpControl);
  server.onNotFound(handleNotFound);
  server.begin();
  Serial.print("HTTP server started on port ");
  Serial.println(webserverPort);
}



void loop()
{
  UdpMulticastServerLoop();   //UDP multicast receiver

  server.handleClient();      //Webserver
}

EDIT: I have not defined a global variable in the sketch for "relay_status" as i know it does not work outside the two handleroot and relaycontrol functions.

Not sure how you arrived at this conclusion. In arduino global variables should work like local variables (ie if you move a declaration from local to global scope nothing else needs to change in order to access and update it- naturally you may experience unwanted side effects from subroutines sharing global variables). Not sure why its not working that way for you.

What happens with the code you now have and how does it differ from what you hope for? I note that your html in form2 lacks the closing tags "" but I dont think this is the cause of your issues.

I totally missed the missing html tags. FIXED. Thank you!

As for my testing, here is what ive updated:

#include <DNSServer.h>
#include <WiFiManager.h>
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <WiFiUDP.h>
#include <Servo.h> 

...

// Web Page Data
String form1 = "<html><center><head><meta content='text/html; charset=utf-8'><title>PROJECTOR DOOR</title></head><body><h1 style='font-family:verdana;'>PROJECTOR DOOR</h1><form action='led' method='GET'><table border=\'1\' width=\'400\' bordercolorlight=\'#000000\' bordercolordark=\'#008000\' height=\'137\'><tr><td style=\'border-style: solid; border-width: 1px\' width=\'91\' bgcolor=\'#339FFF\' align=\'center\'><b><font face=\'Verdana\' size=\'2\' color=\'#FFFF99\'>PROJECTOR DOOR:</font><p><font face=\'Verdana\' size=\'6\' color=\'#FFFFFF\'>";
String form2 = "</font><p></b></td></tr><tr><td style=\'border-style: solid; border-width: 1px\' width=\'91\' align=\'center\'><p>
<input type='submit' name='state' value='OPEN' style='height:100px; width:300px; font-size: 30px;'><p>
</b></font></a></td><tr><td style=\'border-style: solid; border-width: 1px\' width=\'91\' align=\'center\'><p>
<input type='submit' name='state' value='CLOSE' style='height:100px; width:300px; font-size: 30px;'><p>
</b></font></td><font face=\'Verdana\'></b></font></td></tr></table></form></center></body></html>";

// Relay Variable

String relay_status1 = "CLOSED";

...

// ROOT PAGE
void handleRoot()

{
  Serial.println("handleRoot");

  //String form3 = form1;
  //form3 += form2;

  String form3 = form1;
    form3 += relay_status1;
    form3 += form2;
    
  server.send(200, "text/html", form3);
}

// RELAY CONTROL ROUTINE
void relaycontrol() 
{
  Serial.println("relaycontrol");

  String state=server.arg("state");
  if (state == "OPEN") 
  {
    myservo.write(servo_on_pos);
    delay(15);
    Serial.println("door open");
    String relay_status1 = "OPEN";
            
    String form3 = form1;
    form3 += relay_status1;
    form3 += form2;
    
    server.send(200, "text/html", form3);
  }

  else if (state == "CLOSE") 
  
  {
    myservo.write(servo_off_pos);
    delay(15);
    Serial.println("door closed");
    String relay_status1 = "CLOSED";
    
    String form3 = form1;
    form3 += relay_status1;
    form3 += form2;
    
    server.send(200, "text/html", form3);
  }
 
    String form3 = form1;
    form3 += form2;

    server.send(200, "text/html", form3);
}

Everything appears to work great on first run... On visit to the root ip address, it will show the status as closed (which it grabs from the global variable). However, if I click on the open button, it should set the global variable to "OPEN." However if i close the browser and revisit the IP, it will still show "CLOSED" instead of "OPEN" which I assume it should since I clicked on the OPEN button to set the variable. Am I just not updating the global variable correctly (this is how I do it in nodemcu lua)?

thanks for your help so far!

It seems you are re-declaring relay_status1 as a local variable inside the relaycontrol() function so this is hiding the global variable of the same name.

try it something like

 void relaycontrol()
{
  Serial.println("relaycontrol");

  String state=server.arg("state");
  if (state == "OPEN")
  {
    myservo.write(servo_on_pos);
    delay(15);
    Serial.println("door open");
    relay_status1 = "OPEN";
           
    String form3 = form1;
    form3 += relay_status1;
    form3 += form2;
   
    server.send(200, "text/html", form3);
  }

  else if (state == "CLOSE")
 
  {
    myservo.write(servo_off_pos);
    delay(15);
    Serial.println("door closed");
    relay_status1 = "CLOSED";
   
    String form3 = form1;
    form3 += relay_status1;
    form3 += form2;
   
    server.send(200, "text/html", form3);
  }
 
    String form3 = form1;
    form3 += form2;

    server.send(200, "text/html", form3);
}

That was it. THANK YOU!!