Electronic Construction/PICAXE Microcontroller/Apache Server/PHP and Perl Programming
Project

PICAXE Gets Outside Temperature Data,
Apache Server (with PHP and Perl) Puts it on the INTERNET

PICAXE Microcontroller Application Sends Local Temperature Data to the World

Server Configuration and Software

Max Carter


For background, please read first:

Communicate with the PICAXE

PC Communicates with the PICAXE and the INTERNET

PICAXE Outside Temperature/INTERNET Project (Hardware)



As with the previous PICAXE/server applications, getting the project up and running involves several areas:

  1. Configuring Apache for PHP, CGI scripts (Perl) and SHTML (server-side includes).
  2. Installing the serial port driver,
  3. Installing the CGI (Perl) scripts that acquire the PICAXE temperature data through the serial port,
  4. Configuring PHP for graphics,
  5. Installing the PHP code that generates the temperature graph,
  6. Loading the PICAXE program,
  7. Configuring Windows Scheduled Tasks to record the temperature readings, and
  8. Incorporating the generated text and graphs into a Webpage.

1. Apache Configuration:

This section assumes an up and running Apache server on a Windows machine and that win32 versions of PHP and Perl have been downloaded and installed in their respective folders (usually c:\perl and c:\php). [Get (Active)Perl here, get PHP here.]

Open the Apache configuration file. Then:

Load php5 module: In the "LoadModule" section of the configuration file, at the bottom of the module list type or uncomment

LoadModule PHP5_module "path/php5apache2.dll"    (be sure to include the double quotes)

edit path to show the location of the php5apache2.dll file. For example, c:/php (use forward slashes).

Tell Apache where the PHP INI file is: On the next line type (or copy/paste)

PHPIniDir "path/php"    (be sure to include the double quotes)

edit path to show the location of the PHP INI file. Example, c:/ (use forward slashes).

Add PHP file type: Find the "AddType" section of the configuration file. This will usually contain several "AddType" lines, along with some explanatory comments. Add this line near the beginning of the section:

AddType application/x-httpd-php .php

Enable CGI: Verify these statements are present and uncommented.

ScriptAlias /cgi-bin/ "path/cgi-bin/"    (be sure to include the double quotes)

and
<Directory "path/cgi-bin">
    AllowOverride None
    Options None
    Order allow,deny
    Allow from all
</Directory>
    (be sure to include the double quotes)

Edit path, if necessary, to show the path to the cgi-bin folder on your machine, for example c:/program files/apache group/apache2 (use forward slashes).

Enable server-side includes: This is not strictly necessary, but it allows you to insert CGI script-generated text, such as temperature readings, into web pages. The page file extension must be specifed as ".shtml". The text can also be inserted using PHP or JavaScript (see 8 below), in which case these steps can be ignored.

Uncomment the following lines

AddType text/html .shtml

and

AddOutputFilter INCLUDES .shtml

Find the line

<Directory "path/htdocs">

where path is the location of the htdocs directory, for example c:/Program Files/Apache Group/Apache2. Below this line find the line beginning with the word

Options

Add the word

" Includes" (WITHOUT the quotes)(WITH the space)

after the last word in the line. The line should now look something like this

Options FollowSymLinks Includes

Save the configuration file and re-start Apache.

2. The Serial Port Driver:

(see Communicate with the PICAXE for more information about communicating with the PICAXE chip through the server's serial port.)

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>

Type Exit to close the command window.


3. The CGI (Perl) Scripts:

Here are 3 CGI scripts you might want to use (any or all):

  1. Get temperature (°F): Returns the temperature in °F format. This script is useful if you want to get a temperature "snapshot" and (for example) drop it into a web page, spreadsheet or whatever.
  2. Get temperature (°C): Returns the temperature in °C format. Likewise, takes a temperature "snapshot", in degrees Celsius.
  3. Get temperature/write to text file: Writes temperature data to a text file for later recall by the graphing program. It works in conjunction with the PHP Temperature Graph program below.

Copy one of the following Perl scripts 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):


Get temperature (°F):


#!path/bin/perl.exe

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


#open serial port

use Win32::SerialPort;

$Sport = new Win32::SerialPort('COM3');	#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;

print "Content-type: text/html\n\n";   #tells browser HTML to follow


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



sub get_temp($)  {		#subroutine "get_temp"

	$Sport->write("c=t");	#writes "c=t" to serial port (sends command to picaxe)

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

	do {

sub no_resp  {			#No response subroutine



die;				

}

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

	no_resp;				#calls no_resp subroutine above

	}


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


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


	return $_;		#returns $_ value

	}

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



$_ =~ (s/\r//);			#gets rid of the CR, =~ is the substitution operator, substitues \r with "nothing"



@accum = split(' ',$_);			#creates an array named "accum"; the array contains
					#two values: the A/D voltage data from I/O 1 (pin 6) 
					#and the A/D voltage data from I/O 2 (pin 5) of the 08M


$temp = ($accum[1] - $accum[0]);	#subtracts the two voltage readings




$temp = ($temp * .493);	#This is the voltage scale factor; scales 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
			#100/1024.  The power supply voltage in this case measured 5.05 volts. 
			#Thus, 5.05 x 100/1024 = .493. If you don't have a digital multimeter,
			#use 5.0 in the calculation; the scale factor in that case is .488


$temp = ($temp - 2);		#correction, if necessary; the LM34 sensor is very linear,
				#but the system as a whole may require absolute correction;
				#in this case, by comparing the sensor to an accurate 
				#thermometer it was determined that the system
				#required a 2 degree negative correction

$temp = $temp + 100; 		#adds a constant


$int = int($temp);		#returns integer


$dec = $temp - $int;	#returns numbers to the right of the decimal point


if ($dec <= .25)  {	#if decimal is less than or equal to .25,

$dec = 0;		#sets to 0

}

elsif ($dec > .25 && $dec < .75)  {	#if decimal is greater than .25 and less than .75,

$dec = .5;				#sets to .5

}

else  {			#if decimal is greater than .75,

$dec = 1;		#sets to 1

}


$temp = $int + $dec;		#re-combines integer and decimal

$temp = $temp - 100;		#subtracts constant


print " $temp";




Get temperature (°C):


#!path/bin/perl.exe

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


#open serial port

use Win32::SerialPort;

$Sport = new Win32::SerialPort('COM3'); #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;

print "Content-type: text/html\n\n";   #tells browser HTML to follow


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



sub get_temp($)  {		#subroutine "get_temp"

	$Sport->write("c=t");	#writes "c=t" to serial port (sends command to picaxe)

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

	do {

sub no_resp  {			#No response subroutine



die;				

}

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

	no_resp;		  #calls no_resp subroutine above

	}


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


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


	return $_;		#returns $_ value

	}

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





$_ =~ (s/\r//);			#gets rid of the CR



@accum = split(' ',$_);			#creates an array named "accum"; the array contains
					#two values uploaded from the 08M: the A/D voltage 
					#data from I/O 1 (pin 6) and the A/D voltage data
					#from I/O 2 (pin 5)
					
		


$temp = ($accum[1] - $accum[0]);	#subtracts the two voltage readings




$temp = ($temp * .493);	#This is the voltage scale factor; scales 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
			#100/1024.  The power supply voltage in this case measured 5.05 volts. 
			#Thus, 5.05 x 100/1024 = .493. If you don't have a digital multimeter,
			#use 5.0 in the calculation; the scale factor in that case is .488
			#the number returned by this calculation represents the temperature
			#in degrees



$temp = ($temp - 2);		#correction, if necessary; the LM34 sensor is very linear,
				#but the system as a whole may require absolute correction;
				#in this case, by comparing the sensor to an accurate 
				#thermometer it was determined that the system
				#required a 2 degree negative correction



$temp = (($temp - 32) * 5) / 9;  #converts degrees F to degrees C

$temp = $temp + 100;		#adds a constant

#the following rounds the temperature data to the nearest half degree

$int = int($temp);		#returns integer


$dec = $temp - $int;		#returns numbers to the right of the decimal point


if ($dec <= .25)  {		#if decimal is less than or equal to .25,

$dec = 0;			#sets to 0	

}

elsif ($dec > .25 && $dec < .75)  {	#if decimal is greater than .25 and less than .75,

$dec = .5;				#sets to .5

}

else  {			#if decimal is greater than .75, 

$dec = 1;		#sets to 1

}



$temp = $int + $dec;	#re-combines integer and decimal

$temp = $temp - 100;	#subtracts constant

print "$temp";



Get temperature/write to text file:

#!path/bin/perl.exe

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


#open serial port

use Win32::SerialPort;

$Sport = new Win32::SerialPort('COM3');	#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 maximum time the program is allowed to run



sub get_temp($)  {		#subroutine "get_temp"

	$Sport->write("c=t");	#writes "c=t" to serial port (sends command to picaxe)

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

	do {

sub no_resp  {			#No response subroutine



die;				

}

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

	no_resp;				#calls no_resp subroutine above

	}


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


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


	return $_;		#returns $_ value

	}

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


$_ =~ (s/\r//);			#gets rid of the CR




@accum = split(' ',$_);			#creates an array named "accum"; the array contains
					#two values uploaded from the 08M: the A/D voltage 
					#data from I/O 1 (pin 6) and the A/D voltage data
					#from I/O 2 (pin 5)


$temp = ($accum[1] - $accum[0]);	#subtracts the two voltage readings



$temp = ($temp * .493);	#This is the voltage scale factor; scales 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
			#100/1024.  The power supply voltage in this case measured 5.05 volts. 
			#Thus, 5.05 x 100/1024 = .493. If you don't have a digital multimeter,
			#use 5.0 in the calculation; the scale factor in that case is .488
			#the number returned by this calculation represents the temperature
			#in degrees

$temp = ($temp - 2);		#correction, if necessary; the LM34 sensor is very linear,
				#but the system as a whole may require absolute correction;
				#in this case, by comparing the sensor to an accurate 
				#thermometer it was determined that the system
				#required a 2 degree negative correction


$temp = $temp + 100;		#adds a constant


#the following rounds the temperature data to the nearest half degree


$int = int($temp);		#returns integer


$dec = $temp - $int;	#returns numbers to the right of the decimal point


if ($dec <= .25)  {	#if decimal is less than or equal to .25,

$dec = 0;		#sets to 0

}

elsif ($dec > .25 && $dec < .75)  {	#if decimal is greater than .25 and less than .75,

$dec = .5;				#sets to .5

}

else  {			#if decimal is greater than .75, 

$dec = 1;		#sets to 1

}


$temp = $int + $dec;	#re-combines integer and decimal

$temp = $temp - 100;	#subtracts constant

$hour = (localtime())[2];	#gets hour

$min = (localtime())[1];	#gets minute


if (($min > 15) && ($min < 45))		#allows only 30 or 0

{

$min = 30;

}

else

{

$min = 0;

}

#the following line
#assigns the handle "ACCUMDATA" and opens the array.txt file. Opens for append (>>).
#path is the location of the temp.txt file, for example
#c:/progra~1/apache~1/apache2/htdocs/maxmcarter/tempgraph
#

open(ACCUMDATA,">>path/temp.txt");	
											

print ACCUMDATA "$temp $hour $min " ;  #writes temp data to file

close ACCUMDATA;           # closes the file

#the following line
#assigns the handle "ACCUMDATA" and opens the temp.txt file for read (<).
#path is the location of the temp.txt file, for example
#c:/progra~1/apache~1/apache2/htdocs/maxmcarter/tempgraph
#

open(ACCUMDATA,"<path/temp.txt"); 


$data = <ACCUMDATA>; #reads file

close ACCUMDATA;

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

do {

$number = scalar(@accum);  #gets number of entries in array

if ($number > 147)  {

shift(@accum);  #shifts data to left, throws out oldest entry

}
  
}

while ($number > 147);	#this allows only the last 24.5 hours worth of data
			#to be stored in temp.txt; the temperature data is
			#collected every 30 minutes; since each hour's entry
			#requires 3 values (temperature hours minutes), 24.5 hours 
			#worth of entries equals 147  [24.5 x 2 x 3 = 147]



#the following line assigns the handle "ARRAY",
#opens the file temp.txt for write (>) and clears the file
#path is the location of the temp.txt file, for example
#c:/progra~1/apache~1/apache2/htdocs/maxmcarter/tempgraph
#

open(ARRAY,">path/temp.txt");



foreach(@accum)  {  

print ARRAY "$_ ";	#writes array data to the temp.txt file
			#note the space after $_


}

close ARRAY;


4. Configure PHP for graphics:

This will load a PHP module called GD Graphics Library.

Find and open the php.ini file. Most likely it will be in the PHP folder, but could be in the Windows System folder. It may be listed as type "Configuration Settings"

In the Paths and Directories section, verify the line

extension_dir = "c:\php\ext"

is uncommented. Uncomment if necessary. This tells PHP where the extensions files are.

In the Dynamic Extensions section, uncomment the line

extension=php_gd2.dll

Save the INI file and re-start Apache.


5. The PHP Temperature Graph Program:

Copy the following PHP code to your favorite editor (eg Notepad), add paths, filenames, URLs, etc. where called for. Save the file to your website's HTTP files location, ie, htdocs/sitename/. Save the file as (filename.php):


<?php

#reads file, this is the temp data; path is location of the file

$tempdata = file_get_contents("path/temp.txt"); 

$array = split(' ', $tempdata); #creates an array, split by ' ' (space)




#the following gets time of last entry

$min = $array[146];

$hr = $array[145];


$ap = "AM";					#determines AM or PM

if ($hr >= 12)  {

$ap = "PM";

}


if ($hr > 12)  {			#converts to 12 hour format

$hr = $hr - 12;

}

if ($hr == 0)  {

$hr = 12;

}



if ($min == 0)  {			#sets 0 minutes to 1 minute

$min =   "01";

}

else  {						#sets 30 minutes to 31 minutes

$min = "31";

}

$time = "$hr:$min $ap";		#combines hour, minute and AM/PM



#the following multiplies by 5 and subtracts all values in array from 530;
#this number (530) is a correction factor which can be varied to calibrate
#the vertical temp scale on the graph


$b = 0;				#$b is a pointer;
				#points to the locations in the array
				#where the temps and times are;
				#0, 0+3, etc = temp;
				#1, 1+3, etc = hour;
				#2, 2+3, etc = minutes 


$dat = $array[0];			#starts at first array location

while ($b <= 144)  {		#this has to be 3 less than array length
				#to prevent error log message;
				#actual end of array is 147

$array[$b] = 530 - (5 * $dat);		#scales data as explained above;
					#in this case the
					#"vertical gain" = 5 pixels/degree

$b = ($b + 3);

$dat = $array[$b];

}



$graph = ImageCreate(600,830);	#creates image(x[pixels],y[pixels]),
				#starts in upper lefthand corner
 
$white = ImageColorAllocate($graph,255,255,255); 	#specifies color (RGB), 
$black = imagecolorallocate($graph,0,0,0);		#first color is backgound color
$red = imagecolorallocate($graph,255,0,0);
$blue = imagecolorallocate($graph,0,0,255);
$green = imagecolorallocate($graph,0,200,0);
$gray = imagecolorallocate($graph,240,240,240);
$dkgray = imagecolorallocate($graph,180,180,180);
$mddkgray = imagecolorallocate($graph,210,210,210);
$orange = imagecolorallocate($graph,255,128,0);
$dkgreen = imagecolorallocate($graph,0,160,0);
$ltblue = imagecolorallocate($graph,128,128,255);


imagerectangle($graph,50,1,535,740,$black);  #specifies rectange
					#($name,line,x1,y1,x2,y2[diagonal corners],$color) 


#the following draws the graticle lines: gray, medium dark gray, dark gray and green.
#spaced for degrees C

$y = 10;		#$y is vertical pixels

while ($y <= 740)  {

imageline($graph, 50,$y,534,$y, $gray);

$y = ($y + 9);

}

$y = 10;

while ($y <= 740)  {

imageline($graph, 50,$y,534,$y, $mddkgray);

$y = ($y + 90);

}

$y = 10;

while ($y <= 740)  {

imageline($graph, 50,$y,534,$y, $dkgray);

$y = ($y + 45);

}

imageline($graph, 50,369,534,369, $green);
imageline($graph, 50,370,534,370, $green);  #graticle line at freezing point
imageline($graph, 50,371,534,371, $green);




#the following generates the hash marks on the left vertical scale, spaced for degrees C


$y = 2;

while ($y <= 729)  {

imagestring($graph,5,46,$y,'-',$black); #specifies character [string]
					#($name,font size,x,y,'chr',$color)

$y = ($y + 9);

}


#the following generates the hash marks on the right vertical scale, spaced for degrees F


$y = 2;

while ($y <= 725)  { 

imagestring($graph,5,532,$y,'-',$black);	#specifies character [string]
						#($name,font size,x,y,'chr',$color)

$y = ($y + 5);

}


#the following puts in the red Cs and Fs

imagestring($graph,5,10,2,'C',$red);
imagestring($graph,5,578,2,'F',$red);
imagestring($graph,5,10,360,'C',$red);
imagestring($graph,5,578,360,'F',$red);
imagestring($graph,5,5,720,'C',$red);
imagestring($graph,5,578,720,'F',$red);


#the following generates the numbers on the left vertical scale, C

$y = 2;

$c = 40;

while ($y <= 280)  {

imagestring($graph,3,27,$y,$c,$black);	#specifies character [string]
					#($name,font size,x,y,'chr',$color)

$y = ($y + 9);

$c = ($c - 1);

}



while ($y <= 362)  {

imagestring($graph,3,34,$y,$c,$black); 

$y = ($y + 9);

$c = ($c - 1);

}


while ($y <= 443)  {

imagestring($graph,3,27,$y,$c,$black); 

$y = ($y + 9);

$c = ($c - 1);

}

while ($y <= 722)  {

imagestring($graph,3,20,$y,$c,$black); 

$y = ($y + 9);

$c = ($c - 1);

}


#the following generates the numbers on the right vertical scale, F


$y = 3;

$f = 104;

while ($y <= 732)  {

imagestring($graph,3,548,$y,$f,$black); #specifies character [string]
					#($name,font size,x,y,'chr',$color)

$y = ($y + 10);

$f = ($f - 2);


}





#the following puts the notes at the bottom

imagestring($graph,3,1,740,'24 Hrs',$dkgreen);    
imagestring($graph,3,1,753,'Prev.',$dkgreen);
imagestring($graph,3,545,740,'Latest',$dkgreen);
imagestring($graph,3,545,753,$time,$dkgreen);
imagestring($graph,3,545,766,'Today',$dkgreen);


#the following generates the hash marks on the horizontal scale

$x = 42;				#$x is horizontal pixels

while ($x <= 530)  {

imagestringup($graph,5,$x,744,'-',$black);	#specifies character [string]
						#($name,font size,x,y,'chr',$color)
						#"up" rotates the character 90 degrees

$x = ($x + 10);

}



#the following generates the numbers (hours) on the horizontal scale

$x = 47;				#$x is horizontal pixels

$b = 1;				#$b is a pointer; points to the locations  
				#in the array where the temps and times are
				#0, 0+3, etc = temp;
				#1, 1+3, etc = hour;
				#2, 2+3, etc = minutes 

if ($array[2] == 30) {

$x = 57;				#moves start point 10 pixels right

$b = 4;

}


while ($x <= 530)  {

$h = $array[$b];		#$h is hour number; starts at array position 4

if (($h > 0) && ($h < 10))  {

imagestring($graph,3,$x,745,$h,$black);	#puts single digits on the horizontal scale

if ($h == 6)  {

$x = $x - 5;

imagestring($graph,5,$x,770,'AM',$black);	#puts "AM" on the scale

$x = $x + 5;

}


}

if (($h > 9) && ($h < 12)) {

$x = $x - 3;					#shifts 3 pixels left

imagestring($graph,3,$x,745,$h,$black);		#puts 10 and 11 on the scale

$x = $x + 3;					#shifts 3 pixels right

}


if ($h == 12)   {

imagestring($graph,5,$x,745,'M',$orange);  #puts "M" on the scale

$x = $x + 1;

imagestring($graph,3,$x,757,'i',$orange);	#puts "idday" on the scale
imagestring($graph,3,$x,767,'d',$orange);	#shifted one pixel right
imagestring($graph,3,$x,777,'d',$orange);
imagestring($graph,3,$x,777,'a',$orange);
imagestring($graph,3,$x,777,'y',$orange);

$x = $x + 2;

imageline($graph,$x,1,$x,740,$gray);  #generates vertical graticle line (noon)

$x = $x - 3;

}


if ($h > 12)  {

$h = $h - 12;

if ($h == 6)  {

$x = $x - 5;

imagestring($graph,5,$x,770,'PM',$black);	#puts "PM" on the scale

$x = $x + 5;

}


if (($h > 9) && ($h < 12))  {

$x = $x - 3;

imagestring($graph,3,$x,745,$h,$black);

$x = $x + 3;

}

else  {

imagestring($graph,3,$x,745,$h,$black);

}

}


if ($h == 0)  {

imagestring($graph,5,$x,745,'M',$blue);

$x = $x + 1;

imagestring($graph,3,$x,757,'i',$blue);
imagestring($graph,3,$x,767,'d',$blue);
imagestring($graph,3,$x,775,'n',$blue);
imagestring($graph,3,$x,785,'i',$blue);
imagestring($graph,3,$x,793,'g',$blue);
imagestring($graph,3,$x,806,'h',$blue);
imagestring($graph,3,$x,816,'t',$blue);

$x = $x + 2;

imageline($graph,$x,1,$x,740, $gray);  #generates vertical graticle line (midnight)


$x = $x - 3;


}



$x = $x + 20;

$b = $b + 6;

}



#the code below dynamically draws the data plot onto the "graph paper"

$x1 = 50;		#sets lefthand starting point, x1, to 50 pixels

$y1 = $array[0];	#sets lefthand starting point, y1,
			#to the first calculated y value (from above)

$x2 = 60;		#sets ending point of first segment, x2, to 60 pixels

$y2 = $array[3];	#sets ending point of first segment, y2,
			#to the second calculated y value (from above)

$b = 3;			#this tells the while loop where to start


while ($x1 <= 520) {

imageline($graph, $x1, $y1, $x2, $y2, $blue);   #draws the segment

$x1 = $x1 + 10;                       			#moves segment start point
							#10 pixels to the right

$x2 = $x2 + 10;						#moves segment end point
							#10 pixels to the right

$y1 = $array[$b];					#segment y1 value (segment start data)

$b = $b + 3;						#increments "b" value (pointer)

$y2 = $array[$b];					#segment y1 value (segment end data)


}




#the following saves a record of the past 24 hours every night at one minute past midnight

if ($time == "12:01 AM")  {

$today = getdate();

$d = $today['mday'];

if ($d < 10)  {

$d = "0$d";	#adds leading 0

}

$m = $today['mon'];

if ($m < 10)  {

$m = "0$m";	#adds leading 0

}

$y = $today['year'];

$filename = "record/$y-$m-$d.png";  #concatenates date: year-month-day (uses double quotes)

ImagePNG($graph, $filename);	#saves image to file named [year-month-day].png
				#in a folder named "record"
				#this creates a folder full of png images;
				#I might make a movie of it someday


}



#the following sends the resulting graph to the client

header ("Content-type: image/png");		#header tells the browser
						#that a png image follows
 
ImagePNG($graph); 				#sends image to browser
 
ImageDestroy($graph);				#erases image from memory (frees up memory)

 
?>  

6. The PICAXE Program:

Copy the following 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 = "t" then  
		
	gosub get_temp	'calls up "get_temp" subroutine below
	
	endif
	
	goto main
	
	
get_temp:

	ReadADC10 1, W2		'gets voltage on I/O 1 (pin 6)
					'this is ground reference.
	
	ReadADC10 2, W3		'gets voltage on I/O 2 (pin 5)
					'this is Vout from sensor
	
	SerOut 0, N2400, (#W2, 32, #W3, 13)	'sends data to server
							'(data, space, data, CR)
	
	Return


7. Configure Windows Scheduled Tasks:

Windows Scheduled Tasks is configured to call every 30 minutes the "Get temperature/write to text file" CGI (Perl) script you installed in the CGI-BIN folder.

  • From the Windows Start Menu, click Control Panel;
  • In Control Panel, double click Scheduled Tasks;
  • Double click Add Scheduled Task; this opens the Scheduled Tasks Wizard;
  • Click Next; Click Browse; find the "Get temperature/write to text file" Perl script file you saved in the CGI-BIN folder; select and click Open;
  • Check the Daily radio button; click Next;
  • Select a start time near the top of the hour; select a start date (today would be good); click next;
  • You may need to enter a User Name and Password about here;
  • Check Open advanced properties; click Finish;
  • Under the Schedule tab, Click Advanced;
  • Check Repeat task; set to repeat every 30 minutes; check duration radio button; set duration to 24 hours; click OK.



8. Incorporate the Graphical and Text Data into a Webpage:

The graph:

The graph is the easiest. Simply drop the PHP filename and path to it into an image tag like so:

<div><img src="path/filename.php"></div>

where filename is the name you gave the PHP graph program and path is its location.


The text:

Incorporating the text (the temperature data) is also pretty easy - there are (at least) three options:

  1. Server-side include
  2. PHP
  3. JavaScript

Server-side include: The server must be configured for server-side includes (see above) and the webpage filename (URL) must have the file extension ".shtml". The tag that does it looks like this:

<!--#include virtual='/cgi-bin/filename.pl'-->    (single quotes)

where filename is the name of the Perl script that gets the temperature from the PICAXE. Simply drop the tag into the HTML code where you want the temperature to appear.

The server can also be configured to look at every incoming request for server-side includes (not just those with the .shtml extension), but it tends to slow the server's overall response time.



PHP: This does not require the server be configured for server-side includes - ie, forget the steps under enable server-side includes above - but does require PHP (see 1 above). The webpage filename (URL) must have the extension ".php". Drop this tag into the HTML code where you want the temperature data to appear:

<?php virtual("/cgi-bin/filename.pl"); ?>

where filename is the name of the Perl script that gets the temperature from the PICAXE.


JavaScript: This also does not require the server be configured for server-side includes - skip the steps under enable server-side includes above - but does require that JavaScript be enabled in the client browser.

Modify the print statement in the very last line of the Get temperature CGI (Perl) scripts above to read:

print "document.write('$temp');";

Drop the following tag into the HTML code where you want the temperature to appear:

<script language="JavaScript" src="/cgi-bin/filename.pl"></script>

where filename is the name of the Perl script that gets the temperature from the PICAXE.


With any of the above, you would probably want to follow the inserted text with "°F" or "°C".


Top

This page has been assembled with great care, mostly by copying and pasting directly from the actual server files. But ya never know. I may have left out some important step, or the cat may have stepped on the keyboard at some critical point during the process. - Max

The current temperature in Wheatland, Wyoming is 58°F ([an error occurred while processing this directive]°C).


Related Links

Communicate with the PICAXE

PC Communicates with the PICAXE and the INTERNET

PICAXE/Perl Dead-Man Alert System

PICAXE Outside Temperature/INTERNET Project (Hardware)
(Companion to this Page)

Wheatland, Wyoming 24-Hour Temperature Record






cat


+-