Web Control over a couple of servos, Pan-Tilt camara

Hi
I’m a newbie with Arduino and processing, but each day i’m working with this i’m happier.

My project is about a web control with Arduino One and Ethernet shield over a couple of servos for pan-tilt movement, and a several camara functions (zoom +/- and focus +/-)

The camera functions works with a 4 BC107 transistors which are operated through four digital outputs.
Servos are connected directly into arduino but externally powered.

Nowadays, I managed to work all the servos and camara functions through Serial Monitor with a simple code but when I try to modify the code for web control, Camara functions works ok with it but servos doesnt works. =(

I dont know if the code is the problem or ethernet trafic or something else…

The code is:

/*
 Proyecto de controlador web para camara
 */

#include  <SPI.h>
#include  <Ethernet.h>
#include  <Servo.h>  // Incluimos la libreria servo

//mac, IP
byte mac[] = { 0x00, 0x02, 0x0A, 0x0D, 0x06, 0x01 };
byte ip[] = { 192, 168, 1, 177 }; //IPAddress ip(192,168,1,177);
byte gateway[] = { 192, 168, 1, 1 }; // ip router
byte subnet[] = { 255, 255, 255, 0 }; // mascara subnet 
EthernetServer server(80); // puerto ethernet 

//pines out Trans
int zoom1 = 7;
int zoom2 = 8;
int foco1 = 2;
int foco2 = 3;
Servo servohor;  // creando el objeto servo para control
Servo servover;  // otro

int servohorP = 110;
int servoverP = 110;
int MaxservoverP = 155;
int MinservoverP = 65;


String readString;

void setup()
{
  
Serial.begin(9600);
//iniciar conexion
Ethernet.begin(mac, ip, gateway, subnet);
server.begin();

  pinMode(2, OUTPUT); //pin selected to control focus+
  pinMode(3, OUTPUT); //pin selected to control focus-
  pinMode(7, OUTPUT); //pin selected to control zoom+
  pinMode(8, OUTPUT); //pin selected to control zoom-
  pinMode(5, OUTPUT);  // Set servo pin as an output pin  
  pinMode(6, OUTPUT);  // Set servo pin as an output pin  
 
  servohor.attach(6);
  servover.attach(5);
  servohor.write(servohorP);
  servover.write(servoverP);
}

void loop()
{

EthernetClient client = server.available();
if (client) 
{
  while (client.connected()) 
  {
    if (client.available()) 
    {
      char c = client.read();
      if(readString.length() < 100) 
      {
      readString += c;
      }
      Serial.print(c); 
      
    if (c == '\n') 
      {
      

     //HTML creacion de formulario
          Serial.println(readString); 

          client.println("HTTP/1.1 200 OK"); 
          client.println("Content-Type: text/html");
          client.println();

          client.println("<HTML>");
          client.println("<HEAD>");
          client.println("<TITLE>Control Camara posicion zoom y foco</TITLE>");
          client.println("</HEAD>");
          client.println("<BODY>");

          client.println("<H1>Arduino, Control Camara posicion zoom y foco</H1>");
         
         //Servohor 
          client.println("<a href=\"/?right\"\">DERECHA</a>");
          client.println("<a href=\"/?center\"\">CENTRO</a>"); 
          client.println("<a href=\"/?left\"\">IZQUIERDA</a>"); 
          
          //servover
          client.println("<a href=\"/?up\"\">ARRIBA</a>");
          client.println("<a href=\"/?mid\"\">CENTRO</a>"); 
          client.println("<a href=\"/?down\"\">ABAJO</a>"); 
          
          // zoom y foco
          client.println("<a href=\"/?zoom1\"\">ZOOM+</a>");
          client.println("<a href=\"/?zoom2\"\">ZOOM-</a>");
          client.println("<a href=\"/?foco1\"\">FOCO+</a>");
          client.println("<a href=\"/?foco2\"\">FOCO-</a>");

          client.println("</BODY>");
          client.println("</HTML>");
 
          delay(10);
          //stopping client
         client.stop();
   
  
  

          ///////////////////// control arduino pin

     
          if (readString.indexOf("up") >0)
        {
          servoverP -= 2;
          if (servoverP < MaxservoverP) { servoverP += 2; }
          servover.write(servoverP);
          delay (15);
        }       
       
          if (readString.indexOf("down") >0)   
        {
          servoverP += 2;
          if (servoverP > MinservoverP) { servoverP -= 2; }
          servover.write(servoverP);
          delay (15);
        }
        
          if (readString.indexOf("mid") >0)  
        {
          servoverP == 110;
          servover.write(servoverP);
          delay (15);
        }
          
         
          if(readString.indexOf("zoom1") >0)
          {
            digitalWrite(7, HIGH);
            delay (300);
            digitalWrite (7, LOW);
                   
            Serial.println("Zoom+");
          }
                    
          if(readString.indexOf("zoom2") >0)
          {
            digitalWrite(8, HIGH);
            delay (300);
            digitalWrite (8, LOW);            
            Serial.println("Zoom-");
          }
          
          if(readString.indexOf("foco1") >0)
          {
            digitalWrite(2, HIGH);
            delay (300);
            digitalWrite (2, LOW);             
            Serial.println("Foco+");
          }
          
          if(readString.indexOf("foco2") >0)
          {
            digitalWrite(3, HIGH);
            delay (300);
            digitalWrite (3, LOW);           
            Serial.println("Foco-");
          }
          
         
          readString="";
          

 
// break;
          }
      }
   }
}
}

The code includes only one servo functions because i used it for test.
Can you give me some ideas of where I’m wrong?

Thanks for all and regards.

P.D. Thanks for zoomkat. I used part of his code.

      if(readString.length() < 100) 
      {
      readString += c;
      }

So, you know how big the incoming stream of data can be. And, yet you still insist on shooting yourself in the foot using the String class. Why?

You are issuing a GET request to the Arduino. We can’t see what that request consists of. You can see what is actually happening, and yet you haven’t told us.

But, still, you want us to tell you what is wrong with your code. I have a problem with that.

Sorry. :cold_sweat: Proccesing and htmls parts of my project are the most difficult for me. Let me understand why i'm shooting myself in my foot with string class. I tried to captcha the html form and process the movement and functions orders trought arduino but it only works with functions (zoom and focus).

Thanks for all and regards.

So, you know how big the incoming stream of data can be. And, yet you still insist on shooting yourself in the foot using the String class. Why?

Did using the String class cause the problem, or is it just another "red herring" tosswed in for confusion? ;)

http://www.nizkor.org/features/fallacies/red-herring.html

Did using the String class cause the problem

We need feedback from OP on that. I point out potential problem areas and areas where the code can be improved, even if those areas are not DIRECTLY responsible for the problem being asked about.

I will continue to do so, whether you like it or not.

Thanks for your answers.

I try to learn and understand more about this, not only resolve the problem...

I want to know [u]why[/u] the code works for a switch high/low order and doesnt for a servo.write order.

Thanks and regards.

I want to know why the code works for a switch high/low order and doesnt for a servo.write order.

Then, you'll need to tell us what GET request you are sending to the Arduino and what appears in the serial monitor.

I dont send any GET request neither apeers anything in the serial monitor with this code. After write code to Arduino i work only through forms in web browser.
It’s possible I forget anything?

The code which works for me and my servos with serial monitor is something like this:

/* 
 * NewSerialServo 
 * -------------- 
 * Servo control from the Serial port 
 * 
 * Alteration of the control interface to use < and > keys 
 * to slew the servo horn left and right.  Works best with 
 * the Linux/Mac terminal "screen" program. 
 * 
 * Created 10 December 2007 
 * copyleft 2007 Brian D. Wendt 
 * http://principialabs.com/ 
 * 
 * Adapted from code by Tom Igoe 
 * http://itp.nyu.edu/physcomp/Labs/Servo 
 */  
  
/** Adjust these values for your servo and setup, if necessary **/  
int servoPin     =  2;    // control pin for servo motor  
int minPulse     =  600;  // minimum servo position  
int maxPulse     =  2400; // maximum servo position  
int turnRate     =  100;  // servo turn rate increment (larger value, faster rate)  
int refreshTime  =  20;   // time (ms) between pulses (50Hz)  
  
/** The Arduino will calculate these values for you **/  
int centerServo;         // center servo position  
int pulseWidth;          // servo pulse width  
int moveServo;           // raw user input  
long lastPulse   = 0;    // recorded time (ms) of the last pulse  
  
  
void setup() {  
  pinMode(servoPin, OUTPUT);  // Set servo pin as an output pin  
  centerServo = maxPulse - ((maxPulse - minPulse)/2);  
  pulseWidth = centerServo;   // Give the servo a starting point (or it floats)  
  Serial.begin(9600);  
  Serial.println("      Arduino Serial Servo Control");  
  Serial.println("Press < or > to move, spacebar to center");  
  Serial.println();  
}  
  
void loop() {  
  // wait for serial input  
  if (Serial.available() > 0) {  
    // read the incoming byte:  
    moveServo = Serial.read();  
  
    // ASCII '<' is 44, ASCII '>' is 46 (comma and period, really)  
    if (moveServo == 44) { pulseWidth = pulseWidth - turnRate; }  
    if (moveServo == 46) { pulseWidth = pulseWidth + turnRate; }  
    if (moveServo == 32) { pulseWidth = centerServo; }  
  
    // stop servo pulse at min and max  
    if (pulseWidth > maxPulse) { pulseWidth = maxPulse; }  
    if (pulseWidth < minPulse) { pulseWidth = minPulse; }  
  
    // print pulseWidth back to the Serial Monitor (uncomment to debug)  
    // Serial.print("Pulse Width: ");  
    // Serial.print(pulseWidth);  
    // Serial.println("us");   // microseconds  
  }  
  
  // pulse the servo every 20 ms (refreshTime) with current pulseWidth  
  // this will hold the servo's position if unchanged, or move it if changed  
  if (millis() - lastPulse >= refreshTime) {  
    digitalWrite(servoPin, HIGH);   // start the pulse  
    delayMicroseconds(pulseWidth);  // pulse width  
    digitalWrite(servoPin, LOW);    // stop the pulse  
    lastPulse = millis();           // save the time of the last pulse  
  }  
}

from http://principialabs.com/arduino-serial-servo-control/

Thanks and regards.

P.d. I was working with microseconds instead of degrees too but with the same result.

I dont send any GET request neither apeers anything in the serial monitor with this code.

I tried your origionally posted code (changed for my router) and get the below on the serial monitor when the served page buttons are clicked.

GET /?right HTTP/1.1 GET /?right HTTP/1.1

GET /?left HTTP/1.1 GET /?left HTTP/1.1

GET /?center HTTP/1.1 GET /?center HTTP/1.1

GET /?up HTTP/1.1 GET /?up HTTP/1.1

GET /?mid HTTP/1.1 GET /?mid HTTP/1.1

GET /?down HTTP/1.1 GET /?down HTTP/1.1

GET /?zoom1 HTTP/1.1 GET /?zoom1 HTTP/1.1

Zoom+ GET /?zoom2 HTTP/1.1 GET /?zoom2 HTTP/1.1

Zoom- GET /?foco1 HTTP/1.1 GET /?foco1 HTTP/1.1

Foco+ GET /?foco2 HTTP/1.1 GET /?foco2 HTTP/1.1

Foco-

you can try the below code to see if you can get a servo to move.

//zoomkat 4-1-12
//simple button GET for servo and pin 5
//for use with IDE 1.0
//open serial monitor to see what the arduino receives
//use the \ slash to escape the " in the html, or use ' instead of " 
//address will look like http://192.168.1.102:84 when submited
//for use with W5100 based ethernet shields

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

#include <Servo.h> 
Servo myservo;  // create servo object to control a servo 

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //physical mac address
byte ip[] = { 192, 168, 1, 102 }; // ip in lan
byte gateway[] = { 192, 168, 1, 1 }; // internet access via router
byte subnet[] = { 255, 255, 255, 0 }; //subnet mask
EthernetServer server(84); //server port

String readString; 

//////////////////////

void setup(){

  pinMode(5, OUTPUT); //pin selected to control
  //start Ethernet
  Ethernet.begin(mac, ip, gateway, gateway, subnet);
  server.begin();

  myservo.write(90); //set initial servo position if desired
  myservo.attach(7);  //the pin for the servo control
  //enable serial data print 
  Serial.begin(9600); 
  Serial.println("server servo/pin 5 test 1.0"); // so I can keep track of what is loaded
}

void loop(){
  // 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("HTTP/1.1 200 OK"); //send new page
          client.println("Content-Type: text/html");
          client.println();

          client.println("<HTML>");
          client.println("<HEAD>");
          client.println("<TITLE>Arduino GET test page</TITLE>");
          client.println("</HEAD>");
          client.println("<BODY>");

          client.println("<H1>Zoomkat's simple Arduino button</H1>");
          
          client.println("<a href=\"/?on\"\">ON</a>"); 
          client.println("<a href=\"/?off\"\">OFF</a>"); 

          client.println("</BODY>");
          client.println("</HTML>");
 
          delay(1);
          //stopping client
          client.stop();

          ///////////////////// control arduino pin
          if(readString.indexOf("on") >0)//checks for on
          {
            myservo.write(40);
            digitalWrite(5, HIGH);    // set pin 4 high
            Serial.println("Led On");
          }
          if(readString.indexOf("off") >0)//checks for off
          {
            myservo.write(140);
            digitalWrite(5, LOW);    // set pin 4 low
            Serial.println("Led Off");
          }
          //clearing string for next read
          readString="";

        }
      }
    }
  }
}

Doesn't works too.

I had a problem cause my router is far away from the computer. I install arduino soft in another laptop and get the response on serial monitor.

When i had conected the arduino to the router and open the web, shows;

server servo7pin 5 test 1.0 GET / HTTP/1.1

GET /favicon.ico HTTP/1.1

Led On

The servo moves one time but doesnt response after that...

Hi

Ok, I resolve my problem. It was on the Router.

Something was wrong with WPA encryption.

Thanks for all and regards.