Webserver a garbled mess when adding servos

Hi all,

I have a WebServer hosted on an arduino Uno. On it are some check boxes for activating some servos, these in turn press some physical buttons etc.

I have the entire system working for one servo, however, when I start adding more servos (I'll need 8 total) the webpage starts getting garbled, with strange characters, and it duplicates down the page.

Image 1:

This should really look like the following image. Which works fine and triggers the first relay as expected (Only one relay is active in this code)

Image 2:
image

I'm assuming the issue is related to memory, however the IDE seems to think that is fine so far.

Image 3:

Here is my code thus far. I have commented out the servos and once I uncomment four or five, the WebServer turns to soup.

#include <SPI.h>
#include <Ethernet.h>
#include <Servo.h> 

Servo metisservo;
Servo carposervo;
Servo elaraservo;
Servo lysitheaservo;
Servo diaservo;
Servo helikeservo;
Servo valetudoservo;
Servo eukaledeservo;
  
int pos = 0; 
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };   //physical mac address
byte ip[] = { 192, 168, 0, 178 };                      //ip in lan (that's what you need to use in your browser. ("192.168.1.178")
byte gateway[] = { 192, 168, 0, 1 };                   //internet access via router
byte subnet[] = { 255, 255, 255, 0 };                  //subnet mask
EthernetServer server(80);                             //server port     
String readString;
String HTTP_req;
boolean LED_status = 0;

void setup() {
 // Open serial communications and wait for port to open:
  Serial.begin(9600);
   while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }

  metisservo.attach(6);
  //carposervo.attach(7);
  //elaraservo.attach(8);
  //lysitheaservo.attach(9);
  //diaservo.attach(10);
  //helikeservo.attach(11);
  //valetudoservo.attach(12);
  //eukaledeservo.attach(13);
  
  metisservo.write(0);
  //carposervo.write(0);
  //elaraservo.write(0);
  //lysitheaservo.write(0);
  //diaservo.write(0);
  //helikeservo.write(0);
  //valetudoservo.write(0);
  //eukaledeservo.write(0);
  
  // start the Ethernet connection and the server:
  Ethernet.begin(mac, ip, gateway, subnet);
  server.begin();
  Serial.print("server is at ");
  Serial.println(Ethernet.localIP());
}


void loop() {
  
TIMSK0=0; // Fixes Servo Jitter

doHttp();

}

void delayMilliseconds(long milliseconds)
{
  while (milliseconds >= 1)
  {
    delayMicroseconds(1000) ;  // actually this value might be a bit less to allow for loop overheads
    milliseconds -= 1 ;
  }
  //delayMicroseconds(milliseconds)
}

void doHttp(){

  // Create a client connection
  EthernetClient client = server.available();
  if (client) {
    while (client.connected()) {   
      if (client.available()) {
        char c = client.read();
     
        //read char by char HTTP request
        if (readString.length() < 100) {
          //store characters to string
          readString += c;
          //Serial.print(c);
        }

        //if HTTP request has ended
        if (c == '\n') {          
          Serial.println(readString); //print to serial monitor for debuging
   
          client.println(F("HTTP/1.1 200 OK")); //send new page
          client.println(F("Content-Type: text/html"));
          client.println();     
          client.println(F("<HTML>"));
          client.println(F("<BODY>"));
          client.println(F("<p style='font-family:arial;font-size:30px' '><b>Remote Config Erase for TR2 Devices</b></p>"));
          client.println(F("<p style='font-family:arial;font-size:16px' '>Warning! Be careful when refreshing this page!<br />This will resend data that will Factory Reset any devices still cached in the URL</p>"));
          client.println(F("<form action='/check' method=get  name='tickthebox'> <input type='Checkbox' name='metis_check' value='ticked' >  Metis")); client.println(F("<br />"));
          client.println(F("<form action='/check' method=get  name='tickthebox'> <input type='Checkbox' name='carpo_check' value='ticked' >  Carpo")); client.println(F("<br />"));
          client.println(F("<form action='/check' method=get  name='tickthebox'> <input type='Checkbox' name='elara_check' value='ticked' >  Elara")); client.println(F("<br />"));
          client.println(F("<form action='/check' method=get  name='tickthebox'> <input type='Checkbox' name='lysithea_check' value='ticked' >  Lysithea")); client.println(F("<br />"));
          client.println(F("<form action='/check' method=get  name='tickthebox'> <input type='Checkbox' name='dia_check' value='ticked' >  Dia")); client.println(F("<br />"));
          client.println(F("<form action='/check' method=get  name='tickthebox'> <input type='Checkbox' name='helike_check' value='ticked' >  Helike")); client.println(F("<br />"));
          client.println(F("<form action='/check' method=get  name='tickthebox'> <input type='Checkbox' name='valetudo_check' value='ticked' >  Valetudo")); client.println(F("<br />"));
          client.println(F("<form action='/check' method=get  name='tickthebox'> <input type='Checkbox' name='eukalede_check' value='ticked' >  Eukalede")); client.println(F("<br />"));
          client.println(F("<br />")); 
          client.println(F("<input type='submit' value='Reset Checked Devices'></form>"));
          client.println(F("</BODY>"));
          client.println(F("</HTML>"));
     
          delayMilliseconds(1);
          //stopping client
          client.stop();

          
          if (readString.indexOf("check?") >0){
            if (readString.indexOf("metis_check") >0){ metisservo.write(15); }
            //if (readString.indexOf("carpo_check") >0){ carposervo.write(15); }
            //if (readString.indexOf("elara_check") >0){ elaraservo.write(15); }
            //if (readString.indexOf("lysithea_check") >0){ lysitheaservo.write(15); }
            //if (readString.indexOf("dia_check") >0){ diaservo.write(15); }
            //if (readString.indexOf("helike_check") >0){ helikeservo.write(15); }
            //if (readString.indexOf("valetudo_check") >0){ valetudoservo.write(15); }
           // if (readString.indexOf("eukalede_check") >0){ eukaledeservo.write(15); }
              
              
              delayMilliseconds(3000);
              
              metisservo.write(0);
              //carposervo.write(0);
              //elaraservo.write(0);
              //lysitheaservo.write(0);
              //diaservo.write(0);
              //helikeservo.write(0);
              //valetudoservo.write(0);
              //eukaledeservo.write(0);
          }
          //clearing string for next read
          readString="";  
           
        }
       }
    }
}

}

Any suggestions or criticism welcome!

Thanks in advance!

Ideally, you would get rid of the String readString and replace it with a char array. Strings dynamically grow and your processor doesn't have much memory. At the very least, you should pre-allocate the 100 bytes you expect it to use with the .reserve() function.

Also, why the delayMilliseconds() function which blocks and does exactly what delay() does?

Servos introduce electrical noise into the power supply, which can cause program malfunction if they share the same power supply as the Arduino.

If that is the case, power the servos separately, making sure to connect all the grounds.

As mentioned above, on AVR-based Arduinos, Strings can also cause memory problems and program crashes.

Thanks for that advice, I'll change to character arrays and see how it goes.

As for the delayMilliseconds();, I'm using TIMSK0=0; further above which inables the delay(); function. So this workaround gets the job done.

I actually only have the one servo plugged in at the moment and it is on a separate power supply with the ground connected to Arduino ground. I might encounter more issues as I add the physical servos when they arrive in the mail

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.