Sensor2
multiple temp sensors
Edsard Boelen, 02-march-2007
this project is to record the CPU, room and outside temperature and show it in one graph. This time, the digital, factory calibrated DS1820 IC's are used.
see past week graph
see past 24 hours
see all time graph
the idea
the ds1820 uses the dallas 1wire protocol,
the time window of the data is 50us,
which is just too fast for a non-realtime multitasking OS.
These days, microcontrollers are very cheap and advanced,
so let them do the task of converting the 1wire data to simple rs232 digits
with the temp.
the data is logged in a plain text file, and phplot can draw nice graphs from it.
the interface
I used quozl's temp sensor project with the PIC12C509, see
http://quozl.us.netrek.org/ts/
a picture of the board:

the outside sensor

the temp logger
At the moment the device is connected to the serial port,
and the serial port is enabled, it will send the data at 2400 baud.
So in fact cat /dev/ttyS0 or /dev/ttyUSB0 will show you a readout every second.
If not, then check the com port. for example run
comtest or set the tty speed with stty -F /dev/ttyS0 2400
I wrote quickly a C app which will be run every 30 minutes by the cron daemon
templog.c
#include <stdio.h> /* required for file operations */
#include <stdlib.h>
#include <pthread.h> // compile with -lpthread
#include <time.h>
FILE *fr;
void *readlines();
main()
{
pthread_t thread1;
int iret1;
iret1 = pthread_create( &thread1, NULL, readlines,NULL);
sleep(20);
exit(0);
}
void *readlines()
{
int n,cnt=0,number;
char line[80];
char *lch;
float temp1,temp2,cputemp;
FILE *output = NULL, *i2c = NULL;
time_t now;
struct tm *tm;
fr = fopen ("/dev/ttyS0", "rt");
while ((fgets(line, 80, fr) != NULL) && cnt < 8)
{ lch = line + strlen(line) - 1;
while (*lch == '\r' || *lch == '\n') {
*lch-- = '\0';
if (lch < line) break;
}
lch = line;
while (*lch == '\r' || *lch == '\n') lch++;
if (!isdigit(*lch)) continue;
number = atoi(lch)-1;
if (number < 0 || number > 3) continue;
lch++; if (*lch != ' ') continue;
if (strlen(lch) > 9) lch += 11;
lch++; if (number == 0)
sscanf(lch, "%f", &temp1);
if (number == 1)
sscanf(lch, "%f", &temp2);
cnt++;
}
now = time(NULL);
tm = localtime(&now);
fclose(fr);
i2c = fopen("/sys/bus/i2c/devices/0-002d/temp2_input", "r");
if (i2c == NULL) { perror("i2c bus"); exit(1); }
if (fgets(line,10,i2c) != NULL)
{
sscanf(line, "%f", &cputemp);
if(cputemp > 1000)
cputemp = cputemp /1000;
}
fclose(i2c);
output = fopen("xxx.log", "a");
if (output == NULL) { perror("xxx.log"); exit(1); }
fprintf(output,"%04d|%03d|%02d|%02d|%0.2f|%0.2f|%0.2f\n", tm->tm_year+1900,tm->tm_yday+1,
tm->tm_hour, tm->tm_min, temp1 , temp2 , cputemp);
fclose(output);
}
the image generator
I used phplot
for the image generation, the source codes are:
<?php
include("phplot.php");
$timep = $_GET["timep"];
if($timep == "24h")
$graph = new PHPlot(500,400);
else
$graph = new PHPlot(800,400);
$mode = "silent";
include("read_data.php");
$graph->SetXDataLabelAngle(90);
$graph->SetDataValues($stack);
$graph->SetYLabel("Temp C");
$graph->SetPlotType("lines");
$graph->SetDrawXDataLabels(true);
$graph->SetLineStyles("solid");
$graph->SetDataColors(array("red","blue",array(00,166,00),array(166,166,0)),"");
$graph->SetLegend(array("room","outside","cpu","room2"));
$graph->SetLegendPixels(50,10);
$graph->DrawGraph();
?>
and read_data is
<?php
$stack = array();
$lfile = "***.log";
$data = file($lfile);
$cend = count($data);
$cbegin = 0;
if (($timep=="24h") && ($cend > 100))
{
$cbegin = $cend-48;
}
if (($timep=="week") && ($cend > 400))
{
$cbegin = $cend-336;
}
$step = ($cend-$cbegin)/30;
$lcnt = $step;
$i=$cbegin;
for($i; $i<$cend;$i++)
{
$line = $data[$i];
$expl = explode("|",$line);
if ($lcnt >= $step)
{
$outformat = '%d %B %H:%M';
$tstamp = mktime($expl[2], $expl[3],0,1,$expl[1],2007);
$dd = strftime($outformat, $tstamp);
array_push($stack, array($dd,$expl[4],$expl[5],trim($expl[6])));
$lcnt=0;
}
else
{
array_push($stack, array(" ",$expl[4],$expl[5],trim($expl[6])));
$lcnt++;
}
if ($mode != "silent")
echo "$step $expl[4] - $expl[5] - $expl[6] <br> ";
}
?>