ブラウザからサーボを動かす。

Arduinoの華、ethernet shieldを手に入れたのでブラウザからサーボを動かすスケッチを書いてみた。Webサーバはwebduinoライブラリを使った。サーバからのPOSTを処理するコードはこちらを参考にした。手持ちのサーボが秋月電子1回転モデルだったので、それ以外のサーボを使う人は修正が必要。プログラムを書いた経験はほとんど無いのでたぶんデタラメだと思う。

特に使い道が思いつかないけど、遠隔猫かまい器などに。

// webブラウザからサーボを動かす試み。Controlling servo from web browser.
// webduinoのサンプルスケッチ"Web_HelloWorld.pde"と
// http://forums.adafruit.com/viewtopic.php?f=31&t=10347&start=15
// のスケッチを参考に作成。
// for 360 degree servo motor GWS125-1T/2BB/FUTABA

#include "Ethernet.h"
#include "WebServer.h" //webduino libirary
#include <Servo.h> //servo library

// streamingを使えるようにする。
// no-cost stream operator as described at 
// http://sundial.org/arduino/?page_id=119
template<class T>
inline Print &operator <<(Print &obj, T arg)
{ obj.print(arg); return obj; }

Servo myservo; //サーボの名前はmyserbo

/* CHANGE THIS TO YOUR OWN UNIQUE VALUE.  The MAC number should be
 * different from any other devices on your network or you'll have
 * problems receiving packets. */
static uint8_t mac[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };

int servoval = 0; //サーボの向きを格納する変数
int servoval_ = 0; //実際にサーボに渡す角度

/* CHANGE THIS TO MATCH YOUR HOST NETWORK.  Most home networks are in
 * the 192.168.0.XXX or 192.168.1.XXX subrange.  Pick an address
 * that's not in use and isn't going to be automatically allocated by
 * DHCP from your router. */
static uint8_t ip[] = { 192, 168, _, _ };

/* This creates an instance of the webserver.  By specifying a prefix
 * of "/", all pages will be at the root of the server. */
#define PREFIX "/"
WebServer webserver(PREFIX, 80);
 
void servoCmd(WebServer &server, WebServer::ConnectionType type, char *, bool)
{
  /* this line sends the standard "we're all OK" headers back to the
     browser */
  //server.httpSuccess();

  /* if we're handling a GET or POST, we can output our data here.
     For a HEAD request, we just stop after outputting headers. */
    
    // html本文前半
    P(servoMsg) = 
    "<html>"
    "<head>"
    "<title>Arduino Web Server</title>"
    "</head>"
    "<body>"
    "<h1>Arduino Web Servo Server</h1>";   
     
  if (type == WebServer::POST) //submitボタンでtでPOSTされた場合
  {
    char sServoval[16];
    server.readPOSTparam("servoval",16,sServoval,16); //POSTの内容読み取り
    servoval = atoi(sServoval); //intにする
    
    /* this defines some HTML text in read-only memory aka PROGMEM.
     * This is needed to avoid having the string copied to our limited
     * amount of RAM. */
    /* this is a special form of print that outputs from PROGMEM */
    server.httpSuccess();
    server.printP(servoMsg);

    server << "<form action='" PREFIX "' method='post'>";
    server << "direction: <input type='text' name='servoval' size='3' value='";
    server << servoval;
    server << "'><BR>";
    server << "<input type='submit' value='Submit'/></form>";
    server << "</body></html>";
    delay(50);
    Serial.println(servoval);
    servoval = constrain(servoval,0,360); //過大な値を修正(360サーボ)
    servoval_ = map(servoval,0,360,90,180); //秋月の360サーボ以外は要修正 for 360 degree servo
    myservo.write(servoval_);    
     }
   if (type == WebServer::GET) //GETの場合。
    {
    //servoval = myservo.read();
    Serial.println(servoval);
    server.httpSuccess();
    server.printP(servoMsg);
    //ブラウザから値を読まない。
    server << "<form action='" PREFIX "' method='post'>";
    server << "direction: <input type='text' name='servoval' size='3' value='";
    server << servoval;
    server << "'><BR>";
    server << "<input type='submit' value='Submit'/></form>";
    server << "</body></html>";
     }
    else
     {}
}

void setup()
{
  /* initialize the Ethernet adapter */
  Ethernet.begin(mac, ip);

  /* setup our default command that will be run when the user accesses
   * the root page on the server */
  webserver.setDefaultCommand(&servoCmd);

  /* run the same command if you try to load /index.html, a common
   * default page name */
  webserver.addCommand("index.html", &servoCmd);

  /* start the webserver */
  webserver.begin();
  Serial.begin(9600);
  
  //servo
  myservo.attach(9);
  
}

void loop()
{
  char buff[64];
  int len = 64;

  /* process incoming connections one at a time forever */
  webserver.processConnection(buff, &len);
}