Another PICAXE/Perl Data Gathering Application

Phase Meter Computer Interface

Sends pendulum phase and temperature data to a computer.

Please read first Electronic Pendulum Driver and Pendulum Phase Comparator for background on this project.

Max Carter


This article discribes the hardware that passes phase data from the pendulum phase comparator (phase meter) to a computer via the serial port, along with the program that makes it work. It's based on the very easy to use PICAXE 08M2 microcontroller. The article also shows how to install and run the Perl code on the computer that collects the data. The two programs form the core of the pendulum 72-hour phase record and 365-day phase record web pages. Some of the information presented might be useful in your own data-gathering application.



Computer Interface - As Built

The interface plugs into the phase meter board. Connections to the temperature sensor and computer serial port are made through the 3-pin headers.

Interface Schematic

Parts sources shown below.

The interface monitors two analog voltages: the output from the phase meter's integrator (J1-2) and the voltage from a LM34 temperature sensor (J2-2) placed near the pendulum. The first section of the LM358 opamp shifts and scales the voltage from the integrator. The voltage presented to the 08M pin 5 varies from 1.0 to 4.5 volts, depending on pendulum phase. The 08M reads the pin 5 voltage and converts it to a binary word that varies from about 205 (dec) to 925 (dec). Note that the spread is 720. This number corresponds to the 720° peg-to-peg range of the phase meter.

The second section of the LM358 scales the voltage from the LM34 sensor. The opamp multiplies the sensor output voltage by four (4). The voltage presented to the 08M2 pin 6 can vary from 2.00 volts (50°F/10°C) to 4.16 volts (104°F/40°C). The 08M2 reads the voltage on pin 6 and converts it to a binary word that varies from 410 (dec) to 852 (dec).

When polled by the computer, the 08M sends the phase and temperature data (the two binary words) via pin 7 to the computer's serial port.

The PICAXE 08M2 (08M) Microcontroller
The 08M2 is versatile and very easy to use. Programming is in Basic and requires only a serial port (COM) connection to a computer running the (free) PICAXE programming editor.
  • Please read Communicate with the PICAXE to get a feel for the 08M(2) and how it can be programmed and used to collect and send data to a computer.

  • A full description of the complete PICAXE family of microcontrollers, along with the free programming software, is at picaxe.com.

  • The links at the bottom of this page show some other PICAXE/PC data collection projects.


Programming the 08M2
The 08M2 (or 08M) must be plugged into a programming board to load the program. (The program is shown below.)
You don't really need to buy such a board since building one for the 08M(2) is easy enough (or simply use a solderless breadboard).

RS-232 DE9 connector08M picaxe programming circuit


Get the free programming software and learn all about PICAXE microcontrollers at www.picaxe.com.


No Serial Port Available?
If no serial port is available, the easiest way to provide one is with a FTDI cable. It plugs into a USB port and provides an instant serial port (DE9). The one shown is from Amazon. See also: Communicate with the PICAXE for some other options.

USB/serial adaptor

Schematics produced with DCCAD.

Parts

        PICAXE 08M2 microcontroller: Sparkfun/08M2 or PICAXE.com
7805 regulator:Futurlec/7805T
LM358 opamp:Futurlec/LM358N
Resistors, capacitors, diodes:Futurlec/components

back


Firmware/Software

Two programs are shown below:

  1. The firmware for the 08M2 chip (in PICAXE Basic),
  2. The Perl script that acquires the phase/temperature data via the serial port.


(1)

08M2

Copy the following code to the PICAXE Programming Editor and program the chip (works also on 08M):


main:

	SerIn 3, N2400, ("a="), b0	'gets first character after qualifier ("a=") 
						'from server
   
	if b0 = "p" then  
		
	gosub get_phase	'calls up "get_phase" subroutine below
	
	endif
	
	goto main
	
	
get_phase:

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


(2)

Perl Script

Requires late-model ActivePerl installation
[Download and install the Community Edition (free), here]

And module:

  • Win32-SerialPort
Installing Perl Modules
  • Open command window [run CMD from start menu]
  • navigate to the perl\bin directory [type cd\perl\bin <enter>]
  • type ppm <enter> [allow Package Manager to load]
  • click left button (View all packages)
  • select (highlight) packages to be installed
  • click 'mark for install' button
  • click 'run marked actions' button

Copy the following code (in blue) to your favorite text editor. Name and save the file with .pl extension (ex., get_phase.pl) to a location on the computer (ex., c:\pendulum).


use Win32::SerialPort;

$Sport = new Win32::SerialPort('COM1'); #this creates an "object", "class" or something, named $Sport
					#can be any available COM port

$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_phase($)  {		#subroutine "get_temp                      "

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

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

	do {

sub no_resp  {			#No response subroutine

die "no response from interface";				

}

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

	no_resp;				#calls no_resp subroutine above

	}

	$_.= $Sport->read(1);	#reads serial port chr
	
	}


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

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

	}

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

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

@accum = split(' ',$_);		#splits phase and temperature into an array, keys on space (' ')


$phase = $accum[0];		#first item in array

$phase = ($phase - 567);	#the number 567 is the sum of 205 and 360, it sets
				#the "left" end of the scale (-360 degrees), the
				#number (567) can be varied to calibrate the
				#interface if you want
							
$phase = ($phase * .97);	#scale correction factor, it mostly affects
				#the "right" end of the scale (+360 degrees), 
				#vary this number (.97) to calibrate the interface
				#if you want, comment the line if calibration
				#is not required


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


$temp = $accum[1];	#second item in array

$temp =	($temp * 4.88);   #This is the voltage scale factor; converts 0-1023 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 is 5.00 volts. 
			#Thus, 5.00 x 1000/1024 = 4.88; the scale factor is 4.88

$temp = ($temp / 4);	#divides by 4 (remember, the voltage from the temperature sensor is
			#amplified by a factor of 4 before transmission)
			
$temp = int($temp + .5);	#rounds to nearest whole number

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

$temp = ($temp + 1);		#correction (if necessary)


print "Phase: $phase    Temperature: $temp";


Run

To run the application,

  • Open the command line window (run CMD from the start menu)
  • Navigate to the location where you saved the program (cd\pendulum <enter>).
  • At the prompt, type perl get_phase.pl <enter>.

It should look something like this:




Onward

Displaying the phase data statically on a computer screen offers little or no utility over simply watching the phase meter. However, the hardware and programs shown above can form the foundation for applications that store data, generate graphs and produce internet web pages. The code below, for example, when added the Perl code above, saves 72 hours of phase and temperature data (one measurement every 10 minutes) in a text file for retrieval later for graphical display on a web page.


Additional Code Saves Phase and Temperature Data to a Text File

  • Copy the following code (in blue) to your favorite text editor.
  • Add path information.
  • Select all and copy (edit, select all; edit, copy)
  • Open the above Perl code file (get_phase.pl) and paste the additional script at the bottom of the file (after the last line)
  • Save

#-----------------this section records pendulum PHASE data-------------------


open(ACCUMDATA,">>c:/path/phase.txt");	#assigns the handle "ACCUMDATA" and opens the phase.txt file.
					#Opens for append (>>).

print ACCUMDATA "$phase " ;  #writes phase data to file, note the space

close ACCUMDATA;           # closes the file

open(ACCUMDATA,"<c:/path/phase.txt"); #assigns the handle "ACCUMDATA" and opens the phase.txt file for read (<).

$data = ; #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 > 433)  {		#desired number of entries plus one, make this any number you want
				#note: 432 represents one reading every 10 minutes for 3 days (72 hours)

shift(@accum);  #shifts data to left, throws out oldest entry, limits file size to 432 entries

}
  
}

while ($number > 432);		#desired number of entries

open(ARRAY,">c:/path/phase.txt");  #open for write (>) this clears the file

foreach(@accum)  {  

print ARRAY "$_ ";  #writes array data to the phase.txt file


}

close ARRAY;


#--------------------this section records pendulum TEMPERATURE data---------------------


open(ACCUMDATA,">>c:/path/pendtemp.txt");	#assigns the handle "ACCUMDATA" and opens the pendtemp.txt file.
						#Opens for append (>>).

print ACCUMDATA "$temp " ;  #writes temperature data to file, note the space

close ACCUMDATA;           # closes the file

open(ACCUMDATA,"<c:/path/pendtemp.txt");	#assigns the handle "ACCUMDATA"
						#and opens the pendtemp.txt file for read (<).

$data = ; #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 > 433)  {		#desired number of entries plus one, make this any number you want

shift(@accum);  #shifts data to left, throws out oldest entry, limits file size to 432 entries

}
  
}

while ($number > 432);   #desired number of entries

open(ARRAY,">c:/path/pendtemp.txt");  #open for write (>>) this clears the file

foreach(@accum)  {  

print ARRAY "$_ ";  #writes array data to the pendtemp.txt file


}

close ARRAY;


Windows Task Scheduler should be programmed to run the combined file (path\get_phase.pl) at the desired interval.
Your choice here, suggest 10 minutes.




Links to Working Pages Showing Pendulum Performance

And Other Pages of Interest


Pendulum Data

Real-Time Phase and Temperature

72-Hour Phase and Temperature Record (Graphs)

365-Day Record (Graph)


Background on This Article

Electronic Pendulum Driver

Pendulum Phase Comparator


PICAXE Communication/Data-Gathering/Web Articles

Communicate with the PICAXE

Web Server Interface

Outside Temperature/Server Interface


LM34/35 Related Projects

Temperature-Compensated Solar Battery Charger

Electronic Attic Fan Thermostat








cat