PICAXE Microcontroller/Personal Web Server

PC Communicates with the PICAXE and the INTERNET

Gathers Data, Controls Stuff

Read first: Communicate with the PICAXE


Background

This website, maxmcarter.com, is hosted on a server running on an old desktop PC (a hand-me-down from my son) here in my home shop/lab. It's possible to do that because my ISP provides me with a static IP address. The server is Apache 2, with PHP5 and (Active)Perl installed, running over Windows XP.

Among the advantages of hosting a website on your own PC is cost savings. The only ongoing cost is for electric power - about $6 per month in this case. The server runs 24/7/365. The cost of my connection to the internet is not included since I would be paying for that anyway, even if there were no server. My ISP does not charge extra for the static IP and server connection.

An even bigger advantage to having the server on the premises is that it gives me total control of the physical server and the website. I can do pretty much anything I want with the thing. Among my interests is gathering realtime data from various experiments and making them available on the internet via the webserver. Here's an earlier example. The PICAXE microcontroller - possibly the easiest-to-use microcontroller ever - offers another, simpler approach to data gathering and control via PC/web server.

Server/PICAXE Interface

This page shows some coding that will interface a PC/server to the PICAXE via the serial port. Before reading, please read Communicate with the PICAXE for information on physically connecting, interfacing and communicating with the PICAXE chip. The applications shown here are extensions of the get-data-control-stuff-with-a-PC-via-the-serial-port idea introduced in that article. These examples in no way exhaust the possibilities for remote control and monitoring afforded by mating the PICAXE to a server. More pins on larger PICAXE chips; more chips connected together in a wired or wireless network; there are endless possibilities.

This page will not show how to set up a web server. If you're interested in doing that, I found Apache, MySQL, and PHP Web Development All-in-One Desk Reference for Dummies to be helpful. There are many other how-to references out there, along with LOTS of information available on the Web.

If your PC is not a web server (and you don't want it to be), Perl and the CGI script can be run on your PC and addressed directly from your browser. (A GUI written in C# or Visual Basic would be a another approach. See Virtual Serial Port Cookbook, for example.)


Here's an Example of a Control Page

Go ahead and click SEND. You can turn a little light on my 08M board on and off!
Note: Opens a new tab/window. Click CLOSE to return to this spot.

PICAXE Control


Control 1

08M Out 2 (pin 5)

Select command, click SEND

TURN DEVICE 1 ON
TURN DEVICE 1 OFF
GET STATUS

Control 1: Send GET STATUS to connect

Server room
temperature:




cat



Here's a Temperature Only Example

Get server room temperature.

Note: Opens a new tab/window. Click CLOSE to return.




Here's a 24-Hour Temperature Graph Application

It's another application running on this server.
A CGI script polls the PICAXE/temperature sensor at 30-minute intervals and stores the results in a file.
A graphical program (written in PHP) reads the file and generates the graph. The latest point (#24) was recorded within the last 30 minutes.

Server Room Temperature - 24-Hour Record

For an expanded version of this application adapted to collecting outside temperature data,
including hardware, software and server setup details, click
here.



The Code

With the server hardware and software background in place, implementation of the PICAXE/server interface involves four areas:

  1. Verifying Apache configuration,
  2. Installing the serial port driver,
  3. Copying the CGI script file to the cgi-bin folder, and
  4. Loading the PICAXE Basic program.

Apache:

Open your Apache configuration file and make sure the statements

ScriptAlias /cgi-bin/ "path/cgi-bin/"

and
<Directory "path/cgi-bin">
    AllowOverride None
    Options None
    Order allow,deny
    Allow from all
</Directory>
are present and uncommented (uncomment if it's commented). Edit "path" to show the path to the cgi-bin folder on your machine (for example: c:/program files/apache group/apache2). Save and re-start Apache. Note: It is only necessary to do this once.


The serial port driver:

The serial port driver is a perl module called "Win32-SerialPort". The module is installed from the command line in the perl/bin directory as follows:

From the Windows start menu click run, in the Open: field type CMD, click OK, navigate to the perl/bin directory.

Type ppm<return>.

Then type install http://www.bribes.org/perl/ppm/Win32-SerialPort.ppd<return>.

The program will find and install the module. Also, "Win32-API" must be installed if it isn't already :

Type install http://www.bribes.org/perl/ppm/Win32-API.ppd<return>

Note: It is only necessary to do this once.


The CGI script (for the Control Page application above):

This script supports only the Control Page application above. Scripts for other applications should be placed in the cgi-bin folder and called by those applications. (Additional scripts can be seen here.) Copy the following Perl code (or other script) to your favorite editor (eg Notepad), add paths, filenames, URLs, etc. where called for, and save to the cgi-bin folder as a Perl file (filename.pl):


#!path/bin/perl.exe

# the very first line tells Apache where Perl is,
# the line must start with "#!"  path usually is c:/perl

print "Content-type: text/html\n\n";   #generates HTML page
print "<html>\n
<head>\n
<title>Web Server/PICAXE Control Interface Page</title>\n
</head><body>\n

<table width='100%' border='0'><tr><td><td width='80%'>\n
<h1 align='center'>PICAXE Control Page</h1>\n


<hr align='center'>\n
<h3>Control 1</h3>\n
<h4>08M Out 2 (pin 5)</h4>
<p>Select command, click SEND</p>
<form method='post' action='/cgi-bin/filename.pl'>\n
<input type='radio' name='c' value='n'>TURN DEVICE 1 ON<br>\n
<input type='radio' name='c' value='f'>TURN DEVICE 1 OFF<br>\n
<input type='radio' name='c' value='s' checked='checked'>GET STATUS<br>\n

<input type='submit' Value='SEND'>\n



</form>\n
<br>\n

<font size='4'>Control 1: </font>";


$cmd = readline(STDIN); #reads the input command from client browser
			#$cmd will be "c=n" (on), "c=f" (off), "c=t" (temp) or "c=s" (status)


#open serial port

use Win32::SerialPort;

$Sport = new Win32::SerialPort('COM1');	#this creates an "object",
					#"class" or something, named $Sport

$Sport->baudrate(2400);		#configures serial port
$Sport->parity('none');
$Sport->databits(8);
$Sport->stopbits(1);
$Sport->handshake('none');
$Sport->write_settings;




$stoptime = time + 2;	#gets computer time (seconds), adds 2 sec
			#this is the length of time the program is allowed to run



sub get_control($)  {		#subroutine "get_control"

	$Sport->write($cmd);	#writes $cmd to serial port (sends command to picaxe)

	$_ = '';			#clears $_  (sets to 'nothing')

	do {

sub no_resp  {			#No response subroutine

	
	print "<font size='4'>";
	print "No response from sensor...";	#prints this and stops program
						
print "<br><br><hr>\n
</td><td></td></tr></table>\n
<p align='center'>Web host: <a href='URL'</a>yoursitename</p>\n
<div align='center'><img src='yourfavicon'></div>\n
</body>
</html>";


die;				

}

	if (time >= $stoptime)  {		#if current time greater than 
						#or equal to stoptime,

	no_resp;				#calls no_resp subroutine above

	}


	$_ .= $Sport->read(1);	#reads serial port data, one chr at a time
								#".=" is concatenate operator,
		 						#concatenates new chr with previous chrs in the string
	
	}

	while (!/\r/);    	#until carriage return (\r) received


	return $_;		#ends do-while loop, returns $_ value

	}

$_ = get_control ("");		#calls the get_control subroutine above




@accum = split(' ',$_);  #converts string to array, splits $_ at ' ' (space)



if ($accum[0] == 0)  {

print "<font size='5' color='red'>OFF</font>";  #prints "off" if first number in array = 0

}

elsif  ($accum[0] == 1)  {

print "<font size='5' color=' green'>ON</font>"; #prints "on" if first number in array = 1

}



$temp = $accum[1];	#this gets the 0-255 AD voltage reading from temp sensor

$temp = ($temp * 5.08);	#This is the voltage scale factor; converts 0-255 to tens of millivolts.
			#The scale factor is determined by multiplying the power supply
			#voltage (as measured with a digital multimeter) on the PICAXE chip by
			#1000/1024.  The power supply voltage in this case measured 5.2 volts. 
			#Thus, 5.2 x 1000/1024 = 5.08. If you don't have a digital multimeter,
			#use 5.0 in the calculation; the scale factor in that case is 4.88

$temp = int($temp + .5);	#rounds to nearest whole number

$temp = ($temp / 10);		#converts tens of millivolts to degrees

$cal = 0;			#calibration factor; change to positive or negative 
				#number to correct the sensor, if necessary

$temp = ($temp + $cal);		#calibrates temperature sensor



print "<br><br><font size = '4'>Server room<br>temperature: 
</font><font size='5' color='blue'>";
print $temp;
print "&deg;C</font>";
 

print "<br><br><hr>\n
</td><td></td></tr></table>\n
<p align='center'>Web host: <a href='URL'>yoursitename</a></p>\n
<div align='center'><img src='yourfavicon'></div>\n
</body>
</html>";



The PICAXE code (supports all 3 applications above):

This code, in PICAXE Basic, supports polling from the control page, "get temperature" page, and graph generator applications above. Copy the code into the PICAXE Programming Editor and program the chip:

   

 main:
 

	SerIn 3, N2400, ("c="), b0  'gets first character after qualifier ("c=") from server
		

	
	if b0 = "n" then  'looks for "on"
	
	high 2		'turns on the output (start motor, turn on light, etc.)
	
	gosub get_status	'calls up "get_status" subroutine below


	
	else if b0 = "f" then  'looks for "f" (off)
	
	low 2  'turns off the output
	
	gosub get_status	'calls up "get_status" subroutine below


	
	else if b0 = "t" then 'looks for "t" (temp)
	
	gosub get_temp	'calls up "get_temp" subroutine below
	
	SerOut 0, N2400 , (#b2, 13)	'sends temp + CR to server
	
	
	
	else if b0 = "s" then 'looks for "s" (status)
	
	gosub get_status	'calls up "get_status" subroutine below
	
	endif
	
   
	goto main
	
	
get_status:
 
    	
   	readoutputs b1
   	
   	gosub get_temp	'calls temp subroutine below
	
	SerOut 0, N2400, (#bit10 ,32, #b2, 13)	'Sends status and temp to server. 
						'Bit 10 is the on/off status of Out 2.
						'The bit is transmitted as an ASCII
						'character - ie,
						'0 = ASCII 48, 1 = ASCII 49.
						'32 is space, #b2 is the temp data,
						'13 is CR (carriage return)
						    
	return
   
  
 get_temp:
		
	
	ReadADC10 4, b2	'Reads the voltage on In 4; returns a value between 0 and 255,
			'ie, the least significant 8 bits (byte) of a 10-bit word.
			'This byte represents a voltage of 0 to approximately 1.25.
			'It's not necessary to read the most significant bits.
			'The server calculates the actual voltage and temperature 
			'from this data.
	
   	
   	return
   	


"These examples in no way exhaust the possibilities for remote control and monitoring afforded by mating the PICAXE to a server."



Related Links

Communicate With the PICAXE

PICAXE Outside Temperature/INTERNET Project






cat