Table of Contents

PREPARATION FOR USING THE ARDUINO AS AN I/O INTERFACE ON A WEB ENABLED SYSTEM

John T. Rine

Objective

The object of this project is to create Arduino and CGI applications that will be used in combination to monitor sensors and use the returned data to control a process over the World Wide Web.

Materials/Reading/Prerequisites

DescriptionQuantityPriceURL or Model #
float switches2$6.99http://www.aquahub.com/store/ifloatfloatswitch.html
tubing adapters2$1.00http://www.aquahub.com/store/product21.html
mold-a-holder2$3.95http://www.aquahub.com/store/moldaholder9.html
crimp caps1$1.99http://www.aquahub.com/store/product34.html
Solid state relay1pricelessContinental Industries S505-OSJ210-000
Computer with Linux Debian and Apache 2 Web Serverpricelesssee Linux install and Apache 2 install projects-

Background

Web servers use the client/server model. That is, the client makes a request, and the server responds by fullfilling that request.When a URL to a Web page is entered into the Web browser, the browser segments it into protocol, server, and resource (page). The browser then sends a request for a particular page (resource to the server, and the server responds by sending the requested page; in the case of a Web page, it sends it encoded as HTML. When the browser gets the page, it interprets it and then displays it. There are many protocols used for different purposes across the Internet for example, HTTP-Hypertext Transfer Protocol, FTP-File Transfer Protocol, and HTTPS-Secure HTTP. The communication protocol used to request and serve unsecure Web pages is HTTP. As we learned in our networking fundamentals course, the well known port for HTTP is port 80. So a Web server listens at port 80 (usually) for a request from a Web client.

CGI is a specification for transferring information between a Web server and a CGI program. A CGI program is any program designed to accept and return data that follows the CGI specification. A CGI program could be written in any one of a number of programming and scripting languages. In order for the scripts or programs to be executed, a Web server must be installed. Next, the file or files to be executed must be in a specific directory on the Web server. The CGI program can then be executed by including the bin-cgi directory and filename in the URL, for example: http://10.80.2.179/cgi-bin/example.

Arduino is an open-source electronics prototyping platform based on AVR microcontrollers and ICs which make communications between an Arduino and other platforms very easy to implement, for example the FTDI USB serial IC and driver.

Procedure

1. Install the Arduino IDE on a computer
Start the Arduino install by following the instructions on the following Web page: http://arduino.cc/playground/Linux/Debian. On this page, follow the “previous non-packaged approach:” section of the installation instructions.
Preparation for the Arduino IDE installation:

bob@dhcp-179:~$ su
Password: 
root@dhcp-179:/home/bob# sudo apt-get install openjdk-6-jre gcc-avr avr-libc avrdude
Reading package lists... Done
Building dependency tree       
Reading state information... Done
The following extra packages will be installed:
  binutils-avr ca-certificates-java icedtea-6-jre-cacao java-common
  libaccess-bridge-java libaccess-bridge-java-jni openjdk-6-jre-headless
  openjdk-6-jre-lib tzdata-java
Suggested packages:
  avrdude-doc task-c-devel gcc-doc gcc-4.2 default-jre equivs icedtea6-plugin
  sun-java6-fonts ttf-baekmuk ttf-unfonts ttf-unfonts-core ttf-sazanami-gothic
  ttf-kochi-gothic ttf-sazanami-mincho ttf-kochi-mincho ttf-wqy-microhei
  ttf-wqy-zenhei ttf-indic-fonts
The following NEW packages will be installed:
  avr-libc avrdude binutils-avr ca-certificates-java gcc-avr
  icedtea-6-jre-cacao java-common libaccess-bridge-java
  libaccess-bridge-java-jni openjdk-6-jre openjdk-6-jre-headless
  openjdk-6-jre-lib tzdata-java
0 upgraded, 13 newly installed, 0 to remove and 12 not upgraded.
Need to get 49.7 MB of archives.
After this operation, 149 MB of additional disk space will be used.
Do you want to continue [Y/n]? y
Get:1 http://debian.uchicago.edu/debian/ squeeze/main java-common all 0.40 [64.3 kB]
Get:2 http://security.debian.org/ squeeze/updates/main openjdk-6-jre-lib all 6b18-1.8.3-2+squeeze1 [5,953 kB]
Get:3 http://debian.uchicago.edu/debian/ squeeze/main ca-certificates-java all 20100412 [101 kB]
Get:4 http://debian.uchicago.edu/debian/ squeeze/main tzdata-java all 2011c-0squeeze1 [153 kB]
Get:5 http://debian.uchicago.edu/debian/ squeeze/main libaccess-bridge-java-jni i386 1.26.2-5 [27.6 kB]
Get:6 http://debian.uchicago.edu/debian/ squeeze/main libaccess-bridge-java all 1.26.2-5 [429 kB]
Get:7 http://debian.uchicago.edu/debian/ squeeze/main binutils-avr i386 2.20.1-1 [4,256 kB]
Get:8 http://debian.uchicago.edu/debian/ squeeze/main gcc-avr i386 1:4.3.5-1 [5,394 kB]
Get:9 http://security.debian.org/ squeeze/updates/main openjdk-6-jre-headless i386 6b18-1.8.3-2+squeeze1 [27.3 MB]
Get:10 http://debian.uchicago.edu/debian/ squeeze/main avr-libc all 1:1.6.8-2 [5,304 kB]
Get:11 http://debian.uchicago.edu/debian/ squeeze/main avrdude i386 5.10-3 [198 kB]
Get:12 http://security.debian.org/ squeeze/updates/main openjdk-6-jre i386 6b18-1.8.3-2+squeeze1 [254 kB]
Get:13 http://security.debian.org/ squeeze/updates/main icedtea-6-jre-cacao i386 6b18-1.8.3-2+squeeze1 [345 kB]
Fetched 49.7 MB in 2min 4s (400 kB/s)                                          
Selecting previously deselected package java-common.
(Reading database ... 128528 files and directories currently installed.)
Unpacking java-common (from .../java-common_0.40_all.deb) ...
Selecting previously deselected package openjdk-6-jre-lib.
Unpacking openjdk-6-jre-lib (from .../openjdk-6-jre-lib_6b18-1.8.3-2+squeeze1_all.deb) ...
Selecting previously deselected package ca-certificates-java.
Unpacking ca-certificates-java (from .../ca-certificates-java_20100412_all.deb) ...
Selecting previously deselected package tzdata-java.
Unpacking tzdata-java (from .../tzdata-java_2011c-0squeeze1_all.deb) ...
Selecting previously deselected package openjdk-6-jre-headless.
Unpacking openjdk-6-jre-headless (from .../openjdk-6-jre-headless_6b18-1.8.3-2+squeeze1_i386.deb) ...
Selecting previously deselected package libaccess-bridge-java-jni.
Unpacking libaccess-bridge-java-jni (from .../libaccess-bridge-java-jni_1.26.2-5_i386.deb) ...
Selecting previously deselected package openjdk-6-jre.
Unpacking openjdk-6-jre (from .../openjdk-6-jre_6b18-1.8.3-2+squeeze1_i386.deb) ...
Selecting previously deselected package libaccess-bridge-java.
Unpacking libaccess-bridge-java (from .../libaccess-bridge-java_1.26.2-5_all.deb) ...
Selecting previously deselected package binutils-avr.
Unpacking binutils-avr (from .../binutils-avr_2.20.1-1_i386.deb) ...
Selecting previously deselected package gcc-avr.
Unpacking gcc-avr (from .../gcc-avr_1%3a4.3.5-1_i386.deb) ...
Selecting previously deselected package avr-libc.
Unpacking avr-libc (from .../avr-libc_1%3a1.6.8-2_all.deb) ...
Selecting previously deselected package avrdude.
Unpacking avrdude (from .../avrdude_5.10-3_i386.deb) ...
Selecting previously deselected package icedtea-6-jre-cacao.
Unpacking icedtea-6-jre-cacao (from .../icedtea-6-jre-cacao_6b18-1.8.3-2+squeeze1_i386.deb) ...
Processing triggers for man-db ...
Processing triggers for desktop-file-utils ...
Processing triggers for gnome-menus ...
Processing triggers for menu ...
Processing triggers for hicolor-icon-theme ...
Setting up java-common (0.40) ...
Setting up tzdata-java (2011c-0squeeze1) ...
Setting up binutils-avr (2.20.1-1) ...
Setting up gcc-avr (1:4.3.5-1) ...
Setting up avr-libc (1:1.6.8-2) ...
Setting up avrdude (5.10-3) ...
Setting up openjdk-6-jre-lib (6b18-1.8.3-2+squeeze1) ...
Setting up openjdk-6-jre-headless (6b18-1.8.3-2+squeeze1) ...
update-alternatives: using /usr/lib/jvm/java-6-openjdk/jre/bin/java to provide /usr/bin/java (java) in auto mode.
update-alternatives: using /usr/lib/jvm/java-6-openjdk/jre/bin/keytool to provide /usr/bin/keytool (keytool) in auto mode.
update-alternatives: using /usr/lib/jvm/java-6-openjdk/jre/bin/pack200 to provide /usr/bin/pack200 (pack200) in auto mode.
update-alternatives: using /usr/lib/jvm/java-6-openjdk/jre/bin/rmid to provide /usr/bin/rmid (rmid) in auto mode.
update-alternatives: using /usr/lib/jvm/java-6-openjdk/jre/bin/rmiregistry to provide /usr/bin/rmiregistry (rmiregistry) in auto mode.
update-alternatives: using /usr/lib/jvm/java-6-openjdk/jre/bin/unpack200 to provide /usr/bin/unpack200 (unpack200) in auto mode.
update-alternatives: using /usr/lib/jvm/java-6-openjdk/jre/bin/orbd to provide /usr/bin/orbd (orbd) in auto mode.
update-alternatives: using /usr/lib/jvm/java-6-openjdk/jre/bin/servertool to provide /usr/bin/servertool (servertool) in auto mode.
update-alternatives: using /usr/lib/jvm/java-6-openjdk/jre/bin/tnameserv to provide /usr/bin/tnameserv (tnameserv) in auto mode.
update-alternatives: using /usr/lib/jvm/java-6-openjdk/jre/lib/jexec to provide /usr/bin/jexec (jexec) in auto mode.
Setting up libaccess-bridge-java (1.26.2-5) ...
Setting up libaccess-bridge-java-jni (1.26.2-5) ...
Setting up icedtea-6-jre-cacao (6b18-1.8.3-2+squeeze1) ...
Setting up ca-certificates-java (20100412) ...
creating /etc/ssl/certs/java/cacerts...
done.
Setting up openjdk-6-jre (6b18-1.8.3-2+squeeze1) ...
update-alternatives: using /usr/lib/jvm/java-6-openjdk/jre/bin/javaws to provide /usr/bin/javaws (javaws) in auto mode.
update-alternatives: using /usr/lib/jvm/java-6-openjdk/jre/bin/pluginappletviewer to provide /usr/bin/pluginappletviewer (pluginappletviewer) in auto mode.
update-alternatives: using /usr/lib/jvm/java-6-openjdk/jre/bin/policytool to provide /usr/bin/policytool (policytool) in auto mode.
Processing triggers for menu ...
root@dhcp-179:/home/bob# 
  1. After performing these steps, install the Linux 32-bit version of the Arduino IDE software which can be downloaded from the following Web page: http://arduino.googlecode.com/files/arduino-0022.tgz .
  2. Using an appropriate power converter, plug the Arduino end of the power converter into the Arduino Duemilanove and outlet end into a wall outlet.
  3. Using an appropriate USB cable, plug the Arduino end into the Arduino, and the USB end into a USB port on the target computer.
  4. Move the downloaded file to the Desktop directory.
  5. Next, right-click on the file and selected “Extract here” from the pop-up menu.
  6. Navigate into the arduino-0022 directory and run the Arduino file by clicking on it.
  7. On the main menu of the Arduino IDE, select the menu item “Tools”. Notice that the “Serial Port” sub-menu item was greyed out indicating that the application didn't recognized the serial port.
  8. Next, following the instructions on the Web page http://www.arduino.cc/playground/Learning/Linux, log in as the super user and add users to the tty group in the /etc/group file.
  9. Reboot and open the arduino application and checked the “Tools” main menu item. The “Serial Port” item shpu;d still be greyed out. Perform a long listing on the /dev/ttyUS[TAB COMPLETED] and find that ttyUSBX was a member of dialout.
  10. Log in as the super user and add users to the dialout group in the /etc/group file.
  11. Reboot and then open the Arduino IDE. Select the “Tools” menu item and notice that the 'Serial Port“ sub-menu item was no longer greyed out.


2. Write an Arduino application which reads character commands from the serial port and then performs the commands. If a command is to return data via the serial port, the application is to do so.

//http://arduino.cc/en/Tutorial/AnalogReadSerial
//http://www.arduino.cc/en/Serial/Read
//http://www.arduino.cc/en/Serial/Available
//http://www.arduino.cc/en/Reference/DigitalRead
//http://www.arduino.cc/en/Reference/DigitalWrite

//Author: John T. Rine


int serialIn = 0;
int sensorValue = 0;
int digitalValue = 0;
int pin7 = 7;
int pin6 = 6;
int pin6State = LOW;
int pinState = LOW;

void setup()
{
  Serial.begin(9600);
  pinMode(pin7, INPUT);
  pinMode(pin6, OUTPUT);

}

void loop()
{
  if (Serial.available() > 0)
  {
        serialIn = Serial.read();
        switch(serialIn)
        {
          case 'a':
              sensorValue = analogRead(A0);
              Serial.println(sensorValue, DEC);
              serialIn = '\0';
              break;
          case 'd':
              digitalValue = digitalRead(pin7);
              Serial.println(digitalValue, DEC);
              serialIn = '\0';
              break;
          case 'o':
              if(pin6State == LOW)
              {
                pinState = HIGH;
                pin6State = HIGH;
              }
              else
              {
                pinState = LOW;
                pin6State = LOW;
              }
              digitalWrite(pin6, pinState);
              break;

        }
  }
 }


3. If a Web server is not installed, Install the Apache 2 Web server software on the hardware which is to host the server.
After logging in as root, I performed an apt-get install of the apache 2 Web server packages.

root@dhcp-179:/home/bob# apt-get install apache2 apache2-doc apache2-utils
Reading package lists... Done
Building dependency tree       
Reading state information... Done
The following extra packages will be installed:
  apache2-mpm-worker apache2.2-common
Suggested packages:
  apache2-suexec apache2-suexec-custom
The following NEW packages will be installed:
  apache2 apache2-doc apache2-mpm-worker apache2-utils apache2.2-common
0 upgraded, 5 newly installed, 0 to remove and 0 not upgraded.
Need to get 2,779 kB of archives.
After this operation, 15.1 MB of additional disk space will be used.
Do you want to continue [Y/n]? y
Get:1 http://security.debian.org/ squeeze/updates/main apache2-utils i386 2.2.16-6+squeeze1 [165 kB]
Get:2 http://security.debian.org/ squeeze/updates/main apache2.2-common i386 2.2.16-6+squeeze1 [307 kB]
Get:3 http://security.debian.org/ squeeze/updates/main apache2-mpm-worker i386 2.2.16-6+squeeze1 [2,230 B]
Get:4 http://security.debian.org/ squeeze/updates/main apache2 i386 2.2.16-6+squeeze1 [1,386 B]
Get:5 http://security.debian.org/ squeeze/updates/main apache2-doc all 2.2.16-6+squeeze1 [2,304 kB]
Fetched 2,779 kB in 7s (387 kB/s)                                                             
Selecting previously deselected package apache2-utils.
(Reading database ... 124913 files and directories currently installed.)
Unpacking apache2-utils (from .../apache2-utils_2.2.16-6+squeeze1_i386.deb) ...
Selecting previously deselected package apache2.2-common.
Unpacking apache2.2-common (from .../apache2.2-common_2.2.16-6+squeeze1_i386.deb) ...
Selecting previously deselected package apache2-mpm-worker.
Unpacking apache2-mpm-worker (from .../apache2-mpm-worker_2.2.16-6+squeeze1_i386.deb) ...
Selecting previously deselected package apache2.
Unpacking apache2 (from .../apache2_2.2.16-6+squeeze1_i386.deb) ...
Selecting previously deselected package apache2-doc.
Unpacking apache2-doc (from .../apache2-doc_2.2.16-6+squeeze1_all.deb) ...
Processing triggers for man-db ...
Setting up apache2-utils (2.2.16-6+squeeze1) ...
Setting up apache2.2-common (2.2.16-6+squeeze1) ...
Enabling site default.
Enabling module alias.
Enabling module autoindex.
Enabling module dir.
Enabling module env.
Enabling module mime.
Enabling module negotiation.
Enabling module setenvif.
Enabling module status.
Enabling module auth_basic.
Enabling module deflate.
Enabling module authz_default.
Enabling module authz_user.
Enabling module authz_groupfile.
Enabling module authn_file.
Enabling module authz_host.
Enabling module reqtimeout.
Setting up apache2-mpm-worker (2.2.16-6+squeeze1) ...
Starting web server: apache2.
Setting up apache2 (2.2.16-6+squeeze1) ...
Setting up apache2-doc (2.2.16-6+squeeze1) ...
Reloading web server config: apache2.
root@dhcp-179:/home/bob# 
root@dhcp-179:/home/bob# 
root@dhcp-179:/home/bob# apt-get install libapache2-mod-ruby
Reading package lists... Done
Building dependency tree       
Reading state information... Done
The following extra packages will be installed:
  libapache-ruby1.8 libreadline5 libruby1.8
Suggested packages:
  liberuby
The following NEW packages will be installed:
  libapache-ruby1.8 libapache2-mod-ruby libreadline5 libruby1.8
0 upgraded, 4 newly installed, 0 to remove and 0 not upgraded.
Need to get 2,180 kB of archives.
After this operation, 8,147 kB of additional disk space will be used.
Do you want to continue [Y/n]? y
Get:1 http://debian.uchicago.edu/debian/ squeeze/main libreadline5 i386 5.2-7 [135 kB]
Get:2 http://debian.uchicago.edu/debian/ squeeze/main libruby1.8 i386 1.8.7.302-2 [1,965 kB]
Get:3 http://debian.uchicago.edu/debian/ squeeze/main libapache-ruby1.8 all 1.2.6-2 [20.5 kB]
Get:4 http://debian.uchicago.edu/debian/ squeeze/main libapache2-mod-ruby i386 1.2.6-2 [59.7 kB]
Fetched 2,180 kB in 5s (407 kB/s)         
Selecting previously deselected package libreadline5.
(Reading database ... 126955 files and directories currently installed.)
Unpacking libreadline5 (from .../libreadline5_5.2-7_i386.deb) ...
Selecting previously deselected package libruby1.8.
Unpacking libruby1.8 (from .../libruby1.8_1.8.7.302-2_i386.deb) ...
Selecting previously deselected package libapache-ruby1.8.
Unpacking libapache-ruby1.8 (from .../libapache-ruby1.8_1.2.6-2_all.deb) ...
Selecting previously deselected package libapache2-mod-ruby.
Unpacking libapache2-mod-ruby (from .../libapache2-mod-ruby_1.2.6-2_i386.deb) ...
Setting up libreadline5 (5.2-7) ...
Setting up libruby1.8 (1.8.7.302-2) ...
Setting up libapache-ruby1.8 (1.2.6-2) ...
Setting up libapache2-mod-ruby (1.2.6-2) ...
Enabling module ruby.
Run '/etc/init.d/apache2 restart' to activate new configuration!
root@dhcp-179:/home/bob# apt-get install libapache2-mod-perl2
Reading package lists... Done
Building dependency tree       
Reading state information... Done
The following extra packages will be installed:
  libapache2-reload-perl libbsd-resource-perl libdevel-symdump-perl
The following NEW packages will be installed:
  libapache2-mod-perl2 libapache2-reload-perl libbsd-resource-perl libdevel-symdump-perl
0 upgraded, 4 newly installed, 0 to remove and 0 not upgraded.
Need to get 1,146 kB of archives.
After this operation, 4,063 kB of additional disk space will be used.
Do you want to continue [Y/n]? y
Get:1 http://debian.uchicago.edu/debian/ squeeze/main libdevel-symdump-perl all 2.08-3 [16.6 kB]
Get:2 http://debian.uchicago.edu/debian/ squeeze/main libapache2-mod-perl2 i386 2.0.4-7 [1,077 kB]
Get:3 http://debian.uchicago.edu/debian/ squeeze/main libapache2-reload-perl all 0.10-2 [19.9 kB]
Get:4 http://debian.uchicago.edu/debian/ squeeze/main libbsd-resource-perl i386 1.2904-1 [32.5 kB]
Fetched 1,146 kB in 2s (418 kB/s)               
Selecting previously deselected package libdevel-symdump-perl.
(Reading database ... 127688 files and directories currently installed.)
Unpacking libdevel-symdump-perl (from .../libdevel-symdump-perl_2.08-3_all.deb) ...
Selecting previously deselected package libapache2-mod-perl2.
Unpacking libapache2-mod-perl2 (from .../libapache2-mod-perl2_2.0.4-7_i386.deb) ...
Selecting previously deselected package libapache2-reload-perl.
Unpacking libapache2-reload-perl (from .../libapache2-reload-perl_0.10-2_all.deb) ...
Selecting previously deselected package libbsd-resource-perl.
Unpacking libbsd-resource-perl (from .../libbsd-resource-perl_1.2904-1_i386.deb) ...
Processing triggers for man-db ...
Setting up libdevel-symdump-perl (2.08-3) ...
Setting up libapache2-mod-perl2 (2.0.4-7) ...
Enabling module perl.
Run '/etc/init.d/apache2 restart' to activate new configuration!
Setting up libapache2-reload-perl (0.10-2) ...
Setting up libbsd-resource-perl (1.2904-1) ...
root@dhcp-179:/home/bob# 
root@dhcp-179:/home/bob# 
root@dhcp-179:/home/bob# apt-get install libapache2-mod-python
Reading package lists... Done
Building dependency tree       
Reading state information... Done
Suggested packages:
  libapache2-mod-python-doc
The following NEW packages will be installed:
  libapache2-mod-python
0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
Need to get 122 kB of archives.
After this operation, 537 kB of additional disk space will be used.
Get:1 http://debian.uchicago.edu/debian/ squeeze/main libapache2-mod-python i386 3.3.1-9+b1 [122 kB]
Fetched 122 kB in 0s (240 kB/s)           
Selecting previously deselected package libapache2-mod-python.
(Reading database ... 128129 files and directories currently installed.)
Unpacking libapache2-mod-python (from .../libapache2-mod-python_3.3.1-9+b1_i386.deb) ...
Setting up libapache2-mod-python (3.3.1-9+b1) ...
Reloading web server config: apache2.
Processing triggers for python-central ...
root@dhcp-179:/home/bob# apt-get install python-mysqldb
Reading package lists... Done
Building dependency tree       
Reading state information... Done
The following extra packages will be installed:
  libmysqlclient16 mysql-common
Suggested packages:
  python-egenix-mxdatetime mysql-server-5.1 mysql-server python-mysqldb-dbg
The following NEW packages will be installed:
  libmysqlclient16 mysql-common python-mysqldb
0 upgraded, 3 newly installed, 0 to remove and 0 not upgraded.
Need to get 2,101 kB of archives.
After this operation, 4,788 kB of additional disk space will be used.
Do you want to continue [Y/n]? y
Get:1 http://debian.uchicago.edu/debian/ squeeze/main mysql-common all 5.1.49-3 [70.9 kB]
Get:2 http://debian.uchicago.edu/debian/ squeeze/main libmysqlclient16 i386 5.1.49-3 [1,935 kB]
Get:3 http://debian.uchicago.edu/debian/ squeeze/main python-mysqldb i386 1.2.2-10+b1 [95.8 kB]
Fetched 2,101 kB in 5s (374 kB/s)        
Selecting previously deselected package mysql-common.
(Reading database ... 128154 files and directories currently installed.)
Unpacking mysql-common (from .../mysql-common_5.1.49-3_all.deb) ...
Selecting previously deselected package libmysqlclient16.
Unpacking libmysqlclient16 (from .../libmysqlclient16_5.1.49-3_i386.deb) ...
Selecting previously deselected package python-mysqldb.
Unpacking python-mysqldb (from .../python-mysqldb_1.2.2-10+b1_i386.deb) ...
Setting up mysql-common (5.1.49-3) ...
Setting up libmysqlclient16 (5.1.49-3) ...
Setting up python-mysqldb (1.2.2-10+b1) ...
Processing triggers for python-support ...
root@dhcp-179:/home/bob# apt-get install libapache2-mod-php5 php5 php-pear php5-xcache
Reading package lists... Done
Building dependency tree       
Reading state information... Done
The following extra packages will be installed:
  apache2-mpm-prefork libonig2 libqdbm14 php5-cli php5-common php5-suhosin
Suggested packages:
  php5-dev
The following packages will be REMOVED:
  apache2-mpm-worker
The following NEW packages will be installed:
  apache2-mpm-prefork libapache2-mod-php5 libonig2 libqdbm14 php-pear php5 php5-cli
  php5-common php5-suhosin php5-xcache
0 upgraded, 10 newly installed, 1 to remove and 0 not upgraded.
Need to get 7,101 kB of archives.
After this operation, 20.3 MB of additional disk space will be used.
Do you want to continue [Y/n]? y
Get:1 http://debian.uchicago.edu/debian/ squeeze/main libonig2 i386 5.9.1-1 [134 kB]
Get:2 http://security.debian.org/ squeeze/updates/main apache2-mpm-prefork i386 2.2.16-6+squeeze1 [2,286 B]
Get:3 http://security.debian.org/ squeeze/updates/main php5-common i386 5.3.3-7+squeeze1 [541 kB]
Get:4 http://debian.uchicago.edu/debian/ squeeze/main libqdbm14 i386 1.8.77-4 [147 kB]
Get:5 http://debian.uchicago.edu/debian/ squeeze/main php5-suhosin i386 0.9.32.1-1 [80.8 kB]
Get:6 http://debian.uchicago.edu/debian/ squeeze/main php5-xcache i386 1.3.0-7 [86.4 kB]
Get:7 http://security.debian.org/ squeeze/updates/main libapache2-mod-php5 i386 5.3.3-7+squeeze1 [2,888 kB]
Get:8 http://security.debian.org/ squeeze/updates/main php5-cli i386 5.3.3-7+squeeze1 [2,857 kB]
Get:9 http://security.debian.org/ squeeze/updates/main php-pear all 5.3.3-7+squeeze1 [364 kB] 
Get:10 http://security.debian.org/ squeeze/updates/main php5 all 5.3.3-7+squeeze1 [1,068 B]   
Fetched 7,101 kB in 15s (445 kB/s)                                                            
dpkg: apache2-mpm-worker: dependency problems, but removing anyway as you requested:
 apache2 depends on apache2-mpm-worker (= 2.2.16-6+squeeze1) | apache2-mpm-prefork (= 2.2.16-6+squeeze1) | apache2-mpm-event (= 2.2.16-6+squeeze1) | apache2-mpm-itk (= 2.2.16-6+squeeze1); however:
  Package apache2-mpm-worker is to be removed.
  Package apache2-mpm-prefork is not installed.
  Package apache2-mpm-event is not installed.
  Package apache2-mpm-itk is not installed.
(Reading database ... 128207 files and directories currently installed.)
Removing apache2-mpm-worker ...
Stopping web server: apache2 ... waiting .
Selecting previously deselected package apache2-mpm-prefork.
(Reading database ... 128203 files and directories currently installed.)
Unpacking apache2-mpm-prefork (from .../apache2-mpm-prefork_2.2.16-6+squeeze1_i386.deb) ...
Setting up apache2-mpm-prefork (2.2.16-6+squeeze1) ...
Starting web server: apache2.
Selecting previously deselected package libonig2.
(Reading database ... 128208 files and directories currently installed.)
Unpacking libonig2 (from .../libonig2_5.9.1-1_i386.deb) ...
Selecting previously deselected package libqdbm14.
Unpacking libqdbm14 (from .../libqdbm14_1.8.77-4_i386.deb) ...
Selecting previously deselected package php5-common.
Unpacking php5-common (from .../php5-common_5.3.3-7+squeeze1_i386.deb) ...
Selecting previously deselected package libapache2-mod-php5.
Unpacking libapache2-mod-php5 (from .../libapache2-mod-php5_5.3.3-7+squeeze1_i386.deb) ...
Selecting previously deselected package php5-cli.
Unpacking php5-cli (from .../php5-cli_5.3.3-7+squeeze1_i386.deb) ...
Selecting previously deselected package php-pear.
Unpacking php-pear (from .../php-pear_5.3.3-7+squeeze1_all.deb) ...
Selecting previously deselected package php5.
Unpacking php5 (from .../php5_5.3.3-7+squeeze1_all.deb) ...
Selecting previously deselected package php5-suhosin.
Unpacking php5-suhosin (from .../php5-suhosin_0.9.32.1-1_i386.deb) ...
Selecting previously deselected package php5-xcache.
Unpacking php5-xcache (from .../php5-xcache_1.3.0-7_i386.deb) ...
Processing triggers for man-db ...
Setting up libonig2 (5.9.1-1) ...
Setting up libqdbm14 (1.8.77-4) ...
Setting up php5-common (5.3.3-7+squeeze1) ...
Setting up libapache2-mod-php5 (5.3.3-7+squeeze1) ...

Creating config file /etc/php5/apache2/php.ini with new version
Reloading web server config: apache2.
Setting up php5-cli (5.3.3-7+squeeze1) ...

Creating config file /etc/php5/cli/php.ini with new version
update-alternatives: using /usr/bin/php5 to provide /usr/bin/php (php) in auto mode.
Setting up php-pear (5.3.3-7+squeeze1) ...
Setting up php5 (5.3.3-7+squeeze1) ...
Setting up php5-suhosin (0.9.32.1-1) ...
Setting up php5-xcache (1.3.0-7) ...
root@dhcp-179:/home/bob# apt-get install php5-suhosin
Reading package lists... Done
Building dependency tree       
Reading state information... Done
php5-suhosin is already the newest version.
php5-suhosin set to manually installed.
0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
root@dhcp-179:/home/bob# apt-get install php5-mysql
Reading package lists... Done
Building dependency tree       
Reading state information... Done
The following NEW packages will be installed:
  php5-mysql
0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
Need to get 66.8 kB of archives.
After this operation, 250 kB of additional disk space will be used.
Get:1 http://security.debian.org/ squeeze/updates/main php5-mysql i386 5.3.3-7+squeeze1 [66.8 kB]
Fetched 66.8 kB in 2s (27.0 kB/s)     
Selecting previously deselected package php5-mysql.
(Reading database ... 128521 files and directories currently installed.)
Unpacking php5-mysql (from .../php5-mysql_5.3.3-7+squeeze1_i386.deb) ...
Processing triggers for libapache2-mod-php5 ...
Reloading web server config: apache2.
Setting up php5-mysql (5.3.3-7+squeeze1) ...
root@dhcp-179:/home/bob# cd ..
root@dhcp-179:/home# cd /
root@dhcp-179:/# cd /etc/apache2
root@dhcp-179:/etc/apache2# ls
apache2.conf  envvars	  magic		  mods-enabled	sites-available
conf.d	      httpd.conf  mods-available  ports.conf	sites-enabled
root@dhcp-179:/etc/apache2# cd /var/www
root@dhcp-179:/var/www# ls
index.html


4. Write a CGI application or a PHP script which will give commands to the Arduino based upon commands handed to it from the Web and return data as required.
I found the following Linux C Arduino serial code at: http://todbot.com/blog/2006/12/06/arduino-serial-c-code-to-talk-to-arduino/.

/*
 * Arduino-serial
 * --------------
 * 
 * A simple command-line example program showing how a computer can
 * communicate with an Arduino board. Works on any POSIX system (Mac/Unix/PC) 
 *
 *
 * Compile with something like:
 * gcc -o arduino-serial arduino-serial.c
 *
 * Created 5 December 2006
 * Copyleft (c) 2006, Tod E. Kurt, tod@todbot.com
 * http://todbot.com/blog/
 *
 * 
 * Updated 8 December 2006: 
 *  Justin McBride discoevered B14400 & B28800 aren't in Linux's termios.h.
 *  I've included his patch, but commented out for now.  One really needs a
 *  real make system when doing cross-platform C and I wanted to avoid that
 *  for this little program. Those baudrates aren't used much anyway. :)
 *
 * Updated 26 December 2007:
 *  Added ability to specify a delay (so you can wait for Arduino Diecimila)
 *  Added ability to send a binary byte number
 *
 * Update 31 August 2008:
 *  Added patch to clean up odd baudrates from Andy at hexapodia.org
 *
 */

#include <stdio.h>    /* Standard input/output definitions */
#include <stdlib.h> 
#include <stdint.h>   /* Standard types */
#include <string.h>   /* String function definitions */
#include <unistd.h>   /* UNIX standard function definitions */
#include <fcntl.h>    /* File control definitions */
#include <errno.h>    /* Error number definitions */
#include <termios.h>  /* POSIX terminal control definitions */
#include <sys/ioctl.h>
#include <getopt.h>

void usage(void);
int serialport_init(const char* serialport, int baud);
int serialport_writebyte(int fd, uint8_t b);
int serialport_write(int fd, const char* str);
int serialport_read_until(int fd, char* buf, char until);

void usage(void) {
    printf("Usage: arduino-serial -p <serialport> [OPTIONS]\n"
    "\n"
    "Options:\n"
    "  -h, --help                   Print this help message\n"
    "  -p, --port=serialport        Serial port Arduino is on\n"
    "  -b, --baud=baudrate          Baudrate (bps) of Arduino\n"
    "  -s, --send=data              Send data to Arduino\n"
    "  -r, --receive                Receive data from Arduino & print it out\n"
    "  -n  --num=num                Send a number as a single byte\n"
    "  -d  --delay=millis           Delay for specified milliseconds\n"
    "\n"
    "Note: Order is important. Set '-b' before doing '-p'. \n"
    "      Used to make series of actions:  '-d 2000 -s hello -d 100 -r' \n"
    "      means 'wait 2secs, send 'hello', wait 100msec, get reply'\n"
    "\n");
}

int main(int argc, char *argv[]) 
{
    int fd = 0;
    char serialport[256];
    int baudrate = B9600;  // default
    char buf[256];
    int rc,n;

    if (argc==1) {
        usage();
        exit(EXIT_SUCCESS);
    }

    /* parse options */
    int option_index = 0, opt;
    static struct option loptions[] = {
        {"help",       no_argument,       0, 'h'},
        {"port",       required_argument, 0, 'p'},
        {"baud",       required_argument, 0, 'b'},
        {"send",       required_argument, 0, 's'},
        {"receive",    no_argument,       0, 'r'},
        {"num",        required_argument, 0, 'n'},
        {"delay",      required_argument, 0, 'd'}
    };
    
    while(1) {
        opt = getopt_long (argc, argv, "hp:b:s:rn:d:",
                           loptions, &option_index);
        if (opt==-1) break;
        switch (opt) {
        case '0': break;
        case 'd':
            n = strtol(optarg,NULL,10);
            usleep(n * 1000 ); // sleep milliseconds
            break;
        case 'h':
            usage();
            break;
        case 'b':
            baudrate = strtol(optarg,NULL,10);
            break;
        case 'p':
            strcpy(serialport,optarg);
            fd = serialport_init(optarg, baudrate);
            if(fd==-1) return -1;
            break;
        case 'n':
            n = strtol(optarg, NULL, 10); // convert string to number
            rc = serialport_writebyte(fd, (uint8_t)n);
            if(rc==-1) return -1;
            break;
        case 's':
            strcpy(buf,optarg);
            rc = serialport_write(fd, buf);
            if(rc==-1) return -1;
            break;
        case 'r':
            serialport_read_until(fd, buf, '\n');
            printf("read: %s\n",buf);
            break;
        }
    }

    exit(EXIT_SUCCESS);    
} // end main
    
int serialport_writebyte( int fd, uint8_t b)
{
    int n = write(fd,&b,1);
    if( n!=1)
        return -1;
    return 0;
}

int serialport_write(int fd, const char* str)
{
    int len = strlen(str);
    int n = write(fd, str, len);
    if( n!=len ) 
        return -1;
    return 0;
}

int serialport_read_until(int fd, char* buf, char until)
{
    char b[1];
    int i=0;
    do { 
        int n = read(fd, b, 1);  // read a char at a time
        if( n==-1) return -1;    // couldn't read
        if( n==0 ) {
            usleep( 10 * 1000 ); // wait 10 msec try again
            continue;
        }
        buf[i] = b[0]; i++;
    } while( b[0] != until );

    buf[i] = 0;  // null terminate the string
    return 0;
}

// takes the string name of the serial port (e.g. "/dev/tty.usbserial","COM1")
// and a baud rate (bps) and connects to that port at that speed and 8N1.
// opens the port in fully raw mode so you can send binary data.
// returns valid fd, or -1 on error
int serialport_init(const char* serialport, int baud)
{
    struct termios toptions;
    int fd;
    
    //fprintf(stderr,"init_serialport: opening port %s @ %d bps\n",
    //        serialport,baud);

    fd = open(serialport, O_RDWR | O_NOCTTY | O_NDELAY);
    if (fd == -1)  {
        perror("init_serialport: Unable to open port ");
        return -1;
    }
    
    if (tcgetattr(fd, &toptions) < 0) {
        perror("init_serialport: Couldn't get term attributes");
        return -1;
    }
    speed_t brate = baud; // let you override switch below if needed
    switch(baud) {
    case 4800:   brate=B4800;   break;
    case 9600:   brate=B9600;   break;
#ifdef B14400
    case 14400:  brate=B14400;  break;
#endif
    case 19200:  brate=B19200;  break;
#ifdef B28800
    case 28800:  brate=B28800;  break;
#endif
    case 38400:  brate=B38400;  break;
    case 57600:  brate=B57600;  break;
    case 115200: brate=B115200; break;
    }
    cfsetispeed(&toptions, brate);
    cfsetospeed(&toptions, brate);

    // 8N1
    toptions.c_cflag &= ~PARENB;
    toptions.c_cflag &= ~CSTOPB;
    toptions.c_cflag &= ~CSIZE;
    toptions.c_cflag |= CS8;
    // no flow control
    toptions.c_cflag &= ~CRTSCTS;

    toptions.c_cflag |= CREAD | CLOCAL;  // turn on READ & ignore ctrl lines
    toptions.c_iflag &= ~(IXON | IXOFF | IXANY); // turn off s/w flow ctrl

    toptions.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); // make raw
    toptions.c_oflag &= ~OPOST; // make raw

    // see: http://unixwiz.net/techtips/termios-vmin-vtime.html
    toptions.c_cc[VMIN]  = 0;
    toptions.c_cc[VTIME] = 20;
    
    if( tcsetattr(fd, TCSANOW, &toptions) < 0) {
        perror("init_serialport: Couldn't set term attributes");
        return -1;
    }

    return fd;
}

This code could be modified to get data from the Web via an environment variable for example, data = getenv(“QUERY_STRING”);. See the Web page, http://www.cs.tut.fi/~jkorpela/forms/cgic.html for details.

5. Install the CGI application or the PHP script on the Web server.

  1. Place the application into the required Web server directory. If it is a CGI application place the file into the cgi-bin directory, for example the /usr/lib/cgi-bin directory.
  2. If required, set the CGI file permissions.
    1. chown root.root ???.cgi
    2. chmod +s ???.cgi

References