[Home]Plotting DS18S20 Temperature Readings Using SVG

HomePage | RecentChanges | Preferences

Raspberry Pi and DS18S20 temperature measurement

This page records some work on using DS18S20 with Raspberry Pi and plotting using AWK, SVG and JavaScript.

Using the kernal extensions ( see links ) the Raspberry Pi can use the "one wire" interface to read the Dallas 18S20 temperature chips.

I use a shell script to poll the chips and append the readings to a file of JavaScript function calls and other text files.

An awk script is used to extract the text and populate the gbF() function calls. If written to a file, the file can be included into an SVG file.

Using JavaScript in an SVG file, I plot the data as a simple graph. The SVG file does a location.reload() to update.

This is run in the Midori 0.4.3 web browser that renders the SVG file.

example: http://www.dougrice.plus.com/raspberryPi_ds1820/loopDS18S20reportSVG.svg

files: http://www.dougrice.plus.com/raspberryPi_ds1820/

Raspberry Pi and DS18S20

One wire - DS18S20 reader

Used GPIO4 pin 7 - middle pin. 3v3 to power gnd to gnd

		/ 3v3  	
DS18S20	- top (|- buss --GPIO4--[4k7]--/
	  	\ gnd

Web pages to help:-

http://learn.adafruit.com/adafruits-raspberry-pi-lesson-11-ds18b20-temperature-sensing/hardware

http://learn.adafruit.com/adafruits-raspberry-pi-lesson-11-ds18b20-temperature-sensing/ds18b20

Shell Script - loop.sh

The script below starts the kernel module for "OneWire" and loops polling all the devices onthe Bus.

I have 4 DS18S20, which I read and set userfield1,userfield2,userfield3,userfield4 parameters in gbF() guestbook Function. This is appended to gbookFtemp.js on the desk top. The date is set to when I read the devices.

#! /bin/bash
#	
#  Shell Script to poll temperature chips 
#  usage:	 bash loop.sh
#
# http://learn.adafruit.com/adafruits-raspberry-pi-lesson-11-ds18b20-temperature-sensing/hardware
#
echo "---------------------"
ls /sys/bus
echo "---------------------"
sudo modprobe w1-gpio
sudo modprobe w1-therm

echo "---------------------"
ls /sys/bus
echo "---------------------"

while [[ 1 ]]
do
  echo "========" 		    > ~/Desktop/tmp.txt
  date 				   >> ~/Desktop/tmp.txt
  cat /sys/bus/w1/devices/10-*/name >> ~/Desktop/tmp.txt
  cat /sys/bus/w1/devices/10-*/w1* >> ~/Desktop/tmp.txt
  echo " "			   >> ~/Desktop/tmp.txt
  #
  # use AWK to extract the temperatures. appends gbF() to gbookFtemp.js
  #
  cat ~/Desktop/tmp.txt
  awk -f loop.awk ~/Desktop/tmp.txt 

  cat ~/Desktop/tmp.txt >> ~/Desktop/loop_log.txt
  sleep 3 
  
done  

Awk Script loop.awk

This awk script extracts the temperature and puts the results into the javascript include file.

#
#
# loop.awk
#
# usage: 	awk -f loop.awk loop_log.txt
#
#
# pull out the temperature from loop_log.txt written by loop.sh 
# Appends to "gbookFtemp.js"
#
#
#//gbF( name,email,postedOn,IPaddress,userfield1,userfield2,userfield3,userfield4,comments){


BEGIN {
  FS="="

  # zero the temperatures
  ln[1]=0
  ln[2]=0
  ln[3]=0
  ln[4]=0
  # print "" > "gbookFtemp.js"
  notFirst = 0
}

/====/{
  print $0
  getline
  print $0
  
  lnp=1
  cnt +=1
  if ( notFirst ){
    print "gbF( 'awk','t@pi','" lastDate " ','127.0.0.1'," ln[1] "," ln[2] "," ln[3] "," ln[4] ",'comments');" >> "gbookFtemp.js"
  }
  # prepare for next readings
  notFirst = 1
  ln[1]=0
  ln[2]=0
  ln[3]=0
  ln[4]=0
  lastDate = $0
}

/t=/{
  # found a line with a temperature
  ln[lnp] = ($NF/1000) 
  lnp ++
}

END {
  cnt +=1
  print "gbF( 'awk','t@pi','" lastDate " ','127.0.0.1'," ln[1] "," ln[2] "," ln[3] "," ln[4] ",'comments');" >> "gbookFtemp.js"
}

some "gbookFtemp.js"

The temperatures are saved wrapped in a function call.
gbF( 'awk','t@pi','Sun Feb  9 10:30:47 UTC 2014 ','127.0.0.1',17.375,18,17.5,17.312,'comments');
gbF( 'awk','t@pi','Sun Feb  9 10:30:53 UTC 2014 ','127.0.0.1',17.312,18,17.5,17.312,'comments');
gbF( 'awk','t@pi','Sun Feb  9 10:31:00 UTC 2014 ','127.0.0.1',17.375,19.187,17.562,17.375,'comments');
gbF( 'awk','t@pi','Sun Feb  9 10:31:06 UTC 2014 ','127.0.0.1',17.375,19.187,17.562,17.437,'comments');
gbF( 'awk','t@pi','Sun Feb  9 10:31:13 UTC 2014 ','127.0.0.1',17.437,23.25,17.562,17.5,'comments');
gbF( 'awk','t@pi','Sun Feb  9 10:31:20 UTC 2014 ','127.0.0.1',17.437,24.375,17.625,17.562,'comments');
gbF( 'awk','t@pi','Sun Feb  9 10:31:27 UTC 2014 ','127.0.0.1',17.5,25.375,17.687,17.562,'comments');
gbF( 'awk','t@pi','Sun Feb  9 10:31:33 UTC 2014 ','127.0.0.1',17.5,26.062,17.687,17.562,'comments');
gbF( 'awk','t@pi','Sun Feb  9 10:31:40 UTC 2014 ','127.0.0.1',17.5,26.687,17.687,17.625,'comments');
gbF( 'awk','t@pi','Sun Feb  9 10:31:46 UTC 2014 ','127.0.0.1',17.562,27.562,17.75,17.625,'comments');
gbF( 'awk','t@pi','Sun Feb  9 10:31:53 UTC 2014 ','127.0.0.1',17.562,28.437,17.75,17.687,'comments');
gbF( 'awk','t@pi','Sun Feb  9 10:31:59 UTC 2014 ','127.0.0.1',17.625,28.937,17.75,17.687,'comments');
gbF( 'awk','t@pi','Sun Feb  9 10:32:06 UTC 2014 ','127.0.0.1',17.625,-1.25,17.812,17.687,'comments');
gbF( 'awk','t@pi','Sun Feb  9 10:32:13 UTC 2014 ','127.0.0.1',17.625,29.5,17.812,17.687,'comments');

SVG - loopDS18S20reportSVG.svg

The SVG below includes the readings in gbookFtemp.js and plots them.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" width="600" height="600" >
<script type="text/ecmascript"><![CDATA[
//
// Include javascript guestbook and process it. Plots Temperature measurements from DS18S20.
// 

var count=1
var opStr = ""

var linePointsStr2 = ""
var linePointsStr3 = ""
var linePointsStr4 = ""
var linePointsStr5 = ""
var xIndex = 50
var tempStr =""

//
// This function is called once per guestbook entry stored in gbookFtemp.js
// There is a lot of junk in there, which needs to be ignored.
//

function gbF( name,email,postedOn,IPaddress,userfield1,userfield2,userfield3,userfield4,comments){
//  var yvalue = 200 + Math.random()*32
  scale = 10.0
  var yvalue = userfield1*1.0
  if ( yvalue != -1.25) {    linePointsStr2 += xIndex + "," + ( 400 - yvalue*scale ) + " "  }  
  var yvalue = userfield2*1.0
  if ( yvalue != -1.25) {    linePointsStr3 += xIndex + "," + ( 400 - yvalue*scale ) + " "  }  
  var yvalue = userfield3*1.0
  if ( yvalue != -1.25) {    linePointsStr4 += xIndex + "," + ( 400 - yvalue*scale ) + " "  }
  var yvalue =  userfield4*1.0
  if ( yvalue != -1.25) {    linePointsStr5 += xIndex + "," + ( 400 - yvalue*scale ) + " "  }
  xIndex += 1
  tempStr = "last temperatures: " +userfield1 +","+userfield2+","+userfield3+","+userfield4
  
}

function plotMeasured() {
  //
  // Guestbox processed
  //
  obj2=document.getElementById("dhr2");
  obj2.setAttributeNS(null,"points", linePointsStr2  );

  obj3=document.getElementById("dhr3");
  obj3.setAttributeNS(null,"points", linePointsStr3  );

  obj4=document.getElementById("dhr4");
  obj4.setAttributeNS(null,"points", linePointsStr4  );

  obj5=document.getElementById("dhr5");
  obj5.setAttributeNS(null,"points", linePointsStr5  );
}

]]></script>

// window

<defs>
  <!-- Set up clip path to constrain graphs to plot window -->
  <clipPath id = "clip1">
    <path d = "M 48 53 L 548 53  L 548 420 L 48 420 L 48 53 "/>
  </clipPath>
  <radialGradient id = "g1" cx = "50%" cy = "50%" r = "50%" fx = "25%" fy = "25%">
    <stop stop-color = "#ffff66" offset = "0%"/>
    <stop stop-color = "#FFFFCC" offset = "50%"/>
    <stop stop-color = "white" offset = "100%"/>
  </radialGradient>
  <linearGradient id = "g2" x1 = "10%" y1 = "10%" x2 = "90%" y2 = "90%">
    <stop stop-color = "white" offset = "0%"/>
    <stop stop-color = "#7fff66" offset = "25%"/>
    <stop stop-color = "white" offset = "100%"/>
  </linearGradient>
</defs>

// outer square
<rect x="0" y="0" width="600" height="590" fill = "url(#g2)" /> 

//
// plot canvas
//
<rect x="48" y="53" width="500" height="500" stroke="blue" fill = "url(#g1)"  />

//
// define 4 polylines. javascript will change points later.
//

<polyline id="dhr2" fill="none" stroke="blue"   stroke-width="2" points="" clip-path = "url(#clip1)" />
<polyline id="dhr3" fill="none" stroke="lime"   stroke-width="2" points="" clip-path = "url(#clip1)" />
<polyline id="dhr4" fill="none" stroke="red"    stroke-width="2" points="" clip-path = "url(#clip1)" />
<polyline id="dhr5" fill="none" stroke="orange" stroke-width="2" points="" clip-path = "url(#clip1)" />

//
// minor axis lines
//
<line x1="52" y1="100" x2="545" y2="100" style="stroke:rgb(99,99,99);stroke-width:1" />
<line x1="52" y1="200" x2="545" y2="200" style="stroke:rgb(99,99,99);stroke-width:1" />
<line x1="52" y1="300" x2="545" y2="300" style="stroke:rgb(99,99,99);stroke-width:1" />
<line x1="52" y1="400" x2="545" y2="400" style="stroke:rgb(10,10,10);stroke-width:2" />
<line x1="52" y1="500" x2="545" y2="500" style="stroke:rgb(99,99,99);stroke-width:1" />


<text  x="260" y="20"  text-anchor="middle" font-family="Arial,Helvetica" font-size="14px" font-weight="bold" >Temperature Plot using SVG, run: bash loop.sh</text>
<text  x="260" y="40"  text-anchor="middle" font-family="Arial,Helvetica" font-size="14px" id="svg_21"        >data from gbookFtemp.js - DS18S20</text>
<text  x="260" y="580" text-anchor="middle" font-family="Arial,Helvetica" font-size="14px" font-weight="bold" >measurement</text>

<text transform="rotate(270,20,300)" x="20" y="300" font-family="Arial,Helvetica" text-anchor="middle" font-size="14px" pointer-events="none"  font-weight="bold" >Temperature Centigrade</text>

<text  x="30" y="500"  text-anchor="middle" font-family="Arial,Helvetica" font-size="8px" >-10 C </text>
<text  x="30" y="400"  text-anchor="middle" font-family="Arial,Helvetica" font-size="8px" >0 C </text>
<text  x="30" y="300"  text-anchor="middle" font-family="Arial,Helvetica" font-size="8px" >10 C </text>
<text  x="30" y="200"  text-anchor="middle" font-family="Arial,Helvetica" font-size="8px" >20 C </text>
<text  x="30" y="100"  text-anchor="middle" font-family="Arial,Helvetica" font-size="8px" >30 C </text>

<script type="text/ecmascript" xlink:href="gbookFtemp.js" />
//
// include data from guestbook and process.
//


//
// update polyline points 
//
<script type="text/ecmascript"><![CDATA[

 obj6=document.getElementById("svg_21");
 obj6.textContent = tempStr
 
 plotMeasured() 

 window.setInterval("location.reload();",6000);

]]></script>

</svg>


HomePage | RecentChanges | Preferences
This page is read-only | View other revisions
Last edited February 15, 2014 10:50 am by dougrice.plus.com
Search:
dougFooter