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).
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.
Schematics produced with DCCAD .
Parts
back
Firmware/Software
Two programs are shown below:
The firmware for the 08M2 chip (in PICAXE Basic), 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 ]
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
Background on This Article
PICAXE Communication/Data-Gathering/Web Articles
LM34/35 Related Projects