The old saying is that there's always more than one way to skin a cat. One of
the original GP3EZ demos took an LM34 temperature sensor and posted the result
to a web page using some off the shelf tools from the Cygwin toolkit.
The
GP3EZ software is very flexible, so naturally there is more than one way to
accomplish this goal. In this article, I'll show you yet another way, this time
using the GP3EZ's file logging capability and some custom code designed for the
task.
Here's the simple GP3EZ script:
Step # | Tag | Condition | Action | Next | Notes |
1 | Start | (wait) Analog 0>=0 V | External New File: c:\daq.txt |
This is going to read a temperature to the web using the gp3ezweb helper program. This step always triggers. But the step value will be the analog value which we will use to start off the output file | |
2 | digital | (wait) Input: XXXXXXXX | External Add File: c:\daq.txt |
Now we will get the digital input values and log them as line 2 | |
3 | (wait) Always | External program: c:\gp3ezweb c:\daqtemplate.htm c:\daq.txt
c:\daq.htm |
Now we run the gp3ezweb program. You'll need to adjust the paths. Note you might just as well have started a batch file or script that would run the program and then upload the daq.htm file to your server if you wanted to. Or you could make that the next step. Of course, if you are running on the web server, you can just arrange for the file to wind up in the server directory. | ||
4 | (wait) After 1/22/2008 9:44:06 AM Repeat 00:05:00 | Start | This step waits for 5 minutes. You could plug in an "after" delay if you prefer. Note that the after time resets itself on each trigger. So if it triggers at 09:44 the new trigger will be set for 09:49 (5 minutes later). The condition is that the time is simply "after" so to start with you can set the date/time to any time before now (which it should already be set that way) and that "primes" the pump. |
1/22/2008 9:39:06 AM,0.7519531,Start,{none}
1/22/2008 9:39:06 AM,57,digital,{none}
The first field is the time and date of the sample, the next field is the
value. After that is the name or number of the step that generated the line
(Start or digital, in this case). The final field is the GP3's current state
which we are not using in this example.
The LM34 has an output of
10mV/degree so the temperature is actually about 75.2 degrees. The digital input
is 57 which is 39 in hex or 00111001 in binary.
The template file is just
a text file. However, the gp3ezweb program replaces special character sequences
in the template with values from the data file to produce the output file. The
names of the fields are in curly braces (so {Start} and {digital} are the two
fields. You can also get the time and date of a field by prefixing it with @ (so
{@Start} would give you the time and date of the Start line. You can also use
{$state} to get the last state value (meaningless in this case) and {{} will
write out an actual curly brace. The field names are case sensitive. Here's a
simple template file:
<HTML>
counts={Start}
<HEAD><TITLE>GP3 Web Demo</TITLE></HEAD>
<BODY BGCOLOR=#C1C0C6>
<H1>GP3 Web Demo #2</H1>
<H3>{@Start}</H3>
<P>Raw
<P>Raw digital={digital}
<hr>
<P>Temp=
<SCRIPT language=javascript>
<!--
t={Start};
dio={digital};
t1=Math.round(t*1000)/10;
document.write(t1);
//-->
</SCRIPT>
<BR>
<P>Status:<BR>
<SCRIPT language=javascript>
<!--
for (i=128;i>=1;i=i>>=1) if (dio & i) document.write("<img src=led-on.jpg>"); else
document.write("<img src=led-off.jpg>");
//-->
</SCRIPT>
<P>
</BODY>
</HTML>
The variables are highlighted in red. Note that the most useful part of the page just sets the values into a Javascript that does calculations with the values.
The result is a page that looks like this:
Here's a zip file with all the files (including gp3ezweb): zip file
If you are curious, here's the source code for the program:
/* GP3EZWEB by AWC - http://www.awce.com */ #include#include // format of the GP3EZ output lines (conservatively spaced) typedef struct { char timedate[64]; char value[64]; char id[64]; } record; // last state char state[64]; // Maximum #of different values record records[128]; // high water mark in array int recordmax=0; int main(int argc, char *argv[]) { FILE *in=stdin; FILE *out=stdout; FILE *template; char line[1025]; char lineout[1025]; char *token; // set up file handles if (argc<=1) { fprintf(stderr,"Usage: gp3ezweb template [in|-] [out|-]\nUse dashes for standard input or output\n"); return 2; } template=fopen(argv[1],"r"); if (!template) return 4; if (argc>2 && *argv[2]!='-') in=fopen(argv[2],"r"); if (!in) { perror(argv[2]); return 1; } if (argc>3 && *argv[3]!='-') out=fopen(argv[3],"w"); if (!out) { perror(argv[2]); return 3; } // read input -- take last value and last state only while (!feof(in)&&fgets(line,sizeof(line),in)) { int i; token=strtok(line,","); if (!token) continue; // huh? // tenatively record this line strcpy(records[recordmax].timedate,token); token=strtok(NULL,","); if (!token) continue; strcpy(records[recordmax].value,token); token=strtok(NULL,","); if (!token) continue; strcpy(records[recordmax].id,token); // look to see if we can replace an old one for (i=0;i =recordmax) { recordmax++; } // get state token=strtok(NULL,"\n"); strcpy(state,token); } if (in!=stdin) fclose(in); // now copy the template to the output while (!feof(template) && fgets(line,sizeof(line),template)) { char *p1,*p2; int offset=0, i, tokenoffset=0; *lineout='\0'; // find {} while (p1=strchr(line+offset,'{')) { *p1='\0'; strcat(lineout,line+offset); p2=strchr(p1+1,'}'); if (!p2) break; offset=(p2+1)-line; *p2='\0'; token=p1+1; if (!strcmp(token,"{")) // literal { { strcat(lineout,"{"); continue; } if (!strcmp(token,"$state")) // state { strcat(lineout,state); continue; } if (*token=='@') tokenoffset=1; // time stamp for (i=0;i